«Сериализация« SimpleXMLElement »не разрешена при сохранении в WordPress post_meta

Я работаю над страницей на WordPress амазонки. Для этого я использую функцию aws_signed_request, чтобы получить цену и ссылку с amazon.

Вот функция 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("Ymd\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= "nv"; } 

Все это работает очень хорошо, когда я повторяю $ link и $ price. Но я хочу сохранить значения в пользовательских полях сообщения WordPress, поэтому мне не нужно запускать функцию каждый раз.

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

Это добавляет цену как правильное значение, но когда я хочу добавить ссылку, я получаю это сообщение об ошибке:

Необязательное исключение «Исключение» с сообщением «Сериализация« SimpleXMLElement »не разрешено в …

Но когда я удаляю функцию $ parsed_xml = …, она сохраняет пустое значение.

(Почти) все, что возвращается, когда вы проходите объект SimpleXML, на самом деле является другим объектом SimpleXML. Это то, что позволяет вам писать $item->OfferSummary->LowestNewPrice->Amount : ->OfferSummary в объекте $item возвращает объект, представляющий XML-узел OfferSummary , поэтому вы можете запросить ->LowestNewPrice на этом объекте и т. Д. , Обратите внимание, что это также относится к атрибутам – $someNode['someAttribute'] будет объектом, а не строкой!

Чтобы получить строковое содержимое элемента или атрибута, вам нужно «бросить» его, используя (string)$variable . Иногда PHP будет знать, что вы намеревались сделать это, и сделайте это за вас – например, при использовании echo – но в целом рекомендуется всегда применять строчку вручную, чтобы у вас не было никаких сюрпризов, если вы измените код позже. Вы также можете использовать целое число с использованием (int) или float using (float) .

Вторая часть вашей проблемы заключается в том, что объекты SimpleXML хранятся довольно специально в памяти и не могут быть «сериализованы» (т.е. превращены в строку, полностью описывающую объект). Это означает, что если вы попытаетесь сохранить их в базу данных или сеанс, вы получите сообщение об ошибке, которое вы видите. Если вы действительно хотите сохранить целый блок XML, вы можете использовать $foo->asXML() .

Итак, одним словом:

  • используйте $link = (string)$item->DetailPageURL; получить строку, а не объект
  • используйте update_post_meta($post->ID, 'ItemXML', $item->asXML()); если вы хотите сохранить весь товар