2009-06-06 11 views
2

私はPHP 5を使用して、ソートのように定義されたWebサービスを呼び出すようにしたいんだ:PHP Soapクライアント:パラメータとしてDerivedクラスを使用してWebServiceを呼び出す方法

webmethod (AbstractBase obj); 

私はのSoapClient(WSDLベース)を使用しています。 WebメソッドはAbstractBaseのサブクラスを予期しています。しかし、PHPで、SOAPメソッドを呼び出すと、私はこのエラーを取得します - 「しかし、私はでき

 
    Server was unable to read request. 
     ---> There is an error in XML document 
     ---> The specified type is abstract: name='AbstractBase' 

私はこの問題は、私は石鹸の呼び出しでOBJパラメータの型を指定する必要があるかなり確信していますそれをそうするために魔法の言葉を見つけるように見える。

$client = new SoapClient($WSDL, $soapSettings); 
    $obj = array(
     'internal_id' => $internalId, 
     'external_id' => $externald, 
    ); 
    $params = array(
     'obj'  => $obj // How do I say it is of type: DerivedClass? 
    ); 

    $response = $client->webmethod($params); 

答えて

5

これは良い提案でしたが、どちらもうまくいきませんでした。しかし、私は正しい方向に向かいました。私はあなたのアイデアを取り、2つのクラスを作成し、SoapVarとXSD_ANYTYPEを使ってオブジェクトのタイプを明示的に設定しようとしました。それはほぼ成功しましたが、クラス内のフィールドに名前空間(ns1 :)は設定されませんでした。

だから私は最終的にこれを修正しましたか?それは2つのものが必要でした。

私は素晴らしいを発見しましたXSD_ANYXMLこれにより、リクエストに対して自分のXMLをロールバックできます。それ自体では、石鹸の封筒にxsi名前空間を追加できませんでした。そのため、リクエストを作成していたコードを起動するために、1つのパラメータをXSD_STRINGにする必要がありました。私の作業コード:

$client = new SoapClient($WSDL, $soapSettings); 
$myXml = " 
    <ns1:obj xsi:type='ns1:DerivedClass'> 
    <ns1:internal_id>$internalId</ns1:internal_id> 
    <ns1:external_id>$externalId</ns1:external_id> 
    </ns1:obj> 
"; 

$params = array(
    // this is needed to force the XSI namespace in the header (there must be a better way) 
    'foo' => new SoapVar('bar', XSD_STRING, 'String, 'http://www.w3.org/2001/XMLSchema-instance'), 
    // this uses the XML I created 
    'obj' => new SoapVar($myXml, XSD_ANYXML), 
); 

$response = $client->webmethod($params); 
+0

AHHHH !!!もし私があなたに私のすべての報酬ポイントを与えることができたら、私はできます。検索の一日の後、私はこれがインターネット上でこの情報を見つけることができる唯一の場所であると確信しています。助かりました。 – timmyc

+0

'XSD_ANYXML'を使うのはむしろ醜い回避策のようです。 SoapVar()はそのような目的のために '$ type_name'と' $ type_namespace'を取ります。 – silverdr

0

あなたが(代わりにオブジェクトの)を通過している配列がどこかAbstractBaseにキャストされているとエラーがその後、スローされているのだろうか。代わりに実際のオブジェクトを渡す必要があるかもしれません:

abstract class AbstractBase { 
    public $internal_id; 
    public $external_id; 
} 

class DerivedClass extends AbstractBase { } 

$obj = new DerivedClass(); 
$obj->internal_id = $internalId; 
$obj->external_id = $externalId; 

$params = array(
    'obj'  => $obj // Now an instance of DerivedClass 
); 

$response = $client->webmethod($params); 
関連する問題