PHP SoapServerでSOAPリクエストのXMLコンテンツからデータをキャッチするにはどうすればよいですか。

StackOverflow https://stackoverflow.com//questions/12692797

  •  12-12-2019
  •  | 
  •  

質問

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

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

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

何をすべきか?

編集

以下にしたいもののコード例がないことに注意してください - SOAP要求のXMLコンテンツからいくつかの詳細データを取得します - StdClassオブジェクトからの取得方法がわからないためです。

Davidの要求に応じて、ここにいくつかの詳細があります。

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 Envelope + Bodyは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応答:

<?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>
.

素敵なものではありません。

役に立ちましたか?

解決

私は最終的に他のスレッドでの答えを見つけました。-xml-from-php-soap-server

解決策は以下のものを使用することです:

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

注:stdClass入力引数に行動できる関数は見つかりませんでした。
そのため、最良のオプションは標準のPHP入力変数を使用することです。これには次の構造があります.Envelope/Body/..inputXML..。これは、サーバーに投稿される正確なHTTPリクエストコンテンツです。

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

他のヒント

これは完全な答えとして始まりませんが、フォーマットを望んでいました。あなたが設定したものについて詳しく説明してください。一般に、Webサービスとして公開する定期的な引数(XMLではなく)付きのPHPメソッドがあります。これを行う方法に関する基本的な例:

http://www.phpeveryday。 COM /記事/ Webサービス-WSDL-CREATES-SOAP-SERVER-P484.HTML

SOAP本体のXMLコンテンツは、

の関数の引数です。

いいえ、SOAP本体のXMLコンテンツは、手法の表現ですが、引数は必要なものは何でもです。 PHPのSOAPServerとSOAPClientで設定した場合は、手動でXMLに対処する必要はありません。

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

オブジェクトのシリアル化されているオブジェクトを返信しているため、オブジェクトの「素晴らしい」表現を持つことができます(シリアライゼーションはオブジェクトとその状態を文字列表現に変換しています)。返されたオブジェクトのXML表現を持つ場合は、機能の戻りパラメータタイプをオブジェクトに変更する必要があります。今文字列を返しているからです。

Zend_SOAP_SERVER ZEND_SOAP_SERVERとZend_SOAP_AUTODISCOVERコンポーネントを使用することをお勧めします。

Zend_SOAP_AUTODISCOVERを使用すると、関数のDocBlocksを書くだけで、Webサービス定義(WSDL)を動的に生成できます。そしてZend_SOAP_Serverはかなりクールです。

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

サンプル:

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

}
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top