php 在 Wordpress post_meta 中保存时不允许“SimpleXMLElement”的序列化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/14912551/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
'Serialization of 'SimpleXMLElement' is not allowed when saving in Wordpress post_meta
提问by user2078789
I am working on an amazon affiliate wordpress page. For that I am using the aws_signed_request function to get the price and link from amazon.
我正在亚马逊附属 wordpress 页面上工作。为此,我使用 aws_signed_request 函数从亚马逊获取价格和链接。
Here is the aws_signed_request function returning the xml:
这是返回 xml 的 aws_signed_request 函数:
    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;
    }
} 
After that I get the asin from the post and generate the link and price
之后,我从帖子中获取 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."; 
}
This all works pretty good when I echo the $link and $price. But I want to save the values in the custom fields of the wordpress post so I don't have to run the function every time.
当我回显 $link 和 $price 时,这一切都很好。但是我想将值保存在 wordpress 帖子的自定义字段中,这样我就不必每次都运行该函数。
update_post_meta($post->ID, 'Price', $price);
update_post_meta($post->ID, 'Link', $link);
This adds the price as the correct value, but when I want to add the link I get this error message:
这将价格添加为正确的值,但是当我想添加链接时,我收到以下错误消息:
Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in...
未捕获的异常 'Exception' 带有消息 'SimpleXMLElement' 的序列化不允许'...
But when I remove the $parsed_xml=... function, it saves an empty value.
但是当我删除 $parsed_xml=... 函数时,它会保存一个空值。
回答by IMSoP
(Nearly) everything returned when you are traversing a SimpleXML object is actually another SimpleXML object. This is what lets you write $item->OfferSummary->LowestNewPrice->Amount: requesting ->OfferSummaryon the $itemobject returns an object representing the OfferSummaryXML node, so you can request ->LowestNewPriceon that object, and so on. Note that this applies to attributes too - $someNode['someAttribute']will be an object, not a string!
(几乎)当您遍历 SimpleXML 对象时返回的所有内容实际上都是另一个 SimpleXML 对象。这是什么让你写$item->OfferSummary->LowestNewPrice->Amount:请求->OfferSummary的对$item对象返回代表一个对象OfferSummaryXML节点,所以你可以要求->LowestNewPrice该对象,依此类推。请注意,这也适用于属性 -$someNode['someAttribute']将是一个对象,而不是一个字符串!
In order to get the string content of an element or attribute, you have to "cast" it, using the syntax (string)$variable. Sometimes, PHP will know you meant to do this, and do it for you - for instance when using echo- but in general, it's good practice to always cast to string manuallyso that you won't have any surprises if you change your code later. You can also cast to an integer using (int), or a float using (float).
为了获取元素或属性的字符串内容,您必须使用语法“强制转换”它(string)$variable。有时,PHP 会知道您打算执行此操作,并为您执行此操作 - 例如在使用时echo- 但一般来说,始终手动强制转换为字符串是一种很好的做法,以便以后更改代码时不会有任何意外. 您还可以使用 转换为整数(int),或使用 转换为浮点数(float)。
The second part of your problem is that SimpleXML objects are stored rather specially in memory, and can't be "serialized" (i.e. turned into a string that completely describes the object). This means that if you try to save them into a database or session, you will get the error you're seeing. If you actually wanted to save a whole block of XML, you could use $foo->asXML().
问题的第二部分是 SimpleXML 对象存储在内存中相当特殊,并且不能“序列化”(即变成完全描述对象的字符串)。这意味着如果您尝试将它们保存到数据库或会话中,您将收到您所看到的错误。如果你真的想保存一整块 XML,你可以使用$foo->asXML().
So, in short:
所以,简而言之:
- use $link = (string)$item->DetailPageURL;to get a string rather than an object
- use update_post_meta($post->ID, 'ItemXML', $item->asXML());if you ever want to store the whole item
- 用于$link = (string)$item->DetailPageURL;获取字符串而不是对象
- 使用update_post_meta($post->ID, 'ItemXML', $item->asXML());如果你想存储整个项目

