Php SoapClient-递归地去除请求中生成的虚假标记

Php SoapClient-递归地去除请求中生成的虚假标记,php,soap,Php,Soap,我感到非常惊讶的是,这个问题并没有更普遍,但在谷歌只有几个答案。这些都非常特定于一个请求,解决方案是在发送前手动调整Soap参数的结构。首先,我要明确我正在为多个服务呼叫开发一个中央网关。这些调用唯一的共同点是,它们向中心方法传递一个多维参数数组。然后,中心方法进行SoapClient调用 如果需要,我可以单独构造阵列。我无法按照建议构建单个Soap参数对象 在此实例中,我有以下数组: Array ( [userId] => 336790 [locationId] =>

我感到非常惊讶的是,这个问题并没有更普遍,但在谷歌只有几个答案。这些都非常特定于一个请求,解决方案是在发送前手动调整Soap参数的结构。首先,我要明确我正在为多个服务呼叫开发一个中央网关。这些调用唯一的共同点是,它们向中心方法传递一个多维参数数组。然后,中心方法进行SoapClient调用

如果需要,我可以单独构造阵列。我无法按照建议构建单个Soap参数对象

在此实例中,我有以下数组:

Array
(
    [userId] => 336790
    [locationId] => 47862
    [schedule] => Array
        (
            [cipTime] => 15
            [confirmed] => 1
            [cycle] => Twice per Day
            [periods] => Array
                (
                    [0] => Array
                        (
                            [WS_Period] => Array
                                (
                                    [duration] => 300
                                    [startTime] => 15
                                )

                        )

                    [1] => Array
                        (
                            [WS_Period] => Array
                                (
                                    [duration] => 240
                                    [startTime] => 870
                                )

                        )

                )

            [startDate] => 16-08-2014
        )

)
我试图创建一个递归函数来循环这个数组并构建一个有效的Soap请求对象

// Encode the params array into a format that the soap client can use.
    // This is to avoid the dreaded <BOGUS> tags that the PHP SoapClient generates in the request.
    private function encodeSoapParams(Array $params) {

        // The entire request should be an array
        $request = array();

        foreach ($params as $name => $value) {
            if(is_scalar($value)) {
                $request[$name] = new SoapVar($value, XSD_STRING, null, null, $name);
            } elseif(is_array($value)) {
                $newValue = $this->encodeSoapParams($value);
                $request[$name] = new SoapVar($newValue, SOAP_ENC_OBJECT, null, null, $name);       
            }
        }

        return $request;
    }
//将params数组编码为soap客户端可以使用的格式。
//这是为了避免PHP SoapClient在请求中生成可怕的标记。
私有函数编码soapparams(数组$params){
//整个请求应该是一个数组
$request=array();
foreach($name=>$value的参数){
if(是_标量($value)){
$request[$name]=newsoapvar($value,XSD_字符串,null,null,$name);
}elseif(is_数组($value)){
$newValue=$this->encodeSoapParams($value);
$request[$name]=newsoapvar($newValue,SOAP\u ENC\u对象,null,null,$name);
}
}
返回$request;
}
这在大多数情况下都很好,除了我们使用周期数字数组。(上述数组中两个数字索引项的集合)。我在请求XML中得到的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="urn:Blah/WebService/">
    <env:Body>
        <ns1:updateSchedule>
            <userId>336790</userId>
            <locationId>47862</locationId>
            <schedule>
                <cipTime>15</cipTime>
                <confirmed>1</confirmed>
                <cycle>Twice per Day</cycle>
                <periods>
                    <BOGUS>
                        <WS_Period>
                            <duration>300</duration>
                            <startTime>15</startTime>
                        </WS_Period>
                    </BOGUS>
                    <BOGUS>
                        <WS_Period>
                            <duration>240</duration>
                            <startTime>870</startTime>
                        </WS_Period>
                    </BOGUS>
                </periods>
                <startDate>16-08-2014</startDate>
            </schedule>
        </ns1:updateSchedule>
    </env:Body>
</env:Envelope>

336790
47862
15
1.
每天两次
300
15
240
870
16-08-2014
这几乎是正确的。如果只完全省略了
级别标记。目前,该服务正在抱怨结构(我无法控制该服务)


关于如何让递归函数识别这样的集合,有什么想法吗?实际上,我认为这更像是一个逻辑挑战,而不是一个特定于Soap的挑战。

这个问题可能取决于单个数组结构,但下面的递归函数对我抛出的每个数组都有效:

// Encode the params array into a format that the soap client can use.
    // This is to avoid the dreaded <BOGUS> tags that the PHP SoapClient generates in the request.
    // All PI call param arrays should pass through here first
    private function encodeSoapParams(Array $params) {

        // The entire request should be an array
        $request = array();

        foreach($params as $name => $value) {
            if(is_scalar($value)) {
                $request[$name] = new SoapVar($value, XSD_STRING, null, null, $name);
            } else {
                if($this->IsArrayAllKeyInt($value)) {
                    $collection = array();

                    foreach($value as $key => $itemVal) {
                        //$collection[] = $itemVal;
                        if(is_scalar($itemVal)) {
                            $collection[] = new SoapVar($itemVal, XSD_STRING, null, null, $name);
                        } else {
                            // We have an array
                            $subKey = key($itemVal);
                            $collection[] = new SoapVar($itemVal[$subKey], SOAP_ENC_OBJECT, null, null, key($itemVal));
                        }
                    }
                    $request[$name] = new SoapVar($collection,SOAP_ENC_OBJECT,null,null, $name);
                } else {
                    $newValue = $this->encodeSoapParams($value);
                    $request[$name] = new SoapVar($newValue, SOAP_ENC_OBJECT, null, null, $name);
                }
            }
        }

        return $request;
    }

// See if a given array has all Int keys.
// See encodeSoapParams()
function IsArrayAllKeyInt($InputArray)
{
    if(!is_array($InputArray))
    {
        return false;
    }

    if(count($InputArray) <= 0)
    {
        return true;
    }

    return array_unique(array_map("is_int", array_keys($InputArray))) === array(true);
}
//将params数组编码为soap客户端可以使用的格式。
//这是为了避免PHP SoapClient在请求中生成可怕的标记。
//所有PI调用参数数组都应首先通过此处
私有函数编码soapparams(数组$params){
//整个请求应该是一个数组
$request=array();
foreach($name=>$value的参数){
if(是_标量($value)){
$request[$name]=newsoapvar($value,XSD_字符串,null,null,$name);
}否则{
如果($this->IsArrayAllKeyInt($value)){
$collection=array();
foreach($key=>$itemVal的值){
//$collection[]=$itemVal;
if(是_标量($itemVal)){
$collection[]=newsoapvar($itemVal,XSD_字符串,null,null,$name);
}否则{
//我们有一个数组
$subKey=key($itemVal);
$collection[]=newsoapvar($itemVal[$subKey],SOAP_ENC_对象,null,null,key($itemVal));
}
}
$request[$name]=newsoapvar($collection,SOAP\u ENC\u OBJECT,null,null,$name);
}否则{
$newValue=$this->encodeSoapParams($value);
$request[$name]=newsoapvar($newValue,SOAP\u ENC\u对象,null,null,$name);
}
}
}
返回$request;
}
//查看给定数组是否具有所有Int键。
//请参见encodeSoapParams()
函数IsArrayAllKeyInt($InputArray)
{
如果(!is_数组($InputArray))
{
返回false;
}

如果(count($InputArray)如何实现此功能,请指导我..?或更新完整代码。