1

PHPでSOAPサービスを設定しようとしています。サーバーのphp関数を宣言し、その関数をSOAPタイプのhttpリクエストで呼び出すことができます。ここで、コンテンツは私のSOAPエンベロープです。

SOAP本体のXMLコンテンツは、私が想定している関数の引数ですが、phpコードでその中の情報にアクセスする方法がわかりません。

関数の引数がデフォルトのインスタンスであることに気づきましたが、stdClass実際には、なぜそれがphpによってXMLまたはDOMオブジェクトにキャストされないのか疑問に思います-それはSOAP呼び出しですよね?しかし、大丈夫です。オブジェクトから情報を取得するのは私次第です。メソッドが割り当てられていないため、これは簡単ではありませんstdClass。したがって、標準のphp関数である必要があります。だから私は試しserializeましたが、これは私が期待したXML文字列ではなく、私にいくつかのゴミを与えました。

何をすべきか?

編集

stdClassオブジェクトから取得するコードを作成する方法がわからないため、以下に実行したいコードの例がないことに注意してください。SOAPリクエストのXMLコンテンツから詳細データを取得します。

デビッドのリクエストに応じて、ここにいくつかの詳細があります。

phpコード:

<?php
    function mi102($arg) {
        $txt = serialize ($arg);
        $result = new SoapVar ($txt, XSD_ANYXML);
        return($result);
    }
    ini_set( "soap.wsdl_cache_enabled", "0");
    $server = new SoapServer ("test.wsdl");
    $server -> addFunction ("mi102");
    try {
        $server -> handle();
    }
    catch (Exception $e) {
        $server -> fault ('Client', $e -> getMessage());
    }
?php>

httpリクエストは、私が使用するアプリケーションによって作成されます。httpヘッダーとsoapエンベロープ+本文は、フィードしたXMLの周囲に生成されます。

SOAPリクエストの本文の内容:

<mi102 xmlns="http://pse">
  <cdhead cisprik="21"/>
  <instr>
    <insid>
      <bcdt>20120930</bcdt>
    </insid>
  </instr>
</mi102>

使用されるWSDLは次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://pse/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="PSE" targetNamespace="http://pse/">
    <types>
        <xs:schema>
            <xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/>
        </xs:schema>
    </types>
    <message name="MI102Req">
        <part name="cdhead" type="tns:cdhead_T"/>
        <part name="instr" type="tns:instr_T"/>
    </message>
    <message name="Res">
        <part name="cdhead" type="tns:cdhead_T"/>
    </message>
    <portType name="MIPortType">
        <operation name="mi102">
            <input message="tns:MI102Req"/>
            <output message="tns:Res"/>
        </operation>
    </portType>
    <binding name="MIBinding" type="tns:MIPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="mi102">
            <soap:operation soapAction="http://testServerURL/test_soap.php#mi102"/>
            <input>
                <soap:body use="literal" namespace="http://pse/"/>
            </input>
            <output>
                <soap:body use="literal" namespace="http://pse/"/>
            </output>
        </operation>
    </binding>
    <service name="PSE">
        <port name="MIPortType" binding="tns:MIBinding">
            <soap:address location="http://testServerURL/test_soap.php"/>
        </port>
    </service>
</definitions>

そして、結果のXML(ここでも、私が使用するアプリケーションによってSOAP本体から抽出されます)は次のようになります。

SOAP応答:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mi102Response xmlns:ns1="http://pse/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">O:8:"stdClass":2:{s:7:"cisprik";i:21;s:7:"version";s:2:"13";}</ns1:mi102Response>

よくない。

4

3 に答える 3

3

私は最終的に、 get-recieved-xml-from-php-soap-serverのようなSOの他のスレッドで答えを見つけました

解決策は、以下を使用することです。

$inp = file_get_contents ('php://input');

stdClass注:入力引数に作用し、そこからXMLSOAP本文の内容を取得できる関数が見つかりませんでした。
したがって、最良のオプションは、標準のphp入力変数を使用することです。これは次の構造になっていることに注意してください。これEnvelope/Body/..inputXML..は、サーバーに投稿される正確なhttpリクエストコンテンツです。

注:http_get_request_body動作する可能性もありますが、私のphpサーバーはこの機能をサポートしていませんでした。file_get_contentsこれは、あるバージョン以降のすべてのphpサーバーでサポートされていると思います。

于 2012-10-05T07:37:16.840 に答える
0

シリアル化されたオブジェクトを返すため、オブジェクトの「良くない」表現を持っています(シリアル化はオブジェクトとその状態を文字列表現に変換しています)。返されたオブジェクトの xml 表現が必要な場合は、関数の戻りパラメーターの型をオブジェクトに変更する必要があります。今は文字列を返しているからです。

Zend フレームワークの Zend_Soap_Server および Zend_Soap_Autodiscover コンポーネントを使用することをお勧めします。

Zend_Soap_Autodiscover を使用すると、関数の docblock を記述するだけで、Web サービス定義 (wsdl) を動的に生成できます。そして Zend_Soap_Server もかなりクールです。

これらのコンポーネントを使用し、型と関数を文書化して特定の型をシリアル化せずに返す場合、wsdl 定義に従って xml 表現を受け取ることになります。また、作成した各型は、Zend_Soap_Autodiscover によって、生成された wsdl 内の ComplexType に自動的に変換されます。

サンプル:

 public class Person{
         public $id;
         public $name;
    }

    public class MyService {
     /**
     *
     * @param integer $UserID
     * @return Person
     */
    function mi102($UserID) {

         $output = new Person();
         $output->id = 2;
         $output->name = 'Peter';        

        return $output;
    }
}


// Generate WSDL relevant to code
if (isset($_GET['wsdl'])){

    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('MyService');
    $autodiscover->handle();

} else {

    $server = new Zend_Soap_Server($serviceURL . "?wsdl");
    $server->setClass('MyService');
    $server->setObject(new MyService());
    $server->handle();

}
于 2012-10-02T16:05:12.907 に答える
0

これは完全な回答として開始されるわけではありませんが、フォーマットが必要でした。設定した内容を詳しく説明してください。通常、Web サービスとして公開する通常の引数 (XML ではない) を持つ PHP メソッドがあります。これを行う方法の基本的な例は次のとおりです。

http://www.phpeveryday.com/articles/Web-Services-WSDL-Creating-SOAP-Server-P484.html

SOAP本体のXMLコンテンツは、私が想定している関数の引数です

いいえ、SOAP 本体の XML コンテンツは、引数を使用したメソッドの表現ですが、引数は何でも構いません。PHP の SoapServer と SoapClient を使用して XML をセットアップすれば、XML を手動で処理する必要はありません。

編集:SOAPリクエストの本体の単純なPHP配列表現である引数を取得し、それをシリアル化し、応答として送り返します(これはあなたが観察したものです)。これはあなたがやりたいことですか?リクエストデータで何かしたくないですか?また、WSDL からインポートしたスキーマを投稿できますか?

于 2012-10-02T15:14:02.293 に答える