PHP Soap是地狱

时间:2009-11-18 01:01:23

标签: php soap

如果我运行

$HostTransactionInfo = new HostTransactionInfo();  // std Object
$HostTransactionInfo->SecurenetID = $cc->merchant->data[$this->name]['secure_net_id'];
$HostTransactionInfo->SecureKey = $cc->merchant->data[$this->name]['secure_key'];
$HostTransactionInfo->Test = self::TEST;

$securenet = new SoapClient(self::WSDL, array('features' => SOAP_SINGLE_ELEMENT_ARRAYS));
$host_trans_info = new SoapVar($HostTransactionInfo, SOAP_ENC_OBJECT);
var_dump($host_trans_info);

$save = $securenet->Process_Save($host_trans_info);

我在每个变体上都会收到:“服务器无法处理请求.--->对象引用未设置为对象的实例。”

我的SoapClient :: __ getTypes()请求给了我:

array(
 [2] => struct HostTransactionInfo {
 string SecurenetID;
 string SecureKey;
 string Test;
}
 [6] => struct Process_Save {
 HostTransactionInfo oTi;
}
)

我的SoapClient :: __ getFunctions()请求给了我:

array (
    [2] => Process_SaveResponse Process_Save(Process_Save $parameters)
)

有没有人知道我做错了什么?

3 个答案:

答案 0 :(得分:2)

securenet网络服务返回错误。为什么不联系他们的support

但无论如何,服务器应该返回比“未将对象引用设置为对象实例”更具信息性的消息。他们的代码在获得一些意外输入时取消引用空指针的事实对于那些应该是“安全”支付系统的东西来说并不是好兆头。

答案 1 :(得分:1)

请检查发送到服务器的XML请求以及您收到的XML响应:

// ...
$securenet = new SoapClient(self::WSDL, array(
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
    'trace'    => true  // that's important for the debugging methods to work
));
// ...
$save = $securenet->Process_Save($host_trans_info);
var_dump($securenet-> __getLastRequestHeaders());
var_dump($securenet-> __getLastRequest());
var_dump($securenet-> __getLastResponseHeaders());
var_dump($securenet-> __getLastResponse());

这将有助于您了解电线上发生的情况。如果您可以排除任何与服务器相关的问题,则该错误很可能与不符合所需格式的XML-SOAP请求有关。

答案 2 :(得分:1)

嗨,原来的提问者可能会迟到,但对于任何可能有同样错误的人来说......

这是我在使用M $ .Net或C#(CVS)或任何其他M $ Soap服务器时所学到的技巧...... M $改变了信封中的内容,这就是出错的地方。 ..

class MSSoapClient extends SoapClient {
   function __doRequest($request, $location, $action, $version) {
        $namespace = "http://tempuri.org/";

        $request = preg_replace('/<ns1:(\w+)/', '<$1 xmlns="'.$namespace.'"', $request, 1);
        $request = preg_replace('/<ns1:(\w+)/', '<$1', $request);
        $request = str_replace(array('/ns1:', 'xmlns:ns1="'.$namespace.'"'), array('/', ''), $request);        

        // parent call
        return parent::__doRequest($request, $location, $action, $version);
    }
}

这将纠正信封并在大多数情况下纠正错误...查看变量$namespace = "http://tempuri.org/";根据WSDL文件确保这是正确的

我不知道这是否会修复USER的错误,但它可能会帮助其他类似错误的人