web-dev-qa-db-ja.com

Wordpress post_metaに保存する場合、「SimpleXMLElement」のシリアル化は許可されません

Amazonアフィリエイトwordpressページに取り組んでいます。そのため、aws_signed_request関数を使用してAmazonから価格とリンクを取得しています。

次に、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;
    }
} 

その後、私はポストからアシンを取得し、リンクと価格を生成します

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);

これにより、価格が正しい値として追加されますが、リンクを追加すると、次のエラーメッセージが表示されます。

キャッチされない例外「Exception」とメッセージ「SimpleXMLElement」のシリアル化は許可されていません。

しかし、$ parsed_xml = ...関数を削除すると、空の値が保存されます。

17
user2078789

(ほぼ)SimpleXMLオブジェクトをトラバースするときに返されるものはすべて、実際には別のSimpleXMLオブジェクトです。これにより、$item->OfferSummary->LowestNewPrice->Amountを記述できます。->OfferSummaryオブジェクトで$itemをリ​​クエストすると、OfferSummary XMLノードを表すオブジェクトが返されるため、そのオブジェクトで->LowestNewPriceをリ​​クエストできます。これは属性にも適用されることに注意してください-$someNode['someAttribute']は文字列ではなくオブジェクトになります!

要素または属性の文字列コンテンツを取得するには、構文(string)$variableを使用してそれを「キャスト」する必要があります。 PHPは、これを行うつもりであることを知っており、たとえばechoを使用する場合など)ですが、一般的には常に手動で文字列にキャストする後でコードを変更しても驚くことはないように、(int)を使用して整数にキャストすることも、(float)を使用して浮動小数点数にキャストすることもできます。

問題の2番目の部分は、SimpleXMLオブジェクトがかなり特別にメモリに格納されており、「シリアル化」できない(つまり、オブジェクトを完全に説明する文字列に変換できない)ことです。これは、それらをデータベースまたはセッションに保存しようとすると、表示されているエラーが発生することを意味します。 XMLのブロック全体を実際に保存したい場合は、$foo->asXML()を使用できます。

つまり、要するに:

  • $link = (string)$item->DetailPageURL;を使用して、オブジェクトではなく文字列を取得します
  • アイテム全体を保存したい場合は、update_post_meta($post->ID, 'ItemXML', $item->asXML());を使用してください
35
IMSoP