Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHPSOAPServer中从SOAP请求的XML内容捕获数据?_Php_Xml_Soap_Stdclass - Fatal编程技术网

如何在PHPSOAPServer中从SOAP请求的XML内容捕获数据?

如何在PHPSOAPServer中从SOAP请求的XML内容捕获数据?,php,xml,soap,stdclass,Php,Xml,Soap,Stdclass,我正在尝试用php设置SOAP服务。 我声明了一个服务器php函数,并且可以通过SOAP类型的http请求调用该函数,其中内容是我的SOAP信封 SOAP主体的XML内容是我假设的函数的参数,但我不知道如何在php代码中访问其中的信息 我注意到函数参数在默认情况下是stdClass的一个实例,我实际上想知道为什么php不将它强制转换到XML或DOM对象上-这是一个SOAP调用,不是吗? 但是好吧,现在由我来从对象中获取信息,这并不容易,因为没有为stdClass分配方法,所以它必须是标准的php

我正在尝试用php设置SOAP服务。 我声明了一个服务器php函数,并且可以通过SOAP类型的http请求调用该函数,其中内容是我的SOAP信封

SOAP主体的XML内容是我假设的函数的参数,但我不知道如何在php代码中访问其中的信息

我注意到函数参数在默认情况下是
stdClass
的一个实例,我实际上想知道为什么php不将它强制转换到
XML
DOM
对象上-这是一个SOAP调用,不是吗? 但是好吧,现在由我来从对象中获取信息,这并不容易,因为没有为
stdClass
分配方法,所以它必须是标准的php函数。 所以我尝试了
序列化
,但这给了我一些垃圾,而不是我所期望的XML字符串

怎么办

编辑

注意,下面没有我想要做的示例代码——从SOAP请求的XML内容中获取一些详细数据——因为我不知道如何从stdClass对象获取这些数据

应大卫的要求,这里有一些细节

php代码:

<?php
    function mi102($arg) {
        $txt = serialize ($arg);
        $result = new SoapVar ($txt, XSD_ANYXML);
        return($result);
    }
    ini_set( "soap.wsdl_cache_enabled", "0");
    $server = new SoapServer ("test.wsdl");
    $server -> addFunction ("mi102");
    try {
        $server -> handle();
    }
    catch (Exception $e) {
        $server -> fault ('Client', $e -> getMessage());
    }
?php>
addFunction(“mi102”);
试一试{
$server->handle();
}
捕获(例外$e){
$server->fault('Client',$e->getMessage());
}
?php>
http请求由我使用的应用程序构造;http头和soap信封+正文是围绕我提供给它的XML生成的:

SOAP请求正文内容:

<mi102 xmlns="http://pse">
  <cdhead cisprik="21"/>
  <instr>
    <insid>
      <bcdt>20120930</bcdt>
    </insid>
  </instr>
</mi102>

20120930
使用的WSDL如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://pse/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="PSE" targetNamespace="http://pse/">
    <types>
        <xs:schema>
            <xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/>
        </xs:schema>
    </types>
    <message name="MI102Req">
        <part name="cdhead" type="tns:cdhead_T"/>
        <part name="instr" type="tns:instr_T"/>
    </message>
    <message name="Res">
        <part name="cdhead" type="tns:cdhead_T"/>
    </message>
    <portType name="MIPortType">
        <operation name="mi102">
            <input message="tns:MI102Req"/>
            <output message="tns:Res"/>
        </operation>
    </portType>
    <binding name="MIBinding" type="tns:MIPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="mi102">
            <soap:operation soapAction="http://testServerURL/test_soap.php#mi102"/>
            <input>
                <soap:body use="literal" namespace="http://pse/"/>
            </input>
            <output>
                <soap:body use="literal" namespace="http://pse/"/>
            </output>
        </operation>
    </binding>
    <service name="PSE">
        <port name="MIPortType" binding="tns:MIBinding">
            <soap:address location="http://testServerURL/test_soap.php"/>
        </port>
    </service>
</definitions>

生成的XML(同样,由我使用的应用程序从SOAP主体中提取)是

SOAP响应:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mi102Response xmlns:ns1="http://pse/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">O:8:"stdClass":2:{s:7:"cisprik";i:21;s:7:"version";s:2:"13";}</ns1:mi102Response>

O:8:“标准类”:2:{s:7:“西斯普里克”;i:21;s:7:“版本”;s:2:“13”}

不太好。

这不是一个完整的答案,但我想要格式。请详细说明你的设置。通常,您将有一个带有常规参数(而不是XML)的PHP方法,希望将其公开为web服务。下面是一个基本的示例:

SOAP主体的XML内容是我假定的函数的参数

不,SOAP主体的XML内容是带有参数的方法的表示,但是参数是您想要的任何内容。如果使用PHP的SoapServer和SoapClient进行设置,则不必手动处理XML

编辑:您正在接受您的参数,它是SOAP请求主体的一个简单PHP数组表示,序列化它并将其作为响应发送回去(这是您观察到的)。这就是你想做的吗?您不想对请求数据做些什么吗?另外,您可以发布从WSDL导入的模式吗?

您拥有一个对象的“不好”表示,因为您将返回序列化的对象(序列化是将对象及其状态转换为字符串表示)。如果希望返回对象具有xml表示形式,则应将函数的返回参数类型更改为对象。因为现在正在返回一个字符串

我建议您使用Zend_Soap_服务器和Zend_Soap_自动发现组件

使用Zend_Soap_Autodiscover,您可以动态生成web服务定义(wsdl),只需编写函数的docblock。Zend_Soap_服务器也很酷

如果您使用这些组件并记录您的类型和函数以返回特定类型而不序列化它,那么您将根据wsdl定义接收xml表示。 此外,Zend_Soap_Autodiscover会自动将您创建的每个类型转换为生成的wsdl中的ComplexType

样本:

 public class Person{
         public $id;
         public $name;
    }

    public class MyService {
     /**
     *
     * @param integer $UserID
     * @return Person
     */
    function mi102($UserID) {

         $output = new Person();
         $output->id = 2;
         $output->name = 'Peter';        

        return $output;
    }
}


// Generate WSDL relevant to code
if (isset($_GET['wsdl'])){

    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('MyService');
    $autodiscover->handle();

} else {

    $server = new Zend_Soap_Server($serviceURL . "?wsdl");
    $server->setClass('MyService');
    $server->setObject(new MyService());
    $server->handle();

}

我最终在其他帖子中找到了答案,比如

解决方案是使用以下各项:

$inp = file_get_contents ('php://input');
注意:我找不到任何可以作用于
stdClass
输入参数并从中检索XML SOAP正文内容的函数。
因此,最好的选择是使用标准php输入变量。请注意,它具有以下结构:
Envelope/Body/.inputXML..
,这是发布到服务器的确切http请求内容


注意:
http\u get\u request\u body
也可以工作,但我的php服务器不支持此功能。我认为从某个版本开始,每个php服务器都支持
file\u get\u contents

好的,我会试试。是的,我应该使用其他序列化的东西。但我不能理解的是,php将SOAP调用参数(无论是信封、正文还是正文内容,都从http请求内容中去掉)在stdClass中,没有可用于将其转换为DOM或其他东西的函数-肯定还有另一个函数可以做到这一点?根据我的经验,php总是将xml正文中的响应对象转换为stdobject,我认为这是为了使easir能够访问对象属性。当然,会有一个函数可以为您将其转换为DOM树。但是我认为访问生成的stbobject的属性非常容易。是的,我当然希望做其他事情,但为此我需要首先从请求中提取数据:-)xsd相当大,只包含cdhead、instr等格式。我认为你的答案不需要它,但如果你需要,请向我说明原因,我可以提取相关信息。