2016-11-18 34 views
1

是否可以使用字符串的内容来调用PHP SoapClient构造函数,该构造函数将URL作为参数来调用。使用WSDL从变量而不是URL调用SoapClient构造函数

在我的示例中,我有一个包含WSDL的操作DOMDocument,我将其写入带有saveXML()的字符串中。

这个想法是如果可能的话不要触摸文件系统。我尝试过php://内存,但是用像file_get_contents这样的函数检索流内容会导致空字符串测试,因为我怀疑流上下文已经消失。有另一种方法吗?

回答

1

是的,可以通过一个包含WSDL字符串的变量实例化SoapClient类,所有都未触及文件系统。由于SoapClient需要一个URI参数,我们将创建一个Data URI,并传递它:

$wsdlstring = <<<WSDL 
<?xml version="1.0" encoding="utf-8"?> 
<definitions name="SoapArrayTest" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
        xmlns:tns="http://test-uri/" 
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
        xmlns="http://schemas.xmlsoap.org/wsdl/" 
        targetNamespace="http://test-uri/" 
    > 
    <types> 
    <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test-uri/"> 
     <complexType name="Baz"> 
     <sequence> 
      <element name="fruit" type="tns:StringArray"/> 
      <element name="vegetables" type="tns:StringArray"/> 
     </sequence> 
     </complexType> 
     <element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="BazElement" type="tns:Baz"/> 
     <complexType name="StringArray"> 
     <sequence> 
      <element name="item" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/> 
     </sequence> 
     </complexType> 
     <element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="StringArrayElement" type="tns:StringArray"/> 
    </schema> 
    </types> 
    <message name="fooRequest"> 
    </message> 
    <message name="fooResponse"> 
    <part name="result" type="tns:Baz"/> 
    </message> 
    <portType name="TestPortType"> 
    <operation name="foo"> 
     <input message="tns:fooRequest"/> 
     <output message="tns:fooResponse"/> 
    </operation> 
    </portType> 
    <binding name="TestBinding" type="tns:TestPortType"> 
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> 
    <operation name="foo"> 
     <soap:operation soapAction="#foo" style="rpc"/> 
     <input /> 
     <output > 
     <soap:body parts="result" use="literal" namespace="http://test-uri/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> 
     </output> 
    </operation> 
    </binding> 
    <service name="TestService"> 
    <port name="TestPort" binding="tns:TestBinding"> 
     <soap:address location="http://example.com"/> 
    </port> 
    </service> 
</definitions> 
WSDL; 

$doc = new DOMDocument(); 
$doc->loadXML($wsdlstring); 
$data = $doc->saveXML(); 
$wsdl = 'data://text/plain;base64,'.base64_encode($data); 
$soapclient = new SoapClient($wsdl); 
var_dump($soapclient->__getFunctions()); 
+0

这似乎只是使创建SoapClient的实例时出现错误:“未能打开流:rfc2397:在URL没有逗号” – Russ

+0

我已经扩展了提供工作示例的答案,但是从技术上讲,WSDL现在驻留在PHP文件本身内的文件系统中。但是,如果WSDL只是用'DOMDocument'方法调用构建的,它将完全驻留在内存中。当我抽出一点空闲时间时,我会更新答案,以便使用'DOMDocument'实时构建WSDL。 –

+0

我认为这里的关键是,SoapClient可以将URL作为参数,但可以在问题中传递字符串的内容,因为PHP将它视为流上下文。所以我们可以用'data://'而不是'file://'或'http://'替代 –

相关问题