2013-02-16 18 views
11

我正在开发一个amazon affiliate wordpress页面。 为此,我使用aws_signed_request函数从亚马逊获取价格和链接。'保存在Wordpress中时不允许'SimpleXMLElement'的序列化post_meta

这里是aws_signed_request函数返回的XML:

function aws_signed_request($region, $params, $public_key, $private_key, $associate_tag) { 
    $method = "GET"; 
    $host = "ecs.amazonaws.".$region; 
    $uri = "/onca/xml"; 

    $params["Service"]   = "AWSECommerceService"; 
    $params["AWSAccessKeyId"] = $public_key; 
    $params["AssociateTag"]  = $associate_tag; 
    $params["Timestamp"]  = gmdate("Y-m-d\TH:i:s\Z"); 
    $params["Version"]   = "2009-03-31"; 

    ksort($params); 

    $canonicalized_query = array(); 

    foreach ($params as $param=>$value) 
    { 
     $param = str_replace("%7E", "~", rawurlencode($param)); 
     $value = str_replace("%7E", "~", rawurlencode($value)); 
     $canonicalized_query[] = $param."=".$value; 
    } 

    $canonicalized_query = implode("&", $canonicalized_query); 

    $string_to_sign = $method."\n".$host."\n".$uri."\n". 
          $canonicalized_query; 

    /* calculate the signature using HMAC, SHA256 and base64-encoding */ 
    $signature = base64_encode(hash_hmac("sha256", 
            $string_to_sign, $private_key, True)); 

    /* encode the signature for the request */ 
    $signature = str_replace("%7E", "~", rawurlencode($signature)); 

    /* create request */ 
    $request = "http://".$host.$uri."?".$canonicalized_query."&Signature=".$signature; 

    /* I prefer using CURL */ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL,$request); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 15); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 

    $xml_response = curl_exec($ch); 

    if ($xml_response === False) 
    { 
     return False; 
    } 
    else 
    { 
     $parsed_xml = @simplexml_load_string($xml_response); 
     return ($parsed_xml === False) ? False : $parsed_xml; 
    } 
} 

我从后得到的ASIN和生成的链接和价格

global $post; 
$asin = get_post_meta($post->ID, 'ASIN', true); 

$public_key = 'xxxxxxxxxxx'; 
$private_key = 'xxxxxxxxxxx'; 
$associate_tag = 'xxxxxxxxxxx'; 

$xml = aws_signed_Request('de', 
array(
    "MerchantId"=>"Amazon", 
    "Operation"=>"ItemLookup", 
    "ItemId"=>$asin, 
    "ResponseGroup"=>"Medium, Offers"), 
$public_key,$private_key,$associate_tag); 

$item = $xml->Items->Item; 

$link = $item->DetailPageURL; 
$price_amount = $item->OfferSummary->LowestNewPrice->Amount; 
if ($price_amount > 0) { 
    $price_rund = $price_amount/100; 
    $price = number_format($price_rund, 2, ',', '.'); 
} else { 
    $price= "n.v."; 
} 

这时候我赞同所有作品不错之后$ link和$ price。但我想将这些值保存在wordpress的自定义字段中,所以我不必每次都运行这个函数。

update_post_meta($post->ID, 'Price', $price); 
update_post_meta($post->ID, 'Link', $link); 

这增加了价格为正确的值,但是当我想要添加的链接我得到这个错误信息:

未捕获的异常“异常”与消息的SimpleXMLElement“ 系列化“不允许'在...

但是,当我删除$ parsed_xml = ...函数,它保存一个空值。

+0

[未捕获的异常可能重复'异常'消息''SimpleXMLElement序列化'是不允许'](http://stackoverflow.com/questions/6058966/uncaught-exception-exception-with-message-serialization-of-simplexmlelement) – hakre 2013-10-08 08:27:20

回答

27

(几乎)当你遍历一个SimpleXML对象时,所有返回的对象实际上是另一个SimpleXML对象。这是什么让你写$item->OfferSummary->LowestNewPrice->Amount:在$item对象请求->OfferSummary返回表示OfferSummary XML节点的对象,这样你就可以在那个对象上要求->LowestNewPrice,等等。请注意,这也适用于属性 - $someNode['someAttribute']将是一个对象,而不是一个字符串!

为了获得元素或属性的字符串内容,你必须以“铸造”了,使用语法(string)$variable。有时,PHP会知道你打算这样做,并为你做 - 例如使用echo - 但总的来说,最好练习总是强制手动输入字符串,这样如果你改变了你就不会有任何意外你的代码稍后。您也可以使用(int)转换为整数,或使用(float)转换为浮点数。

您的问题的第二个部分是SimpleXML的对象存储,而特别是在存储器中,并且不能为“串行”(即变成完全描述了对象的字符串)。这意味着如果您尝试将它们保存到数据库或会话中,您将看到您看到的错误。如果你真的想保存一整块XML,你可以使用$foo->asXML()

因此,简而言之:

  • 使用$link = (string)$item->DetailPageURL;得到一个字符串,而不是一个对象
  • 使用update_post_meta($post->ID, 'ItemXML', $item->asXML());如果你想存储整个项目
相关问题