的SimpleXMLElement“系列化‘’在WordPress的post_meta保存时是不允许

2019-07-20 00:29发布

我工作的亚马逊子公司WordPress的页面上。 对于我现在用的是aws_signed_request函数来获取从亚马逊的价格和纽带。

这里是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;
    }
} 

从那以后,我得到职位的阿辛和生成的链接和价格

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."; 
}

当我回声$链接和$价格这一切工作不错。 但我想保存在WordPress后的自定义字段中的值,所以我不必每次运行的功能。

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

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

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

但是,当我删除$ parsed_xml = ...功能,这样可以节省空值。

Answer 1:

(几乎)当你穿过SimpleXML对象实际上是另一个SimpleXML的对象一切恢复。 这是什么让你写$item->OfferSummary->LowestNewPrice->Amount :请求->OfferSummary$item对象返回代表一个对象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()); 如果你想存储整个项目


文章来源: 'Serialization of 'SimpleXMLElement' is not allowed when saving in Wordpress post_meta