Skip to content

Instantly share code, notes, and snippets.

@rubo77
Forked from Shagshag/gist:5849065
Last active May 7, 2021 11:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save rubo77/6821632 to your computer and use it in GitHub Desktop.
Save rubo77/6821632 to your computer and use it in GitHub Desktop.
This is a replacement for the original idea how to cirumvent the max_input_vars limitation, that uses the original parse_str() on each element of the query to parse
<?php
/**
* do the same than parse_str without max_input_vars limitation:
* Parses $string as if it were the query string passed via a URL and sets variables in the current scope.
* @param $string array string to parse (not altered like in the original parse_str(), use the second parameter!)
* @param $result array If the second parameter is present, variables are stored in this variable as array elements
* @return bool true or false if $string is an empty string
*
* @author rubo77 at https://gist.github.com/rubo77/6821632
**/
function my_parse_str($string, &$result) {
if($string==='') return false;
$result = array();
// find the pairs "name=value"
$pairs = explode('&', $string);
foreach ($pairs as $pair) {
// use the original parse_str() on each element
parse_str($pair, $params);
$k=key($params);
if(!isset($result[$k])) $result+=$params;
else $result[$k] = array_merge_recursive_distinct($result[$k], $params[$k]);
}
return true;
}
// better recursive array merge function listed on the array_merge_recursive PHP page in the comments
function array_merge_recursive_distinct ( array &$array1, array &$array2 ){
$merged = $array1;
foreach ( $array2 as $key => &$value ) {
if ( is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) ){
$merged [$key] = array_merge_recursive_distinct ( $merged [$key], $value );
} else {
$merged [$key] = $value;
}
}
return $merged;
}
my_parse_str($query, $array);
?>
@phinor
Copy link

phinor commented Sep 19, 2019

OK, the following seems to mirror parse_str perfectly, including dynamic keys which are not last. Specifically, the my_parse_str function becomes:

function my_parse_str($string)
{
    if ($string === '') {
        return [];
    }

    $vars = explode ('&', $string);
    $result = [];
    $count = [];
    foreach ($vars as $var) {
        $dkIndex = strpos($var, '[]');
        if (false === $dkIndex) {
             $dkIndex = strpos ($var, '%5B%5D');
        }
        if (false !== $dkIndex) {
            $varPrefix = substr($var, 0, $dkIndex);
            if (!isset ($count [$varPrefix])) {
                $count [$varPrefix] = 0;
            }
            $var = str_replace(['[]', '%5B%5D'], "[" . $count [$varPrefix]++ . "]", $var);
        }

        // use the original parse_str() on each element
        $params = null;
        parse_str ($var, $params);
        $k = key ($params);
        if (!isset($result[$k])) {
            $result += $params;
        }
        else {
            $result[$k] = array_merge_recursive_distinct ($result[$k], $params[$k]);
        }
    }

    return $result;
}

This works with the following test case:

$string = "key[][index]=1&key[][index]=2&key[][index]=3&var2[][]=1&var2[][]=2&key[1][index]=hi";
$parsed = my_parse_str($string);
print_r ($parsed);
parse_str ($string, $results);
print_r ($results);

Note carefully the overwritten second key[][index]=2 which is consistent with parse_str's behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment