使用 PHP 和 cURL 将 Web 服务 MS .Net 调用到公开的函数并返回值

Calling a webservice MS .Net using PHP and cURL to a function that's exposed and returning the values

提问人:Singleton 提问时间:4/22/2021 更新时间:4/29/2021 访问量:168

问:

这比我预期的要困难得多。我正在尝试调用一个调用的函数并返回它的参数。我试图返回的参数是Get_Item_Quantity

函数名称:Get_Item_Quantity 此函数采用 、fields 并返回 和 参数:TypeCodeQty1, Qty2, Qty3,Qty4

Type = 0 – input value
Code = ‘product100317’ – input value
Qty 1 – return value
Qty 2 – return value
Qty 3 – return value
Qty 4 – return value

这是我的代码:

<?php

namespace Test\CustomApi\Model\Api;

use Psr\Log\LoggerInterface;

class Custom
{
    protected $logger;

    public function __construct(
        LoggerInterface $logger
    )
    {
        $this->logger = $logger;
    }

    /**
     * @inheritdoc
     */
    public function getQty($type, $code, $qty1, $qty2, $qty3, $qty4) {
        $response = ['success' => false];

        try {
            // Logic to call soap service here
            $qty = $this->getItemQty($type, $code, $qty1, $qty2, $qty3, $qty4);
            $response = ['success' => true, 'qty' => $qty];

        } catch (\Exception $e) {
            $response = ['success' => false, 'message' => $e->getMessage()];
            $this->logger->info($e->getMessage());
        }

        $returnArray = json_encode($response);
        return $returnArray;
    }


    /**
     * Soap API call 
     *
     * @param int $type
     * @param string $code
     * @param string $qty1
     * @param string $qty2
     * @param string $qty3
     * @param string $qty4
     * @return void
     */
    public function getItemQty($type, $code, $qty1, $qty2, $qty3, $qty4)
    {
        $soapRequest = '<?xml version="1.0" encoding="utf-8"?>
        <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
          <soap12:Body>
          <APIDataCapture>
            <Get_Item_Quantity xmlns="URLwheresoapxmlexists">
                <Type>' . $type . '</Type>
                <Code>' . $code . '</Code>
                <qty1>' . $qty1 . '</qty1>
                <qty2>' . $qty2 . '</qty2>
                <qty3>' . $qty3 . '</qty3>
                <qty4>' . $qty4 . '</qty4>
            </Get_Item_Quantity>
            </APIDataCapture>
          </soap12:Body>
        </soap12:Envelope>';
        $header = array(
            "Content-type: text/xml;charset=\"utf-8\"",
            "Accept: text/xml",
        );
        $soapHandler = curl_init();
        curl_setopt($soapHandler, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1');
        curl_setopt($soapHandler, CURLOPT_URL, "URLwheresoapxmlexists");
        curl_setopt($soapHandler, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($soapHandler, CURLOPT_CONNECTTIMEOUT, 0);
        curl_setopt($soapHandler, CURLOPT_POST, true);
        curl_setopt($soapHandler, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($soapHandler, CURLOPT_POSTFIELDS, $soapRequest);
        curl_setopt($soapHandler, CURLOPT_HTTPHEADER, $header);
        curl_setopt($soapHandler, CURLOPT_FOLLOWLOCATION, false);
        //header('Content-type: text/xml');
        $result = curl_exec($soapHandler);
        $qtyData = array();
        if ($result === false) {
            $err = 'Curl error: ' . curl_error($soapHandler);
            curl_close($soapHandler);
            $this->logger->info($err);
        } else {
            curl_close($soapHandler);
            $xml = simplexml_load_string($result);
            $xml->registerXPathNamespace('soap', 'http://www.w3.org/2003/05/soap-envelope');
            $result = $xml->xpath('/soap:Envelope/soap:Body');
            $res = $result[0]->Get_Item_Quantity_Result;
            $qtyData = simplexml_load_string($res);
        }
        return $qtyData;
    }
}

当我在 postman 中运行 POST 请求时,我收到了这个回复。

"{\"success\":true,\"qty\":[]}"

enter image description here

下面是带有公开函数的 SOAP XML 文档:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:microsoft-dynamics-schemas/codeunit/myWSAPI"
             targetNamespace="urn:microsoft-dynamics-schemas/codeunit/myWSAPI">
    <types>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:microsoft-dynamics-nav/xmlports/x00000"
                elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-nav/xmlports/x00000">
            <complexType name="APIDataCapture">
                <sequence>
                    <element minOccurs="1" maxOccurs="1" name="Type" type="string"/>
                    <element minOccurs="1" maxOccurs="1" name="Code" type="string"/>
                    <element minOccurs="1" maxOccurs="1" name="Qty1" type="string"/>
                    <element minOccurs="1" maxOccurs="1" name="Qty2" type="string"/>
                    <element minOccurs="1" maxOccurs="1" name="Qty3" type="string"/>
                    <element minOccurs="1" maxOccurs="1" name="Qty4" type="string"/>
                </sequence>
            </complexType>
            <complexType name="Root" mixed="true">
                <sequence>
                    <element minOccurs="1" maxOccurs="unbounded" name="APIDataCapture" type="tns:APIDataCapture"/>
                </sequence>
            </complexType>
            <element name="Root" type="tns:Root"/>
        </schema>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:microsoft-dynamics-nav/xmlports/x50014"
                elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-nav/xmlports/x50014">
            <complexType name="APIDataCapture">
                <sequence>
                    <element minOccurs="1" maxOccurs="1" name="Type" type="string"/>
                    <element minOccurs="1" maxOccurs="1" default="0" name="EntryNo" type="int"/>
                    <element minOccurs="1" maxOccurs="1" name="SalesOrderFound" type="string"/>
                    <element minOccurs="1" maxOccurs="1" name="SalesOrderNo" type="string"/>
                    <element minOccurs="1" maxOccurs="1" default="0" name="SalesOrderLineNo" type="int"/>
                    <element minOccurs="1" maxOccurs="1" name="SalesOrderETADate" type="string"/>
                    <element minOccurs="1" maxOccurs="1" name="SalesOrderItemNo" type="string"/>
                </sequence>
            </complexType>
            <complexType name="Root" mixed="true">
                <sequence>
                    <element minOccurs="1" maxOccurs="unbounded" name="APIDataCapture" type="tns:APIDataCapture"/>
                </sequence>
            </complexType>
            <element name="Root" type="tns:Root"/>
        </schema>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
                targetNamespace="urn:microsoft-dynamics-schemas/codeunit/MyWSAPI">
            <element name="Get_Item_ETA_Date">
                <complexType>
                    <sequence>
                        <element minOccurs="1" maxOccurs="1" name="itemNo" type="string"/>
                    </sequence>
                </complexType>
            </element>
            <element name="Get_Item_ETA_Date_Result">
                <complexType>
                    <sequence>
                        <element minOccurs="1" maxOccurs="1" name="return_value" type="date"/>
                    </sequence>
                </complexType>
            </element>
            <element name="Find_Duplicate_Ext_Doc_No">
                <complexType>
                    <sequence>
                        <element minOccurs="1" maxOccurs="1" name="custNo" type="string"/>
                        <element minOccurs="1" maxOccurs="1" name="extDocNo" type="string"/>
                    </sequence>
                </complexType>
            </element>
            <element name="Find_Duplicate_Ext_Doc_No_Result">
                <complexType>
                    <sequence>
                        <element minOccurs="1" maxOccurs="1" name="return_value" type="boolean"/>
                    </sequence>
                </complexType>
            </element>
            <element name="Get_Item_Quantity">
                <complexType>
                    <sequence>
                        <element xmlns:q1="urn:microsoft-dynamics-nav/xmlports/x00000" minOccurs="1" maxOccurs="1"
                                 name="aPIDataCapture" type="q1:Root"/>
                    </sequence>
                </complexType>
            </element>
            <element name="Get_Item_Quantity_Result">
                <complexType>
                    <sequence>
                        <element xmlns:q2="urn:microsoft-dynamics-nav/xmlports/x00000" minOccurs="1" maxOccurs="1"
                                 name="aPIDataCapture" type="q2:Root"/>
                    </sequence>
                </complexType>
            </element>
            <element name="GetSalesOrderETA">
                <complexType>
                    <sequence>
                        <element xmlns:q3="urn:microsoft-dynamics-nav/xmlports/x50014" minOccurs="1" maxOccurs="1"
                                 name="aPIDataCapture" type="q3:Root"/>
                    </sequence>
                </complexType>
            </element>
            <element name="GetSalesOrderETA_Result">
                <complexType>
                    <sequence>
                        <element xmlns:q4="urn:microsoft-dynamics-nav/xmlports/x50014" minOccurs="1" maxOccurs="1"
                                 name="aPIDataCapture" type="q4:Root"/>
                    </sequence>
                </complexType>
            </element>
        </schema>
    </types>
    <message name="Get_Item_ETA_Date">
        <part name="parameters" element="tns:Get_Item_ETA_Date"/>
    </message>
    <message name="Get_Item_ETA_Date_Result">
        <part name="parameters" element="tns:Get_Item_ETA_Date_Result"/>
    </message>
    <message name="Find_Duplicate_Ext_Doc_No">
        <part name="parameters" element="tns:Find_Duplicate_Ext_Doc_No"/>
    </message>
    <message name="Find_Duplicate_Ext_Doc_No_Result">
        <part name="parameters" element="tns:Find_Duplicate_Ext_Doc_No_Result"/>
    </message>
    <message name="Get_Item_Quantity">
        <part name="parameters" element="tns:Get_Item_Quantity"/>
    </message>
    <message name="Get_Item_Quantity_Result">
        <part name="parameters" element="tns:Get_Item_Quantity_Result"/>
    </message>
    <message name="GetSalesOrderETA">
        <part name="parameters" element="tns:GetSalesOrderETA"/>
    </message>
    <message name="GetSalesOrderETA_Result">
        <part name="parameters" element="tns:GetSalesOrderETA_Result"/>
    </message>
    <portType name="MyWSAPI_Port">
        <operation name="Get_Item_ETA_Date">
            <input name="Get_Item_ETA_Date" message="tns:Get_Item_ETA_Date"/>
            <output name="Get_Item_ETA_Date_Result" message="tns:Get_Item_ETA_Date_Result"/>
        </operation>
        <operation name="Find_Duplicate_Ext_Doc_No">
            <input name="Find_Duplicate_Ext_Doc_No" message="tns:Find_Duplicate_Ext_Doc_No"/>
            <output name="Find_Duplicate_Ext_Doc_No_Result" message="tns:Find_Duplicate_Ext_Doc_No_Result"/>
        </operation>
        <operation name="Get_Item_Quantity">
            <input name="Get_Item_Quantity" message="tns:Get_Item_Quantity"/>
            <output name="Get_Item_Quantity_Result" message="tns:Get_Item_Quantity_Result"/>
        </operation>
        <operation name="GetSalesOrderETA">
            <input name="GetSalesOrderETA" message="tns:GetSalesOrderETA"/>
            <output name="GetSalesOrderETA_Result" message="tns:GetSalesOrderETA_Result"/>
        </operation>
    </portType>
    <binding name="MyWSAPI_Binding" type="tns:MyWSAPI_Port">
        <binding xmlns="http://schemas.xmlsoap.org/wsdl/soap/" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="Get_Item_ETA_Date">
            <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/"
                       soapAction="urn:microsoft-dynamics-schemas/codeunit/MyWSAPI:Get_Item_ETA_Date" style="document"/>
            <input name="Get_Item_ETA_Date">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </input>
            <output name="Get_Item_ETA_Date_Result">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </output>
        </operation>
        <operation name="Find_Duplicate_Ext_Doc_No">
            <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/"
                       soapAction="urn:microsoft-dynamics-schemas/codeunit/myWSAPI:Find_Duplicate_Ext_Doc_No"
                       style="document"/>
            <input name="Find_Duplicate_Ext_Doc_No">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </input>
            <output name="Find_Duplicate_Ext_Doc_No_Result">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </output>
        </operation>
        <operation name="Get_Item_Quantity">
            <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/"
                       soapAction="urn:microsoft-dynamics-schemas/codeunit/myWSAPI:Get_Item_Quantity" style="document"/>
            <input name="Get_Item_Quantity">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </input>
            <output name="Get_Item_Quantity_Result">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </output>
        </operation>
        <operation name="GetSalesOrderETA">
            <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/"
                       soapAction="urn:microsoft-dynamics-schemas/codeunit/myWSAPI:GetSalesOrderETA" style="document"/>
            <input name="GetSalesOrderETA">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </input>
            <output name="GetSalesOrderETA_Result">
                <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/>
            </output>
        </operation>
    </binding>
    <service name="myWSAPI">
        <port name="myWSAPI_Port" binding="tns:MyWSAPI_Binding">
            <address xmlns="http://schemas.xmlsoap.org/wsdl/soap/"
                     location="http://test.myapi.local:7947/my/path/here/myWSAPI"/>
        </port>
    </service>
</definitions>
php xml 卷曲 肥皂

评论

0赞 Zenithies 4/28/2021
在发送请求之前,是否需要执行任何类型的身份验证?运行代码时会发生什么情况?有错误消息吗?也许尝试从控制台运行它,以便您可以检查您的请求发生了什么?curl_setopt($soapHandler, CURLOPT_VERBOSE, true);
0赞 Singleton 4/29/2021
我在邮递员应用程序中添加了我的 NTLM 身份验证。@Zenithies
0赞 Singleton 4/29/2021
我是否没有正确调用/返回数组?为什么我只得到“{\”success\“:true,\”qty\“:[]}”???这是什么意思..我是否成功访问了 XML 文档?

答:

1赞 Klaassiek 4/29/2021 #1

显然,该函数返回 .但是您的代码返回:curl_execfalse

$response = ['success' => true, 'qty' => $qty];//$qty is the empty array []

所以,即使失败了,你也会得到这个答案。您确实有一个日志功能,因此您应该检查日志以查看任何错误消息。或者,出于测试目的,可以将错误添加到 Postman 中查看错误:curl$qtyData

curl_close($soapHandler);
$qtyData[] = $err; // add this line ONLY FOR TESTING
$this->logger->info($err);

该错误将帮助您调试 curl 请求出了什么问题。您可能要检查的一件事是授权。您当前仅将以下两个 http 标头用于请求,但您的 SOAP 服务可能需要某种授权令牌(请参阅文档):

"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",

评论

0赞 Singleton 4/29/2021
嘿,@Klassiek,我认为这个错误对我帮助很大。我现在收到此错误:“{\”success\“:true,\”qty\“:[\”Curl error: Could not resolve host: na-devapp.mysite.local\“]}”
0赞 Singleton 4/29/2021
有两件事,我必须连接到我的 vpn 才能点击主机链接。我在当前连接到我的 netextender/vpn 客户端的计算机上运行 postman。此外,我正在邮递员中添加我的 NTLM 身份验证。您是否认为我需要更多的授权,就像您也建议令牌一样?
0赞 Klaassiek 4/29/2021
我不知道您是否需要身份验证。只是说你的 curl 请求没有设置身份验证标头。我可能会在这里感到困惑,但是如果您需要此身份验证,则向 Postman 请求添加身份验证,然后运行一个 scipt 来执行没有任何身份验证的请求,这是行不通的。curl
0赞 Singleton 4/29/2021
好吧,所以我不知道......我需要在我的 curl 脚本中设置用户名和密码吗?
1赞 Klaassiek 4/29/2021
正如我所说,我不知道您应该如何进行身份验证。它位于 SOAP 服务端点的文档中。你有关于该端点的文档吗?