**SOAP-ERROR:** Encoding: Cannot find encoding

**SOAP-ERROR:** Encoding: Cannot find encoding

我必须使用 PHP 的 SOAP 服务,但我一直无法获得响应。可能是格式或调用或 idk 的问题。例如,我可以使用 __getFunctions() 方法从服务器获取所有函数名称。但是当我尝试调用任何函数时,我不断得到:

SOAP-ERROR: Encoding: Cannot find encoding

下面是代码。

$wsdl = "https://testing.memoryefactura.com/Memory.FEManager/WebService/CFEService.svc?wsdl";


$parameters = array('Rut' => 'XXXXX',
    'CommerceCode' => 'XXXXX',
    'TerminalCode' => 'XXXXX',
    'Timeout' => 5000);


$options = array(
    'style' => SOAP_RPC,
    'use' => SOAP_ENCODED,
    'soap_version' => SOAP_1_1,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'connection_timeout' => 15,
    'trace' => true,
    'exceptions' => true,
);
try {
    $soap = new SoapClient($wsdl, $options);
    $HeaderSecurity = array(
        'stream_context' => stream_context_create(array(
            'http' => array(
                'header' => array('username' => 'XXXXX',
                    'password' => 'XXXXX'
                )
            ),
        )),
    );
    $header[] = new SoapHeader("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", $HeaderSecurity);

    $soap->__setSoapHeaders($header);
    $data = $soap->Ping($parameters);
} catch (Exception $e) {
    die($e->getMessage());
}

var_dump($data);

基于wsdl,ping方法只有3个参数。

class Ping {
    /** @var BaseMessage */ public $message;
}
class BaseMessage {
    /** @var string */  public $CommerceCode;
    /** @var string */  public $TerminalCode;
    /** @var int */ public $Timeout;
}

此外,您错误地设置了授权 header。正确的做法:

$wsdl = "https://testing.memoryefactura.com/Memory.FEManager/WebService/CFEService.svc?wsdl";

$opts = [
    'ssl' => [
        'verify_peer' => false,
        'verify_peer_name' => false
    ],
    'http' => [
        'user_agent' => 'PHPSoapClient'
    ]
];

$params = [
    'encoding' => 'UTF-8',
    'verifypeer' => false,
    'verifyhost' => false,
    'soap_version' => SOAP_1_1,
    'trace' => 1,
    'exceptions' => 1,
    'connection_timeout' => 180,
    'stream_context' => stream_context_create($opts)
];

try {
    $client = new \SoapClient($wsdl, $params);

    $nameSpace = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';

    $soapUsername = new \SoapVar(
        'XXXXX',
        XSD_STRING,
        null,
        $nameSpace,
        null,
        $nameSpace
    );

    $soapPassword = new \SoapVar(
        'XXXXX',
        XSD_STRING,
        null,
        $nameSpace,
        null,
        $nameSpace
    );

    $auth = new \stdClass();
    $auth->Username = $soapUsername;
    $auth->Password = $soapPassword;

    $soapAuth = new \SoapVar(
        $auth,
        SOAP_ENC_OBJECT,
        null,
        $nameSpace,
        'UsernameToken',
        $nameSpace
    );

    $token = new \stdClass();
    $token->UsernameToken = $soapAuth;

    $soapToken = new \SoapVar(
        $token,
        SOAP_ENC_OBJECT,
        null,
        $nameSpace,
        'UsernameToken',
        $nameSpace
    );

    $security = new \SoapVar(
        $soapToken,
        SOAP_ENC_OBJECT,
        null,
        $nameSpace,
        'Security',
        $nameSpace
    );

    $header = new \SoapHeader($nameSpace, 'Security', $security, true);

    $client->__setSoapHeaders([$header]);

    $parameters = array(
        'CommerceCode' => 'XXXXX',
        'TerminalCode' => 'XXXXX',
        'Timeout' => 5000
    );

    $data = $client->Ping($parameters);
} catch (SoapFault $fault) {
    echo "REQUEST:\n" . $client->__getLastRequest();
    die("\nFaultcode: " . $fault->faultcode . "\nFaultstring: " . $fault->faultstring);
} catch (Exception $e) {
    die($e->getMessage());
}