SOAP 调用在 SoapUI 中有效,但在 PHP 中使用soapclient 失败 - 对象引用问题

2024-02-12

尝试使用 PHP 5.x 查询托管在 IIS 服务器上的 .NET Web 服务

$wsdl_path = "http://192.168.1.1/TestSite/TestService.asmx?wsdl";
$soapClient = new SoapClient($wsdl_path, array('trace' => 1));
$dump=var_export($soapClient->__getFunctions(), true);
echo htmlentities($dump);

produces

array (
  0 => 'ProcessTransactionResponse ProcessTransaction(ProcessTransaction $parameters)',
  1 => 'ProcessTransactionResponse ProcessTransaction(ProcessTransaction $parameters)',
)

这表明它正在正确访问 wsdl 文件。

使用 SoapUI 验证的格式正确的查询如下

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.mydomain.tld/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:ProcessTransaction>
        <!--Optional:-->
         <ws:request>
            <!--Optional:-->
            <ws:Header>
               <!--Optional:-->
               <ws:Token>hello</ws:Token>
            </ws:Header>
            <!--Optional:-->
            <ws:Parameters>
               <ws:DeviceID>12345</ws:DeviceID>
               <ws:SourceScreen>12345</ws:SourceScreen>
               <!--Optional:-->
               <ws:Language>E</ws:Language>
               <ws:LocalDateTime>2015-05-20T11:59:29.910Z</ws:LocalDateTime>
               <ws:TicketID>12345</ws:TicketID>
               <ws:PayScreenAttributeID>12345</ws:PayScreenAttributeID>
               <!--Optional:-->
               <ws:InputValue>1234556789</ws:InputValue>
               <ws:PaymentAmount>0</ws:PaymentAmount>
               <!--Optional:-->
               <ws:POSReceiptCustomer>?</ws:POSReceiptCustomer>
               <!--Optional:-->
               <ws:POSReceiptMerchant>?</ws:POSReceiptMerchant>
            </ws:Parameters>
         </ws:request>
      </ws:ProcessTransaction>
   </soapenv:Body>
</soapenv:Envelope>

因此,为了使用 PHP 和 SoapClient 复制此内容,我收集了数组中的数据元素

$inputParams=array(
    'Token' => 'hello',
    'DeviceID' => 12345,
    'SourceScreen' => 12345,
    'Language' => 'E',
    'LocalDateTime' => '2015-05-20T11:59:29.910Z',  
    'TicketID' => 12345,
    'PayScreenAttributeID' => 12345,
    'InputValue' => '123456789',
    'PaymentAmount' => 0,
    'POSReceiptCustomer' => '?',
    'POSReceiptMerchant' => '?',
);

并执行查询

try {
    $response = $soapClient->__soapCall('ProcessTransaction', array('parameters' => $inputParams));
    var_dump($response);
} catch (SoapFault $fault) {
    var_dump($fault);
    echo "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})";
    echo "REQUEST:\n" . htmlentities($soapClient->__getLastRequest()) . "\n";
}

我得到了可怕的Server was unable to process request. ---> Object reference not set to an instance of an object.这不是很有用。

当我看着__getLastRequest()输出,它似乎显示了包装器,但没有显示任何查询元素

REQUEST:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://ws.mydomain.tld/"><SOAP-ENV:Body><ns1:ProcessTransaction/></SOAP-ENV:Body></SOAP-ENV:Envelope>

我尝试过使用和不使用 Token 元素都无济于事,并且最初遗漏了可选字段(在 SoapUI 界面中工作正常),但也没有任何乐趣。

我怀疑它与带有 Token 元素的附加标头容器有关,因为我们的其他肥皂实现未包含此元素。


您可能是对的,标题是原因,或者至少是其中的一部分。我目前无法轻松访问肥皂服务器,但我希望下面至少可以给出一些指示。

这里有两种可能性:要么标头应该作为 SoapHeader 对象包含在内,要么您需要以不同的方式构建参数数组。我将列出这两个版本。

无论哪种方式,您都可以跳过__soapCall()方法并使用 magic 方法,因为您似乎正在使用 wsdl。

参数版本(先试试这个)

如果幸运的话,您只需要重新格式化正文以适应给定的模式。老实说,看起来有点像那样。像这样的事情:

$params = array(
    'request' => array(
        'Header' => array(
            'Token' => 'hello'
        ),
        'Parameters' => array(
            'DeviceID' => 12345,
            'SourceScreen' => 12345,
            'Language' => 'E',
            'LocalDateTime' => '2015-05-20T11:59:29.910Z',  
            'TicketID' => 12345,
            'PayScreenAttributeID' => 12345,
            'InputValue' => '123456789',
            'PaymentAmount' => 0,
            'POSReceiptCustomer' => '?',
            'POSReceiptMerchant' => '?'
        )
    )
);

$wsdl_path = "http://192.168.1.1/TestSite/TestService.asmx?wsdl";
$soapClient = new SoapClient($wsdl_path, array('trace' => 1));
$response = $soapClient->ProcessTransaction($params);

SoapHeader 版本

如果您确实需要正确的标头,您需要做的是创建一个标头对象并将其附加到您已实例化的客户端。然后,您可以调用端点。

为此,您需要知道名称空间,应该调用该名称空间targetNameSpace在你的架构中。您还需要知道名称,您可以在例如中看到该名称。 SoapUI。

最后,直接提供参数就足够了 - 无需将它们放入单元素数组中。所以你最终会得到如下所示的结果。运气好的话,这至少可以让你朝着正确的方向前进。 :)

// instantiate soap client
$wsdl_path = "http://192.168.1.1/TestSite/TestService.asmx?wsdl";
$soapClient = new SoapClient($wsdl_path, array('trace' => 1));

// create and attach a header
$header = new SoapHeader($namespace, $name, array('Token' => 'hello'));
$soapClient->__setSoapHeaders($header);

// call the endpoint
$response = $soapClient->ProcessTransaction($inputParams);
var_dump($response); // hopefully you get something back...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SOAP 调用在 SoapUI 中有效,但在 PHP 中使用soapclient 失败 - 对象引用问题 的相关文章

随机推荐

  • 我怎样才能在 C# 中得到这个正则表达式?

    我正在尝试匹配任何具有type Data 然后将其替换为我想要的文本 下面给出了一个示例输入 可以有一个或多个 layer name cifar type Data top data top label include phase TRAI
  • 如何传递Python args和kwargs?

    虽然我对 Python 的 args 和 kwargs 有一个大致的了解 我认为 但我很难理解如何将它们从一个函数传递到另一个函数 这是我的模型 from pdb import set trace as debug from django
  • 如何在选项卡页面之前添加内容页面或视图

    我想在之前添加页面 视图TabbedPage 我怎样才能做到这一点
  • jQuery 随机块引用

    在过去的两个小时里 我一直在寻找和测试这个问题的各种解决方案 但收效甚微 所以我只能寻求帮助 我想建立一个引用数组 每个引用都有引用和一个链接 可以随机提取 除了在页面刷新时更改它们之外 我不需要任何其他东西 不过 我有一些非常美味的 CS
  • 在数据库中存储枚举值的最佳方法 - String 或 Int

    我的应用程序中有许多枚举 在某些类中用作属性类型 将这些值存储在数据库中的最佳方式是什么 作为字符串还是整数 仅供参考 我还将使用 Fluent Nhibernate 映射这些属性类型 示例代码 public enum ReportOutp
  • dplyr::n() 返回“错误:不应直接调用此函数”

    If I do dplyr mutate MeanValue mean RSSI ReadCount n 一切正常 但是当我尝试限定该函数时 dplyr mutate MeanValue mean RSSI ReadCount dplyr
  • AttributeError:类型对象没有属性

    这是一个有效的多级继承程序 当我运行它时 它显示 AttributeError 类型对象 starts 没有属性 maths 我检查了类的关联 它们继承了 我是一个初学者 所以这对我的进步确实有帮助 class starts def ini
  • 时间图chart.js

    我正在学习如何使用chart js我想要一个图表 以格式 h h mm 显示一天中不同时间 x 轴 的随机值 在 x 轴上 我想要一小时的固定步长 从上午 12 点 0 00 开始 到上午 8 点 8 00 结束 以及数据 例如 x 4 4
  • 必须使用活动访问令牌来查询有关当前用户的信息

    我已经定义了一个访问令牌 它是通过curl 获得的新访问令牌 为什么我仍然收到错误 必须使用活动访问令牌来查询有关当前用户的信息
  • 数据库关联实体和索引

    这是一种一般的数据库设计问题 如果有一个关联实体表 即交叉引用 包含基本上仅由两个 FK 引用组成的记录 是否应该以某种方式对其进行索引 由于关联表中的 PK 已按定义建立索引 是否有必要显式索引该表 如果应该索引它 它应该是一个组合索引
  • 如何将System.IO.Stream转换为图像?

    我怎样才能转换Stream图像 我使用Album GetArt方法从MediaLibrary 转化为可用的Image在我的应用程序中 Easy var img Bitmap FromStream stream
  • 如何在没有科学记数法或尾随零的情况下将浮点数输出到cout?

    在 C 中输出没有科学记数法或尾随零的浮点数的最优雅的方法是什么 float a 0 000001f float b 0 1f cout lt lt a lt lt a lt lt endl 1e 006 terrible don t wa
  • Android 地图标记的非 ASCII 标题

    我希望能够添加一个标题仅包含非 ASCII 字符的标记 marker map addMarker new MarkerOptions title position latlng 不幸的是 该图块没有显示 只有一个空的信息窗口 首先 我认为希
  • 模块化 Rails 应用程序

    我正在寻找一种模块化 Rails 应用程序的方法 正如我所见 没有内置的方法可以实现它 我发现了不同的插件 核心黑客 但我对它们的工作方式和成熟度感到不信任 您有这方面的经验吗 到目前为止我发现了这些 Desert http github
  • 实体框架 - Azure 表存储提供程序 - 枚举支持

    我实际上正在使用 EF 的 Azure 存储表提供程序 EntityFramework AzureTableStorage 7 0 0 beta1 https www nuget org packages EntityFramework A
  • jQuery HTML5 范围滑块中的实时输出

    我正在尝试将 HTML5 输入范围滑块的实时输出获取到 JavaScript 变量中 现在 我正在使用
  • 如何在C++中实现猴子补丁?

    是否可以在 C 中实现猴子修补 或者还有其他类似的方法吗 Thanks 不可移植 而且由于大型项目存在危险 您最好有充分的理由 预处理器可能是最好的候选者 因为它对语言本身一无所知 它可用于重命名属性 方法和其他符号名称 但至少对于单个 i
  • 违反 - 未找到父键 02291.00000 - “完整性约束

    您好 我正在 Oracle SQL 开发中开发一个数据库 该数据库正在尝试从另一个表访问外键 我目前正在处理使用以下 CREATE 语句创建的 ItemOrdered 表 CREATE TABLE ItemOrdered OrderID v
  • PhpStorm - 打印类文件中的方法和变量

    我有大约 10 个类 全部都在单独的文件中 我已经很久没有看过它们了 是否有 PhpStorm 函数允许我列出各个文件中列出的方法和属性 编辑 解决方案是突出显示您感兴趣的所有类 然后使用图表工具 请参阅下面我的回答 您可以使用 PHPSt
  • SOAP 调用在 SoapUI 中有效,但在 PHP 中使用soapclient 失败 - 对象引用问题

    尝试使用 PHP 5 x 查询托管在 IIS 服务器上的 NET Web 服务 wsdl path http 192 168 1 1 TestSite TestService asmx wsdl soapClient new SoapCli