143

PHP コードの作成には慣れていますが、オブジェクト指向コーディングはあまり使用しません。SOAP を (クライアントとして) 操作する必要があり、正しい構文を取得できません。SoapClient クラスを使用して新しい接続を適切にセットアップできるようにする WSDL ファイルがあります。ただし、実際に正しい呼び出しを行ってデータを返すことはできません。次の(簡略化された)データを送信する必要があります。

  • 連絡先ID
  • 連絡先
  • 概要

WSDL ドキュメントには 2 つの関数が定義されていますが、必要なのは 1 つだけです (以下の「FirstFunction」)。使用可能な関数と型に関する情報を取得するために実行するスクリプトを次に示します。

$client = new SoapClient("http://example.com/webservices?wsdl");
var_dump($client->__getFunctions()); 
var_dump($client->__getTypes()); 

そして、生成される出力は次のとおりです。

array(
  [0] => "FirstFunction Function1(FirstFunction $parameters)",
  [1] => "SecondFunction Function2(SecondFunction $parameters)",
);

array(
  [0] => struct Contact {
    id id;
    name name;
  }
  [1] => string "string description"
  [2] => string "int amount"
}

データを使用して FirstFunction を呼び出したいとします。

  • 連絡先 ID: 100
  • 連絡先の名前: ジョン
  • 一般的な説明: 石油のバレル
  • 金額: 500

正しい構文は何でしょうか? 私はあらゆる種類のオプションを試してきましたが、石鹸の構造は非常に柔軟であるように見えるので、これを行うには非常に多くの方法があります. 説明書を見ても分かりませんでした...


更新 1: MMK からサンプルを試しました:

$client = new SoapClient("http://example.com/webservices?wsdl");

$params = array(
  "id" => 100,
  "name" => "John",
  "description" => "Barrel of Oil",
  "amount" => 500,
);
$response = $client->__soapCall("Function1", array($params));

しかし、私はこの応答を受け取ります: Object has no 'Contact' property. の出力でわかるようにgetTypes()struct呼び出されたContactがあるため、どうにかしてパラメータに Contact データが含まれていることを明確にする必要があると思いますが、問題は次のとおりです。どのように?

更新 2: 私もこれらの構造を試しましたが、同じエラーです。

$params = array(
  array(
    "id" => 100,
    "name" => "John",
  ),
  "Barrel of Oil",
  500,
);

としても:

$params = array(
  "Contact" => array(
    "id" => 100,
    "name" => "John",
  ),
  "description" => "Barrel of Oil",
  "amount" => 500,
);

どちらの場合もエラー: オブジェクトに 'Contact' プロパティがありません`

4

13 に答える 13

185

これがあなたがする必要があることです。

その様子を再現してみた…


  • この例では、次のパラメーターを想定してWebMethod呼び出された .NET サンプル WebService (WS) を作成しました。Function1

Function1(連絡先連絡先、文字列説明、int 金額)

  • あなたの場合のように、ゲッターとContactセッターを持つモデルはどこにありますか。idname

  • .NET サンプル WS は次の場所からダウンロードできます。

https://www.dropbox.com/s/6pz1w94a52o5xah/11593623.zip


コード。

これは、PHP 側で行う必要があることです。

(テスト済みで動作中)

<?php
// Create Contact class
class Contact {
    public function __construct($id, $name) 
    {
        $this->id = $id;
        $this->name = $name;
    }
}

// Initialize WS with the WSDL
$client = new SoapClient("http://localhost:10139/Service1.asmx?wsdl");

// Create Contact obj
$contact = new Contact(100, "John");

// Set request params
$params = array(
  "Contact" => $contact,
  "description" => "Barrel of Oil",
  "amount" => 500,
);

// Invoke WS method (Function1) with the request params 
$response = $client->__soapCall("Function1", array($params));

// Print WS response
var_dump($response);

?>

全体をテストします。

  • 実行print_r($params)すると、WS が期待するように、次の出力が表示されます。

Array ( [Contact] => Contact Object ( [id] => 100 [name] => John ) [description] => Barrel of Oil [amount] => 500 )

  • .NET サンプル WS をデバッグすると、次の結果が得られました。

ここに画像の説明を入力

(ご覧のとおり、Contactオブジェクトはnull他のパラメータでもありません。つまり、リクエストがPHP側から正常に実行されたことを意味します)

  • .NET サンプル WS からの応答は予期されたものであり、これは PHP 側で取得したものです。

object(stdClass)[3] public 'Function1Result' => string 'リクエストの詳細情報! id: 100、名前: ジョン、説明: バレルのオイル、量: 500' (長さ = 98)


于 2012-07-30T01:37:29.247 に答える
31

最初に Web サービスを初期化します。

$client = new SoapClient("http://example.com/webservices?wsdl");

次に、パラメータを設定して渡します。

$params = array (
    "arg0" => $contactid,
    "arg1" => $desc,
    "arg2" => $contactname
);

$response = $client->__soapCall('methodname', array($params));

メソッド名は、操作名として WSDL で使用できることに注意してください。

<operation name="methodname">
于 2012-07-21T16:18:25.030 に答える
23

私のWebサービスがあなたと同じ構造を持っている理由はわかりませんが、パラメーターにクラスは必要ありません。配列だけです。

例: - 私の WSDL:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ns="http://www.kiala.com/schemas/psws/1.0">
    <soapenv:Header/>
    <soapenv:Body>
        <ns:createOrder reference="260778">
            <identification>
                <sender>5390a7006cee11e0ae3e0800200c9a66</sender>
                <hash>831f8c1ad25e1dc89cf2d8f23d2af...fa85155f5c67627</hash>
                <originator>VITS-STAELENS</originator>
            </identification>
            <delivery>
                <from country="ES" node=””/>
                <to country="ES" node="0299"/>
            </delivery>
            <parcel>
                <description>Zoethout thee</description>
                <weight>0.100</weight>
                <orderNumber>10K24</orderNumber>
                <orderDate>2012-12-31</orderDate>
            </parcel>
            <receiver>
                <firstName>Gladys</firstName>
                <surname>Roldan de Moras</surname>
                <address>
                    <line1>Calle General Oraá 26</line1>
                    <line2>(4º izda)</line2>
                    <postalCode>28006</postalCode>
                    <city>Madrid</city>
                    <country>ES</country>
                </address>
                <email>gverbruggen@kiala.com</email>
                <language>es</language>
            </receiver>
        </ns:createOrder>
    </soapenv:Body>
</soapenv:Envelope>

私は var_dump:

var_dump($client->getFunctions());
var_dump($client->getTypes());

結果は次のとおりです。

array
  0 => string 'OrderConfirmation createOrder(OrderRequest $createOrder)' (length=56)

array
  0 => string 'struct OrderRequest {
 Identification identification;
 Delivery delivery;
 Parcel parcel;
 Receiver receiver;
 string reference;
}' (length=130)
  1 => string 'struct Identification {
 string sender;
 string hash;
 string originator;
}' (length=75)
  2 => string 'struct Delivery {
 Node from;
 Node to;
}' (length=41)
  3 => string 'struct Node {
 string country;
 string node;
}' (length=46)
  4 => string 'struct Parcel {
 string description;
 decimal weight;
 string orderNumber;
 date orderDate;
}' (length=93)
  5 => string 'struct Receiver {
 string firstName;
 string surname;
 Address address;
 string email;
 string language;
}' (length=106)
  6 => string 'struct Address {
 string line1;
 string line2;
 string postalCode;
 string city;
 string country;
}' (length=99)
  7 => string 'struct OrderConfirmation {
 string trackingNumber;
 string reference;
}' (length=71)
  8 => string 'struct OrderServiceException {
 string code;
 OrderServiceException faultInfo;
 string message;
}' (length=97)

だから私のコードでは:

    $client  = new SoapClient('http://packandship-ws.kiala.com/psws/order?wsdl');

    $params = array(
        'reference' => $orderId,
        'identification' => array(
            'sender' => param('kiala', 'sender_id'),
            'hash' => hash('sha512', $orderId . param('kiala', 'sender_id') . param('kiala', 'password')),
            'originator' => null,
        ),
        'delivery' => array(
            'from' => array(
                'country' => 'es',
                'node' => '',
            ),
            'to' => array(
                'country' => 'es',
                'node' => '0299'
            ),
        ),
        'parcel' => array(
            'description' => 'Description',
            'weight' => 0.200,
            'orderNumber' => $orderId,
            'orderDate' => date('Y-m-d')
        ),
        'receiver' => array(
            'firstName' => 'Customer First Name',
            'surname' => 'Customer Sur Name',
            'address' => array(
                'line1' => 'Line 1 Adress',
                'line2' => 'Line 2 Adress',
                'postalCode' => 28006,
                'city' => 'Madrid',
                'country' => 'es',
                ),
            'email' => 'test.ceres@yahoo.com',
            'language' => 'es'
        )
    );
    $result = $client->createOrder($params);
    var_dump($result);

しかし、それは成功しました!

于 2013-07-17T03:17:42.133 に答える
3

SoapParam のオブジェクトを作成すると、問題が解決します。クラスを作成し、それを WebService によって指定されたオブジェクト タイプにマップし、値を初期化してリクエストで送信します。以下のサンプルを参照してください。

struct Contact {

    function Contact ($pid, $pname)
    {
      id = $pid;
      name = $pname;
  }
}

$struct = new Contact(100,"John");

$soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "Contact","http://soapinterop.org/xsd");

$ContactParam = new SoapParam($soapstruct, "Contact")

$response = $client->Function1($ContactParam);
于 2012-07-25T14:19:15.953 に答える
3

これを読む;-

http://php.net/manual/en/soapclient.call.php

または

これは、SOAP 関数「__call」の良い例です。ただし、非推奨です。

<?php
    $wsdl = "http://webservices.tekever.eu/ctt/?wsdl";
    $int_zona = 5;
    $int_peso = 1001;
    $cliente = new SoapClient($wsdl);
    print "<p>Envio Internacional: ";
    $vem = $cliente->__call('CustoEMSInternacional',array($int_zona, $int_peso));
    print $vem;
    print "</p>";
?>
于 2012-07-29T19:52:32.160 に答える
3

まず、SoapUIを使用して、wsdl から SOAP プロジェクトを作成します。リクエストを送信して、wsdl の操作を試してみてください。xml リクエストがデータ フィールドを構成する方法を観察します。

そして、SoapClient が思いどおりに動作しない場合は、次のようにデバッグします。関数__getLastRequest()が使用できるようにオプションtrace を設定します。

$soapClient = new SoapClient('http://yourwdsdlurl.com?wsdl', ['trace' => true]);
$params = ['user' => 'Hey', 'account' => '12345'];
$response = $soapClient->__soapCall('<operation>', $params);
$xml = $soapClient->__getLastRequest();

$xml変数には、SoapClient がリクエスト用に構成する xml が含まれます。この xml を SoapUI で生成されたものと比較します。

私にとって、SoapClient は連想配列$paramsのキーを無視し、それをインデックス付き配列として解釈するようで、xml に間違ったパラメーター データを引き起こします。つまり、$paramsのデータを並べ替えると、$responseは完全に異なります。

$params = ['account' => '12345', 'user' => 'Hey'];
$response = $soapClient->__soapCall('<operation>', $params);
于 2018-01-26T04:25:03.873 に答える
0

多次元配列が必要です。次のことを試すことができます。

$params = array(
   array(
      "id" => 100,
      "name" => "John",
   ),
   "Barrel of Oil",
   500
);

PHP では、配列は構造体であり、非常に柔軟です。通常、soap 呼び出しでは XML ラッパーを使用するので、それが機能するかどうかはわかりません。

編集:

あなたが試してみたいのは、送信するjsonクエリを作成するか、それを使用して、このページにあるものに従ってxml購入の種類を作成することです: http://onwebdev.blogspot.com/2011/08/php-converting-rss- to-json.html

于 2012-07-23T19:29:24.210 に答える
0

クラス契約を宣言する必要があります

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

$contract = new Contract();
$contract->id = 100;
$contract->name = "John";

$params = array(
  "Contact" => $contract,
  "description" => "Barrel of Oil",
  "amount" => 500,
);

また

$params = array(
  $contract,
  "description" => "Barrel of Oil",
  "amount" => 500,
);

それで

$response = $client->__soapCall("Function1", array("FirstFunction" => $params));

また

$response = $client->__soapCall("Function1", $params);
于 2012-07-29T23:17:39.807 に答える