我如何使用从使用 php 和 Soap 的抽象复杂类型派生的复杂类型

我最近开始使用 SOAP,但发现很难理解抽象复杂类型的使用。


我正在尝试向 wsdl 发出请求,但我一直收到错误消息。'指定的类型是抽象的:name="HomeAffairsIDVRequestedBase"。


我的 php 如下:


$result = $this->soap->__soapCall('PlaceRequest',array('PlaceRequest'=>

                                               array('request' =>

                                                   array(

                                                            'type'=> 'tns:HomeAffairsIDVStandardRequest',

                                                            "IsBatchSearch"=>false,

                                                            "ParentRequestId"=>0,

                                                            "Reference"=>'test',

                                                            "Requester"=>'axxess',

                                                            "SessionId"=>'true',

                                                            "IdNumber"=>$this->idNumber

                                                            ))));

目标 wsdl 部分如下


<s:element name="PlaceRequest">

    <s:complexType>

        <s:sequence>

            <s:element minOccurs="0" maxOccurs="1" name="request" type="tns:HomeAffairsIDVRequestBase"/>

        </s:sequence>

    </s:complexType>

</s:element>

<s:complexType name="HomeAffairsIDVRequestBase" abstract="true">

    <s:sequence>

        <s:element minOccurs="1" maxOccurs="1" name="IsBatchSearch" type="s:boolean"/>

        <s:element minOccurs="1" maxOccurs="1" name="ParentRequestId" nillable="true" type="s:int"/>

        <s:element minOccurs="0" maxOccurs="1" name="Reference" type="s:string"/>

        <s:element minOccurs="0" maxOccurs="1" name="Requester" type="s:string"/>

        <s:element minOccurs="1" maxOccurs="1" name="SessionId" nillable="true" type="s1:guid"/>

    </s:sequence>

注意:我无法编辑 wsdl。


慕勒3428872
浏览 100回答 1
1回答

慕婉清6462132

您可以从 wsdl 读取复杂类型定义作为 php 类定义。每个复杂类型都是一个 php 值对象。抽象复杂类型是抽象的值对象,可以从中继承。由于我们定义了复杂类型,我们可以构建我们的 php 类。abstract class HomeAffairsIDVRequestBase&nbsp;{&nbsp; &nbsp; protected bool $IsBatchSearch;&nbsp; &nbsp; protected int $ParentRequestId;&nbsp; &nbsp; protected ?string $Reference;&nbsp; &nbsp; protected ?string $Requester;&nbsp; &nbsp; protected string $SessionId;&nbsp; &nbsp; public function getIsBatchSearch(): bool&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->IsBatchSearch;&nbsp; &nbsp; }&nbsp; &nbsp; public function setIsBatchSearch(bool $isBatchSearch): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->isBatchSearch = $isBatchSearch;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }&nbsp; &nbsp; public function getParentRequestId(): int&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->ParentRequestId;&nbsp; &nbsp; }&nbsp; &nbsp; public function setParentRequestId(int $parentRequestId): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->ParentRequestId = $parentRequestId;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }&nbsp; &nbsp; public function getReference(): ?string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->Reference;&nbsp; &nbsp; }&nbsp; &nbsp; public function setReference(string $reference): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->Reference = $reference;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }&nbsp; &nbsp; public function getRequester(): ?string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->Requester;&nbsp; &nbsp; }&nbsp; &nbsp; public function setRequester(string $requester): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->Requester = $requester;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }&nbsp; &nbsp; public function getSessionId(): string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->SessionId;&nbsp; &nbsp; }&nbsp; &nbsp; public function setSessionId(string $sessionId): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->SessionId = $sessionId;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }}这是我们作为抽象 php 类的第一个抽象复杂类型定义HomeAffairsIDVRequestBase。如您所见,抽象类具有所有属性,这些属性在 wsdl 文件中为此复杂类型定义。除此之外,我们还有 getter 和 setter 方法来更好地处理类属性。当我们查看 for 的定义时HomeAffairsIDVStandardRequest,我们可以看到它继承自HomeAffairsIDVRequest. 考虑到这一点,我们必须编写更多的 php 类。abstract class HomeAffairsIDVRequest extends HomeAffairsIDVRequestBase&nbsp;{&nbsp; &nbsp; protected ?string $IdNumber;&nbsp; &nbsp; public function getIdNumber(): ?string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->IdNumber;&nbsp; &nbsp; }&nbsp; &nbsp; public function setIdNumber(?string $idNumber): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->IdNumber = $idNumber;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }}class HomeAffairsIDVStandardRequest extends HomeAffairsIDVRequest{}由于其中一种复杂类型HomeAffairsIDVStandardRequest不是HomeAffairsIDVAdvancedRequest抽象的,因此可以将此类用于请求。请记住,抽象 php 类不能直接初始化。wsdl 中的抽象复杂类型也是如此。现在我们需要将请求元素作为一个类。这是我们 soap 请求中的父元素。该PlaceRequest元素只有一个属性,称为request。由于此元素是 的继承HomeAffairsIDVRequestBase并且此定义是抽象的,因此我们必须稍后在请求中使用类型属性。class PlaceRequest&nbsp;{&nbsp; &nbsp; protected HomeAffairsIDVRequestBase $request;&nbsp; &nbsp; public function getRequest(): HomeAffairsIDVRequestBase&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->request;&nbsp; &nbsp; }&nbsp; &nbsp; public function setRequest(HomeAffairsIDVRequestBase $request): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->request = $request;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }}到目前为止,我们将数据结构作为 PHP 值对象。到目前为止,这就是我们所需要的。现在让我们看一下可能的请求。try {&nbsp; &nbsp; $wsdl = 'https://path.to.your.wsdl.file.com?wsdl';&nbsp; &nbsp; $client = new SoapClient($wsdl, [&nbsp; &nbsp; &nbsp; &nbsp; 'exceptions' => true,&nbsp; &nbsp; &nbsp; &nbsp; 'trace' => true,&nbsp; &nbsp; ]);&nbsp; &nbsp; // initialize our value object&nbsp; &nbsp; $standard = (new HomeAffairsIDVStandardRequest())&nbsp; &nbsp; &nbsp; &nbsp; ->setIsBatchSearch(false)&nbsp; &nbsp; &nbsp; &nbsp; ->setParentRequestId(0)&nbsp; &nbsp; &nbsp; &nbsp; ->setReference('test')&nbsp; &nbsp; &nbsp; &nbsp; ->setRequester('requester')&nbsp; &nbsp; &nbsp; &nbsp; ->setSessionId('true')&nbsp; &nbsp; &nbsp; &nbsp; ->setIdNumber($idNumber);&nbsp; &nbsp; // initialize our request element&nbsp; &nbsp; $request = (new PlaceRequest())&nbsp; &nbsp; &nbsp; &nbsp; ->setRequest($standard);&nbsp; &nbsp; $response = $client->placeRequest($request);} catch (SoapFault $fault) {&nbsp; &nbsp; // error handling like var_dump($fault)}由于我没有看到完整的 wsdl 内容,所以我不能说请求 XML 应该是什么样子。上面显示的结果可能会导致 soap 故障。在这种情况下,请尝试以下示例。更改类中的类型提示PlaceRequest。class PlaceRequest&nbsp;{&nbsp; &nbsp; protected SoapVar $request;&nbsp; &nbsp; public function getRequest(): SoapVar&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->request;&nbsp; &nbsp; }&nbsp; &nbsp; public function setRequest(SoapVar $request): self&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->request = $request;&nbsp; &nbsp; &nbsp; &nbsp; return $this;&nbsp; &nbsp; }}之后使用该实例创建一个新的 SoapVar 实例$standard。// we 've already defined the $standard object above (sets an type attribute for the request node)$standard = new SoapVar($standard, SOAP_ENC_OBJECT, 'HomeAffairsIDVStandardRequest', 'http://your.namespace.tld/namespace', 'request', 'http://your.namespace.tld/namespace');// initialise the request element and set the soap var parameter$request = (new PlaceRequest())&nbsp; &nbsp; ->setRequest($standard);// send it via soap client$client->PlaceRequest($request);作为附加信息,您应该始终查看发送的 xml 和接收到的 xml,以便更好地了解错误处理。我们trace在初始化 soap 客户端时设置了选项。这使我们能够看到最后的请求和最后的响应是什么。...} catch (SoapFault $fault) {&nbsp; &nbsp; if ($client) {&nbsp; &nbsp; &nbsp; &nbsp; // get last request&nbsp; &nbsp; &nbsp; &nbsp; var_dump($client->__getLastRequest());&nbsp; &nbsp; &nbsp; &nbsp; // get last response&nbsp; &nbsp; &nbsp; &nbsp; var_dump($client->__getLastResponse());&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP