Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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
SOAP PHP错误解析WSDL:无法加载外部实体?_Php_Xml_Soap_Wsdl_Wamp - Fatal编程技术网

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

SOAP PHP错误解析WSDL:无法加载外部实体?,php,xml,soap,wsdl,wamp,Php,Xml,Soap,Wsdl,Wamp,我正在尝试使用PHP和SOAP运行web服务,但到目前为止,我所了解的是: (SoapFault)[2]消息,该消息声明:“SOAP-ERROR:解析WSDL:无法从“”加载:加载外部实体失败” 我已经尝试将localhost更改为127.0.0.1,但这没有什么区别。login实际上是一个wsdl文件,但如果我将login.wsdl放在SOAPClient构造函数中,它会说“看起来我们没有XML文档” 下面是我的SOAP客户端代码(register_Client.php): 下面是logi

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

(SoapFault)[2]消息,该消息声明:“SOAP-ERROR:解析WSDL:无法从“”加载:加载外部实体失败”

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

下面是我的SOAP客户端代码(register_Client.php):


下面是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>

我不确定这是否涉及其中,因此我提供了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();
?>

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

$sClient = new SoapClient('http://127.0.0.1/MyRegistration/login.wsdl');    
如果127.0.0.0不起作用,您可以尝试使用一些网络IP地址并查看

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


我很想知道它是否能为您解决问题。

我也有同样的问题

此php设置解决了我的问题:

allow_url_fopen -> 1

迁移到PHP5.6.5后,SOAP1.2不再工作。因此,我通过添加可选的SSL参数解决了这个问题

我的错误:

无法加载外部实体

如何解决:

// 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);

将此代码置于任何Soap调用之上:

libxml_disable_entity_loader(false);

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

试试这个。为我工作

$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);

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

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

服务器从PHP 5.5.9-1ubuntu4.21更新后>>PHP 5.5.9-1ubuntu4.23我的客户端机器osx 10.12.6/PHP 5.6.30出现问题,但MS Web Services客户端连接可以正常进行

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

只有
libxml\u get\u last\u error()
提供了一些细节>
SSL操作失败,代码为1。OpenSSL错误消息:
错误:14090086:SSL例程:SSL3\u获取\u服务器\u证书:证书验证失败

因此,我在通话中添加了一些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);
}

在我的例子中,
'allow\u self\u signed'=>true
成功了

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

我正在使用参数:

new \SoapClient($WSDL, array('cache_wsdl' => WSDL_CACHE_NONE, 'trace' => true, "exception" => 0)); 
删除所有参数对我来说很有效:

new \SoapClient($WSDL); 

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

转到php.ini文件末尾删除
extension=openssl
所在的行中


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

我正在使用selinux,通过以下shell命令(作为root),我能够允许PHP进行SOAP调用:

sudo setsebool -P httpd_can_network_connect on

我也遇到了同样的问题,我成功地添加了:

new \SoapClient(URI WSDL OR NULL if non-WSDL mode, [
    'cache_wsdl' => WSDL_CACHE_NONE, 
    'proxy_host' => 'URL PROXY',
    'proxy_port' => 'PORT PROXY'
]);

希望获得以下帮助:)

如果使用docker,由于OpenSSL默认安全级别的原因,可能会出现错误

您需要在
/etc/ssl/openssl.cnf
中使用较低的seclevelDEFAULT@SECLEVEL=2到
DEFAULT@SECLEVEL=1

或者直接添加到Dockerfile中

RUN sed -i "s|DEFAULT@SECLEVEL=2|DEFAULT@SECLEVEL=1|g" /etc/ssl/openssl.cnf
资料来源:

在这一更改之后,我可以运行SoapClient,而无需任何其他选项


您可以通过在容器上运行来验证它

curl-A'curl用户代理'-4https://ewus.nfz.gov.pl/ws-broker-server-ewus/services/Auth?wsdl

为了补充答案,这是由5.6.x中openssl的更改引起的,而不是禁用SSL对等验证,您应该尝试修复导致验证失败的任何问题。例如,通过显式设置cafile的路径,该文件包含需要验证的根证书。答案直指问题的核心,有时这可能是唯一可用的解决方案,因此+1.比如将“openssl.cafile=C:/path/to/sslCertificates/cacert.pem”添加到php.ini:-)(比如curl.cainfo!)找不到捆绑包java.util.PropertyResourceBundle的资源,密钥SOAP 1.2消息在发送到仅限SOAP 1.1的端点时无效。为什么这样认为?代码似乎根本没有使用SSL。如果您看到可以从命令行加载wsdl,但php无法加载,那么这就是您的答案。我花了一整天的时间试图解决这个问题。我尝试了您的
sed
建议,它在命令行中工作,但在我的PHP SoapClient配置中没有解决问题。我不得不在SSL
stream\u上下文中添加
'security\u level'=>1
设置,以便在PHP中执行相同的操作。我只是想加上这句话,以防其他人也被同样的方式困住。
new \SoapClient(URI WSDL OR NULL if non-WSDL mode, [
    'cache_wsdl' => WSDL_CACHE_NONE, 
    'proxy_host' => 'URL PROXY',
    'proxy_port' => 'PORT PROXY'
]);
RUN sed -i "s|DEFAULT@SECLEVEL=2|DEFAULT@SECLEVEL=1|g" /etc/ssl/openssl.cnf