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.
var_export
or serialize
is what you're looking for. var_export
will render a PHP parsable array syntax, and serialize
will render a non-human readable but reversible "array to string" conversion...
Edit Alright, for the challenge:
Basically, I convert the output into a serialized string (and then unserialize it). I don't claim this to be perfect, but it appears to work on some pretty complex structures that I've tried...
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 = create_function(
'$match',
'return "s:".strlen($match[1]).":\\"".$match[1]."\\"";'
);
$serialized = preg_replace_callback(
'#\\s*\\["(.*?)"\\]\\s*=>#',
$func,
$serialized
);
$func = create_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);
}
I tested it on a complex structure such as:
array(4) {
["foo"]=>
string(8) "Foo"bar""
[0]=>
int(4)
[5]=>
float(43.2)
["af"]=>
array(3) {
[0]=>
string(3) "123"
[1]=>
object(stdClass)#2 (2) {
["bar"]=>
string(4) "bart"
["foo"]=>
array(1) {
[0]=>
string(2) "re"
}
}
[2]=>
NULL
}
}