eftec/cloudking

PHP 的 SOAP 服务器

3.0 2020-10-26 21:19 UTC

This package is auto-updated.

Last update: 2024-08-27 05:20:48 UTC


README

PHP 5.6 及更高版本的 SOAP 服务器引擎。

它支持 SOAP 1.1、1.2 或两者。JAVA 通常支持 1.1,C# 支持两者。

Packagist Total Downloads Maintenance composer php php CocoaPods

UI 示例

为什么我们需要 Web 服务 SOAP?

因为一些旧项目仍在使用它。SOAP 也是声明式的(与缺乏规范的 REST 相比)

为什么要使用这个库?

  • 它生成服务器(服务类和客户端)
  • 它生成 WSDL。
  • 它与复杂结构一起工作。

入门

1. 创建定义

定义类是什么。它是一个定义了 Web 服务名称、命名空间、函数和复杂类型的类。

在本例中,我们定义了一个简单的函数:function hello($param);

class ExampleDefinition {
    public static $service;

    /**
     * You must create this file manually.
     *
     * @param bool $gui if true then it shows the web gui
     */
    public static function init($gui = true) {
        $FILE = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'];
        $NAMESPACE
            = 'http://www.examplenamespace.cl/'; // the namespace of the web service. It could be anything and not specifically an existing url
        $NAME_WS = 'Example2WS'; // the name of the service

        self::$service = new CloudKing($FILE, $NAMESPACE, $NAME_WS);
        self::$service->allowed_input['gui'] = $gui; // set to false to disable the web gui.
        self::$service->serviceInstance = null;
        self::$service->verbose = 2; // for debug purpose
        self::$service->description = 'Example server SoapKing';

        self::$service->addfunction('hello',
            [
                self::$service->param('param', 'string', true, false),
            ],
            [
                self::$service->param('return', 'string')
            ],
            'Example of function'
        );
    }

    public static function run() {
        $r = self::$service->run();
        echo $r;
    }
}

我们将在稍后详细介绍。

2. 首次运行。

让我们称这个定义为以下内容

<?php

include 'ExampleDefinition.php';

ExampleDefinition::init();
ExampleDefinition::run();

目前,这个 Web 服务没有运行,因为我们没有将定义与一个真实函数关联。函数定义在 SERVICE CLASS 类中。

docs/helloservice.jpg

这里有你服务的定义和相关信息。如果你想禁用它,你可以禁用 $GUI 或将 VERBOSE 降至 0。

3. 调用服务

目前,服务不完整,但你可以测试它。如果你点击 WSDL 描述,它将显示一个巨大的 XML 文件。你可以下载它或复制地址(以 ?wsdl 结尾)

在这个例子中,我们将使用程序 SOAPUI(有免费和付费版本)

打开 SOAPUI(或你想要使用的程序),粘贴 wsdl 地址(在上一步中获取)并运行它。

docs/hellosoap.jpg

它将显示定义的所有方法。在我们的案例中,有一个名为 "hello" 的单个函数。然后,你可以运行它。

docs/hellosoap2.jpg

如果你运行它,它将失败。为什么?因为它还没有定义服务类。

4. 服务类

在我们的网站上,有一个名为 SOURCE GENERATION 的链接。点击它,将显示下一个屏幕。

你可以生成 c# 代码,以及 PHP 代码(服务器和客户端)。我们需要生成服务器源代码。如果你点击 View PHP Server Source,你可以查看代码。然而,你还可以直接生成它。但是,为了做到这一点,你需要设置文件夹

docs/helloservice2.jpg

让我们修改步骤 2 的文件

<?php

include 'ExampleDefinition.php';

ExampleDefinition::init();
ExampleDefinition::$service->folderServer=__DIR__; // or you could select any folder.
ExampleDefinition::run();

如果我们刷新网站,它将显示

docs/helloservice3.jpg

因此,你可以自动生成 1 个类和 1 个接口。点击它,它将生成这两个文件

docs/helloservice4.jpg

它将生成 service 文件夹和 2 个文件

📁 service

___ 📃 ExampleHelloService.php(我们的服务类)

___ 📃 IExampleHelloService.php(接口类)

5. 编辑服务类。

这个类是半自动生成的。我们可以在类中编辑我们的操作,所以让我们更改我们的代码。

class ExampleHelloService implements IExampleHelloService {

   /**
    * @inheritDoc
    */
   public function hello(&$param) {
      return $param." world!"; // <--- edit this.
   }
} // end class 

6. 编辑我们的服务

让我们再次修改步骤 2 中定义的服务,现在我们必须指定我们的服务类(在步骤 4 中创建)

ExampleDefinition::init();
ExampleDefinition::$service->folderServer=__DIR__; // or you could select any folder.run_initial.php
ExampleDefinition::$service->serviceInstance=new ExampleHelloService();
ExampleDefinition::run();

然后我们再次使用 SOAPUI 运行它

docs/hellosoap3.jpg

现在,服务已经启动并运行。

你可以稍后禁用 GUI

定义

参数

参数用于指示函数的参数、函数的返回值或复杂结构的字段。

定义单个参数。

param(参数名, 类型, 引用, 必需, 描述)

  • 参数名称:参数的名称,例如 "idCompany"、"money" 等
  • 类型:参数的类型。它可以是基本类型(字符串、整数等)或通过结构/类定义(称为复杂类型)。如果我们想使用复杂类型,我们需要在使用之前定义它。
  • 引用:(可选)如果为 true,则返回值。如果为 false,则不返回值。
  • 必需:(可选)如果为 true,则必需提供值。
  • 描述:(可选)参数的可选描述。
self::$service->param('counter', 'integer') // a parameter called "counter" of the type integer
self::$service->param('name', 'string', true, false, "description") // a string parameter called "name"
self::$service->param('prod', 'Product', true, false, "description") // a parameter called "prod" of the complex type Product (it must be defined)

定义参数数组

也可以定义参数数组(列表)。

paramList(参数名称, 类型, 引用, 必需, 描述 )

self::$service->paramList('names', 'string') // defining an array of string called "names"
self::$service->paramList('productList', 'Product',false,false,'List of products') // defining an array of complex type Product called "productList"

注意:此函数会自动定义一个名为 ArrayOf<参数名称> 的复杂类型。如果存在具有相同名称的复杂类型,则使用它而不是创建新的。

复杂类型

还可以定义复杂类型。当需要定义模型或结构时,会使用复杂类型。

addType(类型名称, [参数] , 描述)

  • 类型名称:它是类型名称。名称的大小写是重要的。
  • 参数:我们可以为类型定义一个或多个参数。我们甚至可以定义参数列表或使用复杂类型的参数。
  • 描述:(可选)类型的描述
self::$service->addtype('Product',
    [
        self::$service->param('idProduct', 'int',false,true, 'comentary'),
        self::$service->param('name', 'string'),
        self::$service->param('price', 'int')
    ]);

示例:定义一个包含发票详情的复杂类型发票。

self::$service->addtype('InvoiceDetail', [
    self::$service->param('idInvoiceDetail', 'int'),
    self::$service->param('idInvoice', 'int'),
    self::$service->param('detail', 'string')
]);
self::$service->addtype('Invoice', [
    self::$service->param('idInvoice', 'int'),
    self::$service->paramList('details','InvoiceDetail'),
]);

版本

  • 3.0
    • 重新构建了引擎。现在 SOAP 和 JSON 可以正确工作。
  • 2.6
    • 修复了客户端在返回对象数组时的错误。
  • 2.5
    • 更改了 xml 序列化
  • 2.4.1 使用 composer.json 修复了一个问题
  • 2.4 一个新版本