Adding attributes to the actual function tag in PH

2019-06-25 13:10发布

问题:

I need to add attributes to the tag representing the function/method in a call to a soap interface (specifically, a zimbra interface).

I understand how attributes are added to parameter tags, but not to the actual method tag.

For example, to add them to parameters, one might do something like:

    $var = new SoapVar('<account by="name">' . $account . '</account>', XSD_ANYXML);
    $params = array(new SoapParam($var, 'account'));

    try {
        $result = $this->SoapClient->__soapCall(
            "GetAccountInfoRequest", $params, null, $header
        );
    } catch (SoapFault $fault) {
        return false;
    } 

Which will generate the following expected XML:

<body>
    <GetAccountInfoRequest>
        <account by="name">*someAccountName*</account>
    </GetAccountInfoRequest>
</body>

But what happens when one need to add attributes to the actual method tag, such as in the Zimbra setPasswordRequest.

That request is expecting XML not unlike the following:

<body>
    <SetPasswordRequest id="someAccountId" newPassword="s3cr3tP@ss" />
</body>

Which is simply the tag representing the method with attributes and 0 parameters.

I've tried the following (to no avail):

    $var = new SoapVar('<SetPasswordRequest id="'.$accountInfo->id
        .' newPassword="'.$newPass.'"/>', XSD_ANYXML);
    $params = array(new SoapParam($var, 'SetPasswordRequest'));

    try {
        $result = $this->SoapClient->__soapCall(
            "SetPasswordRequest", $params, null, $header
        );
    } catch (SoapFault $fault) {
        return false;
    }

Which, much to my chagrin, created a nested tag like the following:

<body>
    <ns1:SetPasswordRequest>
        <SetPasswordRequest id="5329ee70-fb5b-4fa1-a6cb-4c5a3f7f8a91 newPassword="DpJsPX3w?"/>
    </ns1:SetPasswordRequest>
</body>

Currently, I'm serializing the soap XML manually for requests like this, and sending it with curl, but there must be a way to do this with SoapClient, I'm worried about code readability and portability for future developers on this, I don't want someone to have to learn to use my own iteration of a SOAP serializer just to be able to send requests.

回答1:

Looks like are missing a closing double quote in the code above.

$var = new SoapVar('<SetPasswordRequest id="'.$accountInfo->id
        .'" newPassword="'.$newPass.'"/>', XSD_ANYXML);
    $params = array(new SoapParam($var, 'SetPasswordRequest'));

Also reference this post for an alternative approach. PHP SoapVar Object Attribute?