无法将NVP字符串转换为数组..?

时间:2014-07-31 07:26:44

标签: php arrays string

问题的快速版

我正在尝试这样的字符串......

BUTTONSOURCE[18]=AngellEYE_PHPClass&VERBOSITY[4]=HIGH&USER[6]=tester

并将其转换为此用于记录目的......

BUTTONSOURCE[18]=AngellEYE_PHPClass
VERBOSITY[4]=HIGH
USER[6]=tester

问题的详细版本

我一直使用此功能将NVP字符串转换为数组而没有任何问题......

function NVPToArray($NVPString)
{
    $proArray = array();
    while(strlen($NVPString))
    {
        // name
        $keypos= strpos($NVPString,'=');
        $keyval = substr($NVPString,0,$keypos);
        // value
        $valuepos = strpos($NVPString,'&') ? strpos($NVPString,'&'): strlen($NVPString);
        $valval = substr($NVPString,$keypos+1,$valuepos-$keypos-1);
        // decoding the respose
        $proArray[$keyval] = urldecode($valval);
        $NVPString = substr($NVPString,$valuepos+1,strlen($NVPString));
    }

    return $proArray;

}

我很久以前从某个地方把它拉出来,从那以后我就用它了。但是,现在,我正在处理一个NVP字符串,其中包含参数名称的[x]值以显示值的长度。例如,

BUTTONSOURCE[18]=AngellEYE_PHPClass&VERBOSITY[4]=HIGH...

当我通过我的函数运行这样的字符串时,[]会导致它将它看作一个数组索引,我最终得到一个像这样的数组......

Array
(
    [BUTTONSOURCE] => Array
        (
            [18] => AngellEYE_PHPClass
        )

    [VERBOSITY] => Array
        (
            [4] => HIGH
        )

那么如果我尝试这样的话......

        foreach($string_data_array as $var => $val)
        {
            $string_data_indiv .= $var.'='.$val.chr(13);
        }

我最终得到了一个“数组到字符串转换”的PHP注意事项,我的结果看起来像这样......

BUTTONSOURCE=Array
VERBOSITY=Array

我想要最终得到的是NVP字符串的一个很好的细分,一次一行。所以这就是我所期待的......

BUTTONSOURCE[18]=AngellEYE_PHPClass
VERBOSITY[4]=HIGH

我可能会认为这是一种可能更容易的疯狂方式,但在我开始使用包含像这样的字符数的NVP字符串之前,我从未遇到过这类问题。

我将非常感谢有关如何解决此问题的任何信息。谢谢!

1 个答案:

答案 0 :(得分:1)

PHP提供了一个执行此操作的函数:parse_str

注意:它处理' url编码'根据手册中的示例正确填写字符。

像往常一样,这变得比我想象的要复杂得多。 ; - /

嗯,这是非常脆弱的'作为一个功能 - 例如你不能' urlencode'整个字符串并将 parse_str 解码为相同的NVP。但是,你可以' urlencode()'任何_name_value_pair_,它将正确解码。这个功能很有用'但是并不像我希望的那样一般

1) The array characters '[' and ']' are used by PHP in a special manner.
2) The parameters may just be normal NVP's e.g. 'Param01=PlainText'
3) The parameter may be URL encoded. e.g. %3CParam42_URLEncodedWithSpecialChars%3E%3DThisIs42%21

首先, parse_str 会处理上述所有格式,但所生成的数组条目并不是“一致的”。格式。

此代码尝试在一个字符串中接受各种NVP格式并生成合理的输出。这应该是“一般性的”。使用

经测试的代码:PHP 5.3.18 Source Code at Pastebin.com

解析NVP字符串的函数:

function NVPToArray($NVPString) { // replacement for the original
    $parsed = array();
    parse_str($NVPString, $parsed);

    // convert it to an an associated array with the required formats:
    $nvpArray = array();
    foreach($parsed as $parsedName => $parsedValue) {
        if (is_array($parsedValue)) {
            $nvpName = $parsedName .'['. key($parsedValue) .']';
            $nvpValue = current($parsedValue);
        }
        elseif (empty($parsedValue)) { // was url encoded
            $parsedKeyAndValue = explode('=', $parsedName);
            $nvpName = $parsedKeyAndValue[0];
            $nvpValue = $parsedKeyAndValue[1];
        }
        else {
            $nvpName = $parsedName;
            $nvpValue = $parsedValue;
        }

        $nvpArray[$nvpName] =  $nvpValue;
    }
    return $nvpArray;
}

以下是一些使用该函数并显示输出的示例代码:

数据:

$p1 = 'ParamNoLength=PlainTextIsItAnArray';
$p2 = 'ParamNoLengthUrlEncoded=EncodedTextIsItAnArray';
$p3 = '<Param42_URLEncodedWithSpecialChars>=ThisIs42!';

$src = 'BUTTONSOURCE[18]=AngellEYE_PHPClass&VERBOSITY[4]=HIGH'
       .'&'. $p1
       .'&'. urlencode($p2)
       .'&'. urlencode($p3);

代码:

$nvpArray = NVPToArray($src);

echo '<br />Input NVP string:<pre>';
var_dump($src,  __FILE__.__LINE__);
echo '</pre>';

echo '<br />Output:<pre>';
var_dump($nvpArray,  __FILE__.__LINE__);
echo '</pre>';

输入数据:

'BUTTONSOURCE[18]=AngellEYE_PHPClass&VERBOSITY[4]=HIGH&ParamNoLength=PlainTextIsItAnArray&ParamNoLengthUrlEncoded%3DEncodedTextIsItAnArray&%3CParam42_URLEncodedWithSpecialChars%3E%3DThisIs42%21'

输出:

array
  'BUTTONSOURCE[18]' => string 'AngellEYE_PHPClass' (length=18)
  'VERBOSITY[4]' => string 'HIGH' (length=4)
  'ParamNoLength' => string 'PlainTextIsItAnArray' (length=20)
  'ParamNoLengthUrlEncoded' => string 'EncodedTextIsItAnArray' (length=22)
  '<Param42_URLEncodedWithSpecialChars>' => string 'ThisIs42!' (length=9)