Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Quick version of question

I'm trying to take a string like this...

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

and turn it into this for logging purposes...

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

Detailed version of question

I've always used this function to convert an NVP string to an array without any problems...

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;

}

I pulled it from somewhere a long time ago and I've used it ever since. Now, though, I'm working with an NVP string that includes [x] values on the parameter names to show the lengh of the value. For example,

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

When I run a string like that through my function, though, the []'s are causing it to see it as an array index, and I end up with an array like this...

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

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

So then if I try something like this...

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

I end up with an "array to string conversion" PHP Notice and my result looks like this...

BUTTONSOURCE=Array
VERBOSITY=Array

What I'm trying to end up with is a nice break-down of the NVP string, one line at a time. So this is what I was expecting...

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

I may be going about this a crazy way that could be a lot easier, but I've never had any issues with this sort of thing until I started working with an NVP string that includes the character count like this.

Any information on how I can resolve this issue would be greatly appreciated. Thanks!

share|improve this question
    
Have you updated your PHP version ? I don't have any issue with PHP5.5. –  Debflav yesterday
    
I'm currently running 5.5.12 –  Andrew Angell yesterday
    
What is the exact format of your string? Why don't simply match all you need with preg_match_all() ? –  Alma Do yesterday
    
I provided the exact format (though just the first couple of parameters) in the original post. It's BUTTONSOURCE[18]=AngellEYE_PHPClass&VERBOSITY[4]=HIGH. The entire string is just more of the same with different vars and vals. I'm not sure I understand what you're saying I should try with preg_match_all()..?? –  Andrew Angell yesterday
    
So you want that, for instance "BUTTONSOURCE[18]" would be your string key in the array? –  Alma Do yesterday

1 Answer 1

PHP provides a function to do this called: parse_str.

Note: It handles 'url encoded' characters correctly according to the example in the manual.

As usual, this turned into rather more complex than i first thought. ;-/

Hmm, this is 'quite fragile' as a function - for example you cannot 'urlencode' the entire string and have parse_str decode it as the the same NVP's. However, you can 'urlencode()' any _name_value_pair_ and it will decode them correctly. This function is 'useful' but not as general as i wish.

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

First, parse_str handles all the above formats but the array entries produced are not of a 'consistent' format.

This code attempts to accept the various NVP formats in one string and produce sensible outputs. This should make it of 'general' use.

Tested code: PHP 5.3.18 Source Code at Pastebin.com

The function that parses the NVP string:

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;
}

Here is some sample code that uses the function and displays the output:

Data:

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

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

Code:

$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>';

Input data:

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

Output :

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)
share|improve this answer
    
hmmm..that looks like it's giving me the same thing I'm already getting, but then you're just pulling out each piece and formatting the output differently..?? I need the output formatted just like I showed it. –  Andrew Angell yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.