php SoapClient LibXMLError:无法加载外部实体,SOAP-ERROR:解析 WSDL:无法加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10318526/
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-24 21:54:31  来源:igfitidea点击:

SoapClient LibXMLError: failed to load external entity, SOAP-ERROR: Parsing WSDL: Couldn't load

phpxmlweb-servicessoapwsdl

提问by David

I am trying to establish a SOAP connection using the following PHP code, and it's failing at the point of the SoapClient construct:

我正在尝试使用以下 PHP 代码建立 SOAP 连接,但它在 SoapClient 构造点失败:

// Need to declare these settings here because our php.ini has alternate
// settings due to global purposes for other PHP scripts
ini_set("soap.wsdl_cache_enabled", "0");
ini_set("soap.wsdl_cache", "0");
ini_set("display_errors","On");
ini_set("track_errors","On");

// FedEx web services URL, note the HTTPS
$path_to_wsdl = 'https://wsbeta.fedex.com/web-services';

$soap_args = array(
    'exceptions'=>true,
    'cache_wsdl'=>WSDL_CACHE_NONE,
    'trace'=>1)
;

try {
    $client = new SoapClient($path_to_wsdl,$soap_args);
} catch (SoapFault $e) {
    var_dump(libxml_get_last_error());
    echo "<BR><BR>";
    var_dump($e);
}

This outputs:

这输出:

object(LibXMLError)#1 (6) {
    ["level"]=> int(1)
    ["code"]=> int(1549)
    ["column"]=> int(0)
    ["message"]=> string(71) "failed to load external entity "https://wsbeta.fedex.com/web-services" "
    ["file"]=> string(0) ""
    ["line"]=> int(0)
}

object(SoapFault)#2 (9) {
    ["message":protected]=> string(158) "SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://wsbeta.fedex.com/web-services' : failed to load external entity "https://wsbeta.fedex.com/web-services" "
    ["string":"Exception":private]=> string(0) ""
    ["code":protected]=> int(0)
    ["file":protected]=> string(53) "/mnt/array/bell-enterprise/bell/fedex_shipservice.php"
    ["line":protected]=> int(34)
    ["trace":"Exception":private]=> array(1) {
        [0]=> array(6) {
            ["file"]=> string(53) "/mnt/array/bell-enterprise/bell/fedex_shipservice.php"
            ["line"]=> int(34)
            ["function"]=> string(10) "SoapClient"
            ["class"]=> string(10) "SoapClient"
            ["type"]=> string(2) "->"
            ["args"]=> array(2) {
                [0]=> string(37) "https://wsbeta.fedex.com/web-services"
                [1]=> array(4) {
                    ["exceptions"]=> bool(true)
                    ["soap_version"]=> int(1)
                    ["cache_wsdl"]=> int(0)
                    ["trace"]=> int(1)
                }
            }
        }
    }
    ["previous":"Exception":private]=> NULL
    ["faultstring"]=> string(158) "SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://wsbeta.fedex.com/web-services' : failed to load external entity "https://wsbeta.fedex.com/web-services" "
    ["faultcode"]=> string(4) "WSDL"
}

回答by Justin Valceanu

After 6 hours of headache, the ONLY solution is to download the WSDL files.

经过 6 个小时的头痛,唯一的解决方案是下载 WSDL 文件。

https://wsbeta.fedex.com/web-servicesand https://ws.fedex.com/web-services

https://wsbeta.fedex.com/web-serviceshttps://ws.fedex.com/web-services

It will always throw an error 500, because this is not the wsdl.

它总是会抛出错误 500,因为这不是 wsdl。

Once you download the wsdls from Technical Resources -> FedEx WebServices For Shipping -> GetStarted(click on "Rate Services" and then "Download WSDL or XML"), in your script you will need to load your locally stored WSDL and everything will work like a charm.

技术资源 -> FedEx WebServices For Shipping -> GetStarted(点击“Rate Services”,然后点击“Download WSDL or XML”)下载wsdls 后,您将需要在脚本中加载本地存储的 WSDL 并且一切正常就像一个魅力。

$this->_soapClient = new SoapClient("RateService_v13.wsdl", array('exceptions'=>true, 'trace' => true));

Have fun!

玩得开心!

回答by Wrikken

That url is NOT the path to a WSDL , but the url the SOAP requests should be going to. Never worked with the guys, but I gather you can get a wsdl file somewhereand store it locally, and you can alter the endpoint in that wsdl to the wsbeta one. I cannot find the wsdl's and the fedex site doesn't allow me to go further in their dev technical resources without signing up, so I'll leave it at that: you wsdlis somewhere else, the url you have is just the location of a particular service.

该 url 不是 WSDL 的路径,而是 SOAP 请求应该到达的 url。从来没有和这些人一起工作过,但我认为你可以在某处得到一个 wsdl 文件并将其存储在本地,你可以将该 wsdl 中的端点更改为 wsbeta 端点。我找不到 wsdl 并且联邦快递网站不允许我在没有注册的情况下进一步了解他们的开发技术资源,所以我将保留它:你wsdl在其他地方,你拥有的 url 只是他们的位置一项特定的服务。

回答by alganet

You'll need a local certificate file to access a WSDL on HTTPS:

您需要一个本地证书文件来访问 HTTPS 上的 WSDL:

$client = new SoapClient($wsdl, array('local_cert' => $pathToLocalCert));

Append this option to your current $soap_argsand this code should work as expected. A passphraseoption is also available if you need it for the certificate.

将此选项附加到您的当前选项$soap_args,此代码应按预期工作。passphrase如果您需要证书,也可以使用一个选项。