Convert var_dump of array back to array variable

Viewed 35755

I have never really thought about this until today, but after searching the web I didn't really find anything. Maybe I wasn't wording it right in the search.

Given an array (of multiple dimensions or not):

$data = array('this' => array('is' => 'the'), 'challenge' => array('for' => array('you')));

When var_dumped:

array(2) { ["this"]=> array(1) { ["is"]=> string(3) "the" } ["challenge"]=> array(1) { ["for"]=> array(1) { [0]=> string(3) "you" } } }

The challenge is this: What is the best optimized method for recompiling the array to a useable array for PHP? Like an undump_var() function. Whether the data is all on one line as output in a browser or whether it contains the line breaks as output to terminal.

Is it just a matter of regex? Or is there some other way? I am looking for creativity.

UPDATE: Note. I am familiar with serialize and unserialize folks. I am not looking for alternative solutions. This is a code challenge to see if it can be done in an optimized and creative way. So serialize and var_export are not solutions here. Nor are they the best answers.

7 Answers

Updated to NOT USE create_function, as it is DEPRECATED as of PHP 7.2.0. Instead it is replaced to use anonymous functions:



    function unvar_dump($str) {
        if (strpos($str, "\n") === false) {
            //Add new lines:
            $regex = array(
                '#(\[.*?\]=>)#',
                '#(string\(|int\(|float\(|array\(|NULL|object\(|})#',
            );
            $str = preg_replace($regex, "\n\1", $str);
            $str = trim($str);
        }
        $regex = array(
            '#^\040*NULL\040*$#m',
            '#^\s*array\((.*?)\)\s*{\s*$#m',
            '#^\s*string\((.*?)\)\s*(.*?)$#m',
            '#^\s*int\((.*?)\)\s*$#m',
            '#^\s*bool\(true\)\s*$#m',
            '#^\s*bool\(false\)\s*$#m',
            '#^\s*float\((.*?)\)\s*$#m',
            '#^\s*\[(\d+)\]\s*=>\s*$#m',
            '#\s*?\r?\n\s*#m',
        );
        $replace = array(
            'N',
            'a:\1:{',
            's:\1:\2',
            'i:\1',
            'b:1',
            'b:0',
            'd:\1',
            'i:\1',
            ';'
        );
        $serialized = preg_replace($regex, $replace, $str);
        $func = function($match) {
            return 's:'.strlen($match[1]).':"'.$match[1].'"';
        };
        $serialized = preg_replace_callback(
            '#\s*\["(.*?)"\]\s*=>#', 
            $func,
            $serialized
        );
        $func = function($match) {
            return 'O:'.strlen($match[1]).':"'.$match[1].'":'.$match[2].':{';
        };
        $serialized = preg_replace_callback(
            '#object\((.*?)\).*?\((\d+)\)\s*{\s*;#', 
            $func, 
            $serialized
        );
        $serialized = preg_replace(
            array('#};#', '#{;#'), 
            array('}', '{'), 
            $serialized
        );

        return unserialize($serialized);
    }

    $test = 'array(10) {
      ["status"]=>
      string(1) "1"
      ["transactionID"]=>
      string(14) "1532xxx"
      ["orderID"]=>
      string(10) "1532xxx"
      ["value"]=>
      string(8) "0.73xxx"
      ["address"]=>
      string(1) "-"
      ["confirmations"]=>
      string(3) "999"
      ["transaction_hash"]=>
      string(64) "internxxx"
      ["notes"]=>
      string(0) ""
      ["txCost"]=>
      string(1) "0"
      ["txTimestamp"]=>
      string(10) "1532078165"
    }';
    var_export(unvar_dump($test));


Related