6

Zend_Soap_ServerPHPでクラスを使用してSOAPサーバーを実装しようとしています。

webservice.phpリクエストのエントリポイントであるファイルは次のとおりです。

<?php
require_once 'library.php';
require_once 'Zend/Loader/Autoloader.php';
$autoloader = \Zend_Loader_Autoloader::getInstance();

class Math
{
    /**
     * This method takes ...
     *
     * @param integer $inputParam
     * @return \Library\IncrementedInt
     */
    public function increment($inputParam)
    {
        return new \Library\IncrementedInt($inputParam);
    }
}

$options = array('uri' => 'http://localhost' . $_SERVER['REQUEST_URI']);

if (isset($_GET['wsdl'])){
    $server = new Zend_Soap_AutoDiscover();
    $server->setClass('Math');
}
else {
    $server = new Zend_Soap_Server(null, $options);
    $server->setClass('Math');
    $server->setObject(new Math());
}

$server->handle();

そして、私はlibrary.php次のようなファイルを持っています:

<?php
namespace Library;

class IncrementedInt
{
    public $original;
    public $incremented;

    public function __construct($num)
    {
        $this->original = $num;
        $this->incremented = ++$num;
    }
}

を呼び出すと、次のhttp://localhost/webservice.php?wsdlように出力されます。

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" 

xmlns:tns="http://localhost/webservice.php" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="Math" targetNamespace="http://localhost/webservice.php">
    <script/>
    <types>
        <xsd:schema targetNamespace="http://localhost/webservice.php">
            <xsd:complexType name="\Library\IncrementedInt">
                <xsd:all/>
            </xsd:complexType>
        </xsd:schema>
    </types>
    <portType name="MathPort">
        <operation name="increment">
            <documentation>This method takes ...</documentation>
            <input message="tns:incrementIn"/>
            <output message="tns:incrementOut"/>
        </operation>
    </portType>
    <binding name="MathBinding" type="tns:MathPort">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="increment">
            <soap:operation soapAction="http://localhost/webservice.php#increment"/>
            <input>
                <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/webservice.php"/>
            </input>
            <output>
                <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/webservice.php"/>
            </output>
        </operation>
    </binding>
    <service name="MathService">
        <port name="MathPort" binding="tns:MathBinding">
            <soap:address location="http://localhost/webservice.php"/>
        </port>
    </service>
    <message name="incrementIn">
        <part name="inputParam" type="xsd:int"/>
    </message>
    <message name="incrementOut">
        <part name="return" type="tns:\Library\IncrementedInt"/>
    </message>
</definitions>

soapUI 4.5.1ここで、SOAP クライアントを実装する Java アプリケーションである、使用する機能をテストします。URIを指定http://localhost/webservice.php?wsdlすると関数incrementが抽出されるはずですが、そうではありません。代わりに、エラーが表示されます: The Value '\Library\IncrementInt' is an invalid name. \タイプ名の一部として受け入れるのに問題があるようです。一方、PHPはそれらなしではできません。

他のすべてが問題ないことを確認するために、名前空間なしでまったく同じファイルをテストしたところ、スムーズに動作しました.

誰かが同様の問題に直面したことがありますか?さらに重要なことに、この問題を克服する方法を知っている人はいますか?

[アップデート]

ZF2 で同じシナリオをテストすることができましたが、うまくいきました。ZF1は諦めなきゃいけないかも!

4

2 に答える 2

4

XSD オブジェクト型\Library\IncrementedInt 、概説したような PHP 名前空間内の PHP クラスではありません。

<?php
namespace Library;

class IncrementedInt
{
    ...

接頭辞付きのタイプは実際には次のとおりです。

tns:\Library\IncrementedInt

そしてtns:、接頭辞である前に注意してください。PHP では表現できませんでしたが、それを名前空間 URI に展開するとさらに明確になります。

{http://localhost/webservice.php}\Library\IncrementedInt

また、Zend SOAP はPHP 名前空間 (PHP 5.2)よりも前の時代に登場したため、この型を PHP 型 (クラス名) にエイリアスするには別の戦略を採用する必要があります。次のタイプのローカル名を取ります。

\Library\IncrementedInt

そして、そのタイプ名の各「無効な」文字をアンダースコアに置き換えます。

_Library_IncrementedInt

したがって、次のようにクラスに名前を付ける必要があります。

<?php

class _Library_IncrementedInt
{
    ...

すぐに使えるようにしたい場合。


次に、明確化のためにコメントを介して尋ねました:

つまり、あなたが言っているのは、名前空間化されたクラスを型名として持つためにできることは何もないということですよね?

デフォルトの動作に関してはおそらくそうではありませんが、戦略という用語が含まれているため、その操作のためにZend Soapを拡張し、たとえば名前空間付きのクラス(クラスストラテジー パターンを参照してください。

そして、これが単一のクラスにすぎない場合は、その間にいくつかの安価なトリックを実行して、名前空間付きのクラスを短い名前またはエイリアスとして拡張できますclass_alias.

于 2013-09-17T09:03:08.690 に答える