2010-09-24 33 views
10

numaralı bir içerik ve complexType içeren WSDL içeren PHP SoapClient sınıf haritası seçeneğini kullanarak, bir öğe ve aynı ada sahip bir karmaşıkType içeren birkaç farklı WSDL dosyasıyla karşılaştım. Örneğin, http://soap.search.msn.com/webservices.asmx?wsdl, "SearchResponse" adında iki öğeye sahiptir:Bir öğe ve aynı isimli

Bu senaryoda, SoapClient() "sınıf haritaları" seçeneğini kullanarak bu varlıkları PHP sınıflarına doğru şekilde nasıl eşleyeceğinizi anlayamıyorum.

ClassMap seçeneği PHP sınıflarına bazı WSDL türlerini eşleştirmek için kullanılabilir:

PHP kılavuzu bu diyor. Bu seçeneği, anahtar olarak WSDL türlerine ve değer olarak PHP sınıflarının adlarına sahip bir dizi olmalıdır. Aynı anahtar ('SearchResponse') ile iki WSDL türü vardır beri

yazık ki, iki SearchResponse varlıklar arasında ayrım anlamaya ve bunlara karşılık gelen PHP sınıflarına bunları atanamıyor. anahtarların aynı

<xsd:complexType name="SearchResponse"> 
    <xsd:sequence> 
     <xsd:element minOccurs="1" maxOccurs="1" name="Responses" type="tns:ArrayOfSourceResponseResponses"/> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:element name="SearchResponse"> 
    <xsd:complexType> 
     <xsd:sequence> 
      <xsd:element minOccurs="1" maxOccurs="1" name="Response" type="tns:SearchResponse"/> 
     </xsd:sequence> 
    </xsd:complexType> 
</xsd:element> 

Ve burada açıkça classmaps beri işe yaramaz PHP'dir: Örneğin

, burada örnek WSDL ilgili snippet'tir

<?php $server = new SoapClient("http://soap.search.msn.com/webservices.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MySearchResponseElement', 'SearchResponse' => 'MySearchResponseComplexType'))); ?> 

Bir çözüm ararken, Java Web Services'ın bunu, "Element" veya "ComplexType" varlıklarına özel bir sonek belirtmenize izin vererek ele aldığını gördüm.

http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html#wp149350

Yani, şu anda sadece PHP'nin SoapClient ile yapmak için hiçbir yolu yoktur gibi hissediyorum, ama orada kimse herhangi bir tavsiye sunabilir eğer merak ediyorum. FWIW, uzak WDSL'yi düzenleyemiyorum.

Herhangi bir fikir ???

+0

yok hemen bir fikir, ama sen http://www.php.net/manual/en/soapclient.soapclient.php#94151 bulunan Açıklama kontrol edebilir. Belirtilen 'SoapClient -> __ getTypes()' işlevini kullanarak, kullanabileceğiniz iki öğenin 'örtük' türden bir ayrımını (yalnızca bir tahmin olsa da) bulabilirsiniz. –

+0

Henrik, yorumunuz için teşekkürler. __getTypes() mevcut veri yapıları hakkında bazı ilginç ayrıntıları döndürür ve benim durumumda, farklı özelliklere sahip aynı ada sahip iki 'yapı' alıyorum. Ne yazık ki sorun şu şekilde devam ediyor: classmap parametresinin ayarlandığı şekilde (array anahtarının yapının adı olduğu) bu iki yapıyı farklı PHP sınıflarına eşleyemiyorum. – stereoscott

cevap

7

Bu, başımın en üstündedir, ancak her iki SearchResponse türünün de MY_SearchResponse ile eşleştirilebileceğini ve ikisi arasındaki farkı bulmayı deneyebildiğini düşünüyorum. Kludgy, ama böyle bir şey olabilir mi?

<?php 
//Assuming SearchResponse<complexType> contains SearchReponse<element> which contains and Array of SourceResponses 
//You could try abstracting the nested Hierarchy like so: 
class MY_SearchResponse 
{ 
    protected $Responses; 
    protected $Response; 

    /** 
    * This should return the nested SearchReponse<element> as a MY_SearchRepsonse or NULL 
    **/ 
    public function get_search_response() 
    { 
     if($this->Response && isset($this->Response)) 
     { 
     return $this->Response; //This should also be a MY_SearchResponse 
     } 
     return NULL; 
    } 

    /** 
    * This should return an array of SourceList Responses or NULL 
    **/ 
    public function get_source_responses() 
    { 
     //If this is an instance of the top SearchResponse<complexType>, try to get the SearchResponse<element> and it's source responses 
     if($this->get_search_response() && isset($this->get_search_response()->get_source_responses())) 
     { 
     return $this->get_search_response()->get_source_responses(); 
     } 
     //We are already the nested SearchReponse<element> just go directly at the Responses 
     elseif($this->Responses && is_array($this->Responses) 
     { 
     return $this->Responses; 
     } 
     return NULL; 
    } 
} 

class MY_SourceResponse 
{ 
    //whatever properties SourceResponses have 
} 

$client = new SoapClient("http:/theurl.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MY_SearchResponse', 'SourceResponse' => 'MY_SourceResponse'))); 
+0

Bu oldukça ilginç. Bununla oynuyordum ve gayet iyi çalışıyor. Her iki türdeki varlıklar için de aynı sınıfı kullanmam gerektiği gerçeğini aşmak zorunda kaldım. – stereoscott

+0

Ayrıca ... Sabır istekleri sunucuya sınıf gibi çalışarak işe yaramaz gibi geliyor, ama hangi parametreleri temsil ettiğine göre uygun parametreleri çıkaran bir yöntem yaratmayı hayal edebiliyorum. Detaylı örneğiniz için teşekkürler. – stereoscott

+0

Evet, bu, WS sağlayıcılarının üzerinde oldukça belirsiz adlandırma stratejisidir.Yine de yardımcı olabileceğime sevindim. –

İlgili konular