SOAP PHP 错误解析 WSDL:无法加载外部实体?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12875409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:24:15  来源:igfitidea点击:

SOAP PHP fault parsing WSDL: failed to load external entity?

phpxmlsoapwsdlwamp

提问by user1743679

I'm trying to run a web service using PHP & SOAP, but all I'm getting so far is this:

我正在尝试使用 PHP 和 SOAP 运行 Web 服务,但到目前为止我所得到的是:

(SoapFault)[2] message which states: 'SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/MyRegistration/login.xml' : failed to load external entity "http://localhost/MyRegistration/login.xml"

(SoapFault)[2] 消息指出:“SOAP-ERROR:解析 WSDL:无法从‘ http://localhost/MyRegistration/login.xml’加载:无法加载外部实体” http://localhost/MyRegistration /登录.xml

I've tried changing localhost to 127.0.0.1, but that makes no difference. login is actually a wsdl file, but if I put login.wsdl in the SOAPClient constructor, it says "'looks like we got no XML document'" instead.

我尝试将 localhost 更改为 127.0.0.1,但这没有区别。login 实际上是一个 wsdl 文件,但如果我将 login.wsdl 放在 SOAPClient 构造函数中,它会改为显示“'看起来我们没有 XML 文档'”。

Here is my code for the SOAP Client (register_client.php):

这是我的 SOAP 客户端代码 (register_client.php):

<?php
try
{
    $sClient = new SoapClient('http://127.0.0.1/MyRegistration/login.wsdl');    

    $param1 = $_POST["regname"];
    $param2 = $_POST["regpass1"];

    $response = $sClient->loginVerify($param1, $param2);    

    var_dump($response);
}
catch(SoapFault $e)
{
    var_dump($e);
}
?> 

And here is the login.wsdl file:

这是 login.wsdl 文件:

<?xml version="1.0"?>
<definitions name="LoginVal" 
    targetNamespace="urn:LoginVal" 
    xmlns:tns="urn:LoginVal"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns="http://schemas.xmlsoap.org/wsdl/">
  <types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Login">
  <xsd:element name="getName" type="xsd:string" />
<xsd:element name="getPass" type="xsd:string" />
  <xsd:element name="LoginResponse" type="xsd:string" />          
</xsd:schema>           
  </types>

  <message name="loginVerify">
<part name="username" type="tns:getName" />
<part name="password" type="tns:getPass" />
  </message>

  <message name="doLoginResponse">
<part name="return" type="tns:LoginResponse" />
  </message>  

  <portType name="LoginPort">
    <operation name="loginVerify">
  <input message="tns:loginVerify" />
  <output message="tns:doLoginResponse" />
    </operation>
  </portType>

  <binding name="LoginBinding" type="tns:LoginPort">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
  <operation name="loginVerify">
    <soap:operation soapAction="urn:LoginAction" />
    <input>
      <soap:body use="encoded" namespace="urn:Login" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />         
    </input>
    <output>
      <soap:body use="encoded" namespace="urn:Login" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />         
    </output>
  </operation>
  </binding>

  <service name="LoginService">
    <port name="LoginPort" binding="tns:LoginBinding">
  <soap:address location="http://localhost/MyRegistration/register.php" />
    </port>
  </service>

</definitions>

And I'm not sure if this is involved, so I'm providing the code for the SOAP Server register.php:

我不确定这是否涉及,所以我提供了 SOAP 服务器 register.php 的代码:

<?php
if(!extension_loaded("soap"))
{
    dl("php_soap.dll");
}

ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer("login.wsdl", array('uri'=>'http://127.0.0.1/MyRegistration'))

public function loginVerify($username, $password)
{
    if($_POST["regname"] && $_POST["regemail"] && $_POST["regpass1"] && $_POST["regpass2"] )
    {
        if($_POST["regpass1"] == $_POST["regpass2"])
        {
            $servername = "localhost";
            $username = "root";
            $password = "Hellfire";

            $conn = mysql_connect($servername,$username,"Hellfire")or die(mysql_error());

            mysql_select_db("soap",$conn);

            $sql = "insert into users (name,email,password)values('$_POST[regname]','$_POST[regemail]','$_POST[regpass1]')";

            $result = mysql_query($sql,$conn) or die(mysql_error());

            return "You have registered sucessfully";

            //print "<a href='index.php'>go to login page</a>";
        }
        else return "passwords dont match";
    }
    else return "invalid data";
}

$server->AddFunction("loginVerify");
$server->handle();
?>

I'm sorry if I'm giving unnecessary information, but I'm a complete novice at this - and I'd really appreciate it if someone could point out why exactly this SOAP Fault is being generated, and what I can do to rectify it.

如果我提供了不必要的信息,我很抱歉,但我在这方面完全是新手 - 如果有人能指出为什么会产生这个 SOAP 错误,以及我能做些什么来纠正,我真的很感激它。

I am using WAMP Server version 2.2, with mySQL 5.5.24 and PHP 5.3.13

我正在使用 WAMP 服务器版本 2.2,以及 mySQL 5.5.24 和 PHP 5.3.13

回答by R?mulo Z. C. Cunha

After migrating to PHP 5.6.5, the soap 1.2 did not work anymore. So I solved the problem by adding optional SSL parameters.

迁移到 PHP 5.6.5 后,soap 1.2 不再起作用。所以我通过添加可选的 SSL 参数解决了这个问题。

My error:

我的错误:

failed to load external entity

无法加载外部实体

How to solve:

怎么解决:

// options for ssl in php 5.6.5
$opts = array(
    'ssl' => array(
        'ciphers' => 'RC4-SHA',
        'verify_peer' => false,
        'verify_peer_name' => false
    )
);

// SOAP 1.2 client
$params = array(
    'encoding' => 'UTF-8',
    'verifypeer' => false,
    'verifyhost' => false,
    'soap_version' => SOAP_1_2,
    'trace' => 1,
    'exceptions' => 1,
    'connection_timeout' => 180,
    'stream_context' => stream_context_create($opts)
);

$wsdlUrl = $url . '?WSDL';
$oSoapClient = new SoapClient($wsdlUrl, $params);

回答by Thanh Nguyen

Put this code above any Soap call:

将此代码放在任何 Soap 调用之上:

libxml_disable_entity_loader(false);

回答by gogagubi

try this. works for me

尝试这个。为我工作

$options = array(
    'cache_wsdl' => 0,
    'trace' => 1,
    'stream_context' => stream_context_create(array(
          'ssl' => array(
               'verify_peer' => false,
                'verify_peer_name' => false,
                'allow_self_signed' => true
          )
    ))

$client = new SoapClient(url, $options);

回答by deej

On register_client.php make sure that the URL that has been passed to SoapClient is accessible from the machine you're executing the code.

在 register_client.php 上,确保您正在执行代码的机器可以访问传递给 SoapClient 的 URL。

$sClient = new SoapClient('http://127.0.0.1/MyRegistration/login.wsdl');    

If 127.0.0.0 does not work you can try using some network IP address and see.

如果 127.0.0.0 不起作用,您可以尝试使用一些网络 IP 地址并查看。

Let me know if it still does not fix it for you, I did try with your example and changing path (making it proper in my dev. environment) has fixed same error for me.

如果它仍然不能为您修复它,请告诉我,我确实尝试过使用您的示例并更改路径(使其在我的开发环境中正确)为我修复了相同的错误。

I would be interested to know if it does not fix it for you.

我很想知道它是否不能为您修复。

回答by hazard16

I had the same problem.

我有同样的问题。

This php setting solved my problem:

这个php设置解决了我的问题:

allow_url_fopen -> 1

回答by Samo

I am using selinux and with the following shell command (as root) I was able to allow PHP to make SOAP calls:

我正在使用 selinux 并使用以下 shell 命令(以 root 身份)我能够允许 PHP 进行 SOAP 调用:

sudo setsebool -P httpd_can_network_connect on

回答by c3labs

Got a similar response with https WSDL URL using php soapClient

使用 php soapClient 得到了与 https WSDL URL 类似的响应

SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from ...

SoapFault 异常:[WSDL] SOAP-ERROR:解析 WSDL:无法从...加载

After server has been updated from PHP 5.5.9-1ubuntu4.21 >> PHP 5.5.9-1ubuntu4.23 something went wrong for my client machine osx 10.12.6 / PHP 5.6.30, but MS Web Services Clients connections could be made without issues.

服务器从 PHP 5.5.9-1ubuntu4.21 >> PHP 5.5.9-1ubuntu4.23 更新后,我的客户端机器 osx 10.12.6 / PHP 5.6.30 出现问题,但可以建立 MS Web 服务客户端连接没有问题。

Apache2's server_access.log showed no entry when i tried to load WSDL so i added 'cache_wsdl' => WSDL_CACHE_NONEto prevent client-side wsdl caching, but still got no entries. Finally i tried to load wsdl per CURL -ichecked HEADERS but all seemed to be ok..

当我尝试加载 WSDL 时,Apache2 的 server_access.log 没有显示任何条目,因此我添加了'cache_wsdl' => WSDL_CACHE_NONE以防止客户端 wsdl 缓存,但仍然没有条目。最后,我尝试为每个CURL -i检查过的 HEADERS加载 wsdl,但似乎一切正常..

Only libxml_get_last_error()provided some insight > SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

libxml_get_last_error()提供了一些见解>SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

So I added some ssl options to my call:

所以我在通话中添加了一些 ssl 选项:

$contextOptions = array(
    'ssl' => array(
    'verify_peer' => false,
    'verify_peer_name' => false,
    'allow_self_signed' => true
    ));

$sslContext = stream_context_create($contextOptions);

$params =  array(
    'trace' => 1,
    'exceptions' => true,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'stream_context' => $sslContext
    );

try {
    $proxy = new SoapClient( $wsdl_url, $params );
} catch (SoapFault $proxy) {
    var_dump(libxml_get_last_error());
    var_dump($proxy);
}

In my case 'allow_self_signed' => truedid the trick!

在我的情况下'allow_self_signed' => true成功了!

回答by read

Just had a similar problem trying to use SoapClient. Everything was working fine but in production, sometimes on page refresh, I would get the "SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from .." error.

刚刚在尝试使用 SoapClient 时遇到了类似的问题。一切正常,但在生产中,有时在页面刷新时,我会收到“SoapFault 异常:[WSDL] SOAP-ERROR:解析 WSDL:无法从 .. 加载”错误。

I was using the params:

我正在使用参数:

new \SoapClient($WSDL, array('cache_wsdl' => WSDL_CACHE_NONE, 'trace' => true, "exception" => 0)); 

Removing all the params worked for me:

删除所有参数对我有用:

new \SoapClient($WSDL); 

回答by Dawid D

The problem may lie in you don't have enabled openssl extention in your php.ini file

问题可能在于您没有在 php.ini 文件中启用 openssl 扩展

go to your php.ini file end remove ;in line where extension=opensslis

转到您的 php.ini 文件末尾删除;行中的extension=openssl位置

Of course in question code there is a part of code responsible for checking whether extension is loaded or not but maybe some uncautious forget about it

当然,有问题的代码有一部分代码负责检查扩展是否已加载,但也许有些不小心忘记了它

回答by Shmarkus

If anyone has the same problem, one possible solution is to set the bindtostream context configuration parameter (assuming you're connecting from 11.22.33.44 to 55.66.77.88):

如果有人bindto遇到同样的问题,一种可能的解决方案是设置流上下文配置参数(假设您从 11.22.33.44 连接到 55.66.77.88):

$context = [
    'socket' => [
        'bindto' => '55.66.77.88'
    ]
];

$options = [
    'soapVersion' => SOAP_1_1,
    'stream_context' => stream_context_create($context)
];

$client = new Client('11.22.33.44', $options);