2013-02-16 2 views
11

में सहेजते समय' SimpleXMLElement 'का सीरियलाइजेशन की अनुमति नहीं है मैं एक अमेज़ॅन संबद्ध WordPress पृष्ठ पर काम कर रहा हूं। इसके लिए मैं अमेज़ॅन से मूल्य और लिंक प्राप्त करने के लिए aws_signed_request फ़ंक्शन का उपयोग कर रहा हूं।'WordX post_meta

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

यह सब बहुत अच्छी काम करता है जब मैं गूंज उत्पन्न:

यहाँ एक्सएमएल लौटने aws_signed_request समारोह है $ लिंक और $ मूल्य। लेकिन मैं वर्डप्रेस पोस्ट के कस्टम फ़ील्ड में मानों को सहेजना चाहता हूं इसलिए मुझे हर बार फ़ंक्शन चलाने की ज़रूरत नहीं है।

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

उत्तर

27

(लगभग) जब आप एक SimpleXML ऑब्जेक्ट को घुमा रहे हैं तो सबकुछ वापस आ गया है वास्तव में एक और SimpleXML ऑब्जेक्ट है। यह आपको $item->OfferSummary->LowestNewPrice->Amount लिखने देता है: पर $item ऑब्जेक्ट पर OfferSummary एक्सएमएल नोड का प्रतिनिधित्व करने वाला ऑब्जेक्ट देता है, इसलिए आप उस ऑब्जेक्ट पर ->LowestNewPrice का अनुरोध कर सकते हैं, और इसी तरह। ध्यान दें कि यह विशेषताओं पर भी लागू होता है - $someNode['someAttribute'] एक ऑब्जेक्ट होगा, स्ट्रिंग नहीं!

किसी तत्व या विशेषता की स्ट्रिंग सामग्री प्राप्त करने के लिए, आपको वाक्यविन्यास (string)$variable का उपयोग करके इसे "कास्ट" करना होगा। कभी-कभी, PHP जानता होगा कि आपको ऐसा करने का मतलब है, और यह आपके लिए करें - उदाहरण के लिए echo का उपयोग करते समय - लेकिन सामान्य रूप से, पर यह अच्छा अभ्यास है हमेशा मैन्युअल रूप से स्ट्रिंग करने के लिए डाला जाता है ताकि आप कोई आश्चर्यचकित न हों अगर आप बदलते हैं बाद में आपका कोड आप (int), या (float) का उपयोग करके एक फ़्लोट का उपयोग करके एक पूर्णांक में भी जा सकते हैं।

आपकी समस्या का दूसरा भाग यह है कि SimpleXML ऑब्जेक्ट्स विशेष रूप से स्मृति में संग्रहीत किए जाते हैं, और "क्रमबद्ध" नहीं हो सकते हैं (यानी एक स्ट्रिंग में बदल दिया गया है जो वस्तु को पूरी तरह से वर्णन करता है)। इसका अर्थ यह है कि यदि आप उन्हें डेटाबेस या सत्र में सहेजने का प्रयास करते हैं, तो आपको वह त्रुटि मिल जाएगी जो आप देख रहे हैं। यदि आप वास्तव में एक्सएमएल के पूरे ब्लॉक को सहेजना चाहते हैं, तो आप $foo->asXML() का उपयोग कर सकते हैं।

तो, संक्षेप में:

  • उपयोग $link = (string)$item->DetailPageURL; एक वस्तु
  • उपयोग update_post_meta($post->ID, 'ItemXML', $item->asXML()); के बजाय एक स्ट्रिंग प्राप्त करने के लिए अगर आप कभी भी पूरे आइटम