【问题标题】:How to create php soap wsdl client with wsHTTPBinding?如何使用 wsHTTPBinding 创建 php soap wsdl 客户端?
【发布时间】:2016-08-16 08:29:02
【问题描述】:

我正在尝试从 wsdl 创建一个使用 WCF 服务的 php 客户端。 我已经设法通过仅传递凭据(不需要 pem 认证)来使用 C# 控制台应用程序使用 Web 服务。

wsdl的url如下(是测试环境):

https://extenavigator.ukho.gov.uk/serviceB2B/submitUKHOOrdering.svc?wsdl

所以如果有人想尝试创建一个肥皂客户端,请使用这个 wsdl。

“尝试使用缺少相关服务权限的帐户进行访问将导致响应带有 ProcessResult.Failure Acknowledgment 和添加到 Messages 属性的消息:服务 [serviceName] 对用户不可用 [ userId]"(来自提供者)。

因此,具有错误凭据的工作肥皂客户端应该返回上述消息。

为了在 php 中创建一个肥皂客户端,我首先通过 wsdl2phpgenerator 创建了存根类。然后我实例化soap客户端如下:

ini_set('max_execution_time', 480);
ini_set('default_socket_timeout', 400);

$orderServiceClient = new OrderingService(array('login' => DIST_B2B_USERNAME, 'password' => DIST_B2B_PASSWORD, "trace"=>1, 
"exceptions"=>1, 'cache_wsdl' => WSDL_CACHE_MEMORY, 'soap_version' => SOAP_1_2, 'keep_alive' => false, 
"connection_timeout" => 240, 'verifypeer' => false, 'verifyhost' => false, "ssl_method" => SOAP_SSL_METHOD_TLS));

其中 OrderingService 是扩展 SOAP 客户端类的存根类。

最后我调用了这样一个方法:

$getHoldingsRequest = new GetHoldingRequest(DIST_ID, 25555, ProductType::AVCSCharts); // set some params for the called method

$responce = $orderServiceClient->GetHoldings($getHoldingsRequest); // call the method

我得到的错误是:Error Fetching http headers

我在 php.ini 和 apache conf 文件中启用了 ssl。我使用的是 Windows PC。

我看过这篇文章:

Connecting to WS-Security protected Web Service with PHP

SoapFault exception: [HTTP] Error Fetching http headers

我发现问题在于必须自定义soap标头才能传递凭据(“通过SSL的用户名和密码身份验证”)

我也尝试过创建自定义肥皂标题:

 class WsseAuthHeader extends SoapHeader 
{
    private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
    function __construct($user, $pass, $ns = null) 
    {    
    if ($ns) 
    {        
        $this->wss_ns = $ns;    
    }    

    $auth = new stdClass();    

    $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);     
    $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);    
    $username_token = new stdClass();    
    $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);     
    $security_sv = new SoapVar(        
                            new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),        
                            SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);    

    parent::__construct($this->wss_ns, 'Security', $security_sv, true);
    }
}

 $wsse_header = new WsseAuthHeader("xxxx", "xxxx");

 $orderServiceClient = new OrderingService(array('trace' => true, 'exceptions' => true, 'cache_wsdl' => WSDL_CACHE_MEMORY, 
'soap_version' => SOAP_1_2, 'keep_alive' => false, 'connection_timeout' => 240));

 $orderServiceClient->__setSoapHeaders(array($wsse_header));

终于

$getHoldingsRequest = new GetHoldingRequest(DIST_ID, 25555, ProductType::AVCSCharts);
 $getHoldingsRequest->setRequestId($GUID);

try {
$responce = $orderServiceClient->GetHoldings($getHoldingsRequest);

} catch (Exception $e) {
echo $e->getMessage();
}


 echo "<pre>" . var_export($orderServiceClient->__getLastRequest(), TRUE) . "</pre>";

我明白了:

获取 http 标头时出错

我还尝试了上述帖子中提到的其他事情,但没有结果。

来自上述帖子:

“但正如我上面所说:我认为需要更多关于 WS-Security 规范和给定服务架构的知识才能使其正常工作。”

所以如果有人有使用soap客户端的经验并且能够为这个wsdl创建一个php客户端,那将是一个很大的帮助。

对于 GUID,我使用了以下函数:

  function getGUID(){
if (function_exists('com_create_guid')){
    return com_create_guid();
}else{
    mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
    $charid = strtoupper(md5(uniqid(rand(), true)));
    $hyphen = chr(45);// "-"
    $uuid = chr(123)// "{"
        .substr($charid, 0, 8).$hyphen
        .substr($charid, 8, 4).$hyphen
        .substr($charid,12, 4).$hyphen
        .substr($charid,16, 4).$hyphen
        .substr($charid,20,12)
        .chr(125);// "}"
    return $uuid;
   }
}

   $GUID = getGUID();

【问题讨论】:

    标签: php ssl wsdl soap-client wshttpbinding


    【解决方案1】:

    我是新人,不确定我的帖子是否有用,但我会尽力帮助您 - 如果您已经获得 WSDL 文件或 URL,那么

    -你可以使用 php SoapClient

    • 如果帖子不符合您的要求,请忽略

    尝试按照下面给出的示例以及您的 WSDL 文件结构(持有 函数和参数通过 XML)

    由你决定,可以将第 1 步和第 2 步代码放在类/函数中,也可以以简单的给定方式使用。

    步骤 1-

    试试 {

    $client = new SoapClient(SOAP_CLIENT_WSDL_URL, array('soap_version' => SOAP_VERSION, 'trace' => true)); 返回 $client;

    } 捕获(SoapFault $fault){

    trigger_error("SOAP 错误:(faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);

    死();

    }

    第 2 步-

    result = $client->your_wsdl_containing_function("follow_wsdl_parameter")

    $xml_last_response = $client->__getLastResponse();

    echo '';print_r($xml_last_response);

    【讨论】:

    • 您能否详细说明第 2 步?我必须将第 1 步和第 2 步结合起来吗?
    • 你可以把第一步的代码放在initialize_soap_client()里面,然后在第二步你可以看到它被调用了,然后对象soapclient就可以用来调用wsdl里面的函数了,最后你会收到你的最终响应/xml,然后将xml响应转换成数组
    • 现在已经更新了答案,没有initialize_soap_clie‌​nt(),你可以简单的使用它,也建议你在last_response之前查看你的request_response进行调试
    • 我编辑了这个问题。如果您(或其他人)想尝试使用上述服务。
    猜你喜欢
    • 2014-11-27
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    相关资源
    最近更新 更多