如何使用 SoapClient 类进行 PHP SOAP 调用

2021-12-24 00:00:00 php soap

我习惯于编写 PHP 代码,但不经常使用面向对象的编码.我现在需要与 SOAP(作为客户端)交互,但无法正确使用语法.我有一个 WSDL 文件,它允许我使用 SoapClient 类正确设置新连接.但是,我实际上无法进行正确的调用并返回数据.我需要发送以下(简化的)数据:

I'm used to writing PHP code, but do not often use Object-Oriented coding. I now need to interact with SOAP (as a client) and am not able to get the syntax right. I've got a WSDL file which allows me to properly set up a new connection using the SoapClient class. However, I'm unable to actually make the right call and get data returned. I need to send the following (simplified) data:

  • 联系人 ID
  • 联系人姓名
  • 一般说明
  • 金额

WSDL 文档中定义了两个函数,但我只需要一个(下面的FirstFunction").这是我运行的脚本以获取有关可用函数和类型的信息:

There are two functions defined in the WSDL document, but I only need one ("FirstFunction" below). Here is the script I run to get information on the available functions and types:

$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:

Say I want to make a call to the FirstFunction with the data:

  • 联系人 ID:100
  • 联系人姓名:约翰
  • 一般描述:一桶油
  • 数量:500

正确的语法是什么?我一直在尝试各种选择,但看起来肥皂结构非常灵活,因此有很多方法可以做到这一点.手册上也查不到...

What would be the right syntax? I've been trying all sorts of options but it appears the soap structure is quite flexible so there are very many ways of doing this. Couldn't figure it out from the manual either...

更新 1:来自 MMK 的尝试样本:

UPDATE 1: tried sample from 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,所以我想我需要以某种方式明确我的参数包括联系人数据,但问题是:如何?

But I get this response: Object has no 'Contact' property. As you can see in the output of getTypes(), there is a struct called Contact, so I guess I somehow need to make clear my parameters include the Contact data, but the question is: how?

更新 2:我也试过这些结构,同样的错误.

UPDATE 2: I've also tried these structures, same error.

$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,
);

两种情况下的错误:对象没有联系人"属性`

Error in both cases: Object has no 'Contact' property`

推荐答案

这是你需要做的.

我试图重现这种情况...

This is what you need to do.

I tried to recreate the situation...

  • 对于本示例,我创建了一个 .NET 示例 WebService (WS),其中包含一个名为 Function1WebMethod,需要以下参数:
  • For this example, I created a .NET sample WebService (WS) with a WebMethod called Function1 expecting the following params:

Function1(Contact Contact, string description, int amount)

Function1(Contact Contact, string description, int amount)

  • 其中 Contact 只是一个具有 idname 的 getter 和 setter 的模型,就像您的情况一样.

    • Where Contact is just a model that has getters and setters for id and name like in your case.

      您可以在以下位置下载 .NET 示例 WS:

      You can download the .NET sample WS at:

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

      这是你在 PHP 端需要做的:

      This is what you need to do at PHP side:

      (经过测试和工作)

      <?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 所期望的:

      • Testing the whole thing.

        • If you do print_r($params) you will see the following output, as your WS would expect:
        • Array ( [Contact] => Contact Object ( [id] => 100 [name] => John )[说明] =>每桶油 [数量] =>500)

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

          • 当我调试 .NET 示例 WS 时,我得到以下信息:
          • (如您所见,Contact 对象既不是 null 也不是其他参数.这意味着您的请求已从 PHP 端成功完成)

            (As you can see, Contact object is not null nor the other params. That means your request was successfully done from PHP side)

            • 来自 .NET 示例 WS 的响应是预期的响应,这就是我在 PHP 方面得到的响应:

            object(stdClass)[3] public 'Function1Result' =>字符串 '详细您的请求信息!id:100,姓名:John,描述:桶油,数量:500'(长度=98)

            object(stdClass)[3] public 'Function1Result' => string 'Detailed information of your request! id: 100, name: John, description: Barrel of Oil, amount: 500' (length=98)

相关文章