12

How can i create variable from it's print_r output ? In other words, i'd like to know if something similar to my fictive var_import function exists in php ? var_import would be the inverse of var_export

He is a use case:

$a = var_import('Array ( [0] => foo [1] => bar )');
$output = var_export($a);
echo $output; // Array ( [0] => foo [1] => bar )

If such a function does not exist, is there a tool (or online tool) to do this ? I am also interested to do the same with var_dump output.

EDIT: The variable is only available as a print_r output (string). To clarify what i need, imagine the folowing situation: someone posts a some sample on the internet somewhere with a print_r output. To test his code, you need to import his print_r variable into your code. This is an example where var_import would be usefull.

Charles
  • 50,943
  • 13
  • 104
  • 142
Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236
  • You'll basically want to use the evil `eval`. – Joseph Silber Aug 29 '11 at 14:53
  • So you already know about `var_export`. But can you actually influence the input, or do you really need to reparse the print_r structure? Is so, a regex could work. But only reliably if newlines have been preserved or no nested arrays are present. – mario Aug 29 '11 at 14:56
  • There is no way you can properly parse `print_r` output back to an array, object, etc. It is not structured enough for that (i.e.: too human friendly). – netcoder Aug 29 '11 at 15:00
  • http://php.net/manual/bg/function.var-export.php – Alex Emilov Aug 29 '11 at 14:51

5 Answers5

18

Amusingly the PHP manual contains an example that tries to recreate the original structure from the print_r output:
print_r_reverse()
http://www.php.net/manual/en/function.print-r.php#93529

However it does depend on whitespace being preserved. So you would need the actual HTML content, not the rendered text to pipe it back in.

Also it doesn't look like it could understand anything but arrays, and does not descend. That would be incredibly difficult as there is no real termination marker for strings, which can both contain newlines and ) or even [0] and => which could be mistaken for print_r delimiters. Correctly reparsing the print_r structure would be near impossible even with a recursive regex (and an actual parser) - it could only be accomplished by guesswork splitting like in the code linked above.. (There are two more versions there, maybe you have to try them through to find a match for your specific case.)

mario
  • 144,265
  • 20
  • 237
  • 291
10

Why don't you use var_export instead ?

var_export(array(1, 2, 3)); // array(1, 2, 3)

You can import var_export's output with eval(), however I would recommend you to avoid this function as much as possible.

The following functions are better for exporting and importing variables:

serialize() and unserialize():

$string = serialize(array(1, 2, 3));
$array = unserialize($string); // array(1, 2, 3);

Or json_encode() and json_decode():

$string = json_encode(array(1, 2, 3));
$array = json_decode($string);
Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
  • I want to create my variable from the output (i don't have the variable before that). So i have `Array ( [0] => foo [1] => bar )`, not `array('foo', 'bar')` – Benjamin Crouzier Aug 29 '11 at 14:56
  • 1
    But why don't you use something other than print_r in the first place ? print_r()'s output is not meant to be parsable / importable. – Arnaud Le Blanc Aug 29 '11 at 14:56
  • 3
    None of your suggestions answers the **actual** question. The print_r input is the precondition, not an option. – mario Aug 29 '11 at 15:05
  • I was in the impression that he was wrongly using print_r for serializing purposes – Arnaud Le Blanc Aug 29 '11 at 15:16
  • I've been looking for something like this because people frequently put `print_r` output in SO questions, and I want to turn it into test data when I'm working on an answer. – Barmar Dec 15 '13 at 07:19
2

You can wrap it in an output buffer:

ob_start();
print_r(array(1,2,3));
$arr = ob_get_clean();
echo $arr;

Ok so I misunderstood the first question. I think I have another solution which actually does answer your question:

<?php
$ar = array('foo','bar');
$p = print_r($ar, true);

$reg = '/\[([0-9]+)\] \=\> ([a-z]+)/';
$m = preg_match_all($reg, $p, $ms);

$new_ar = $ms[2];

echo "Your wanted result:\n";
print_r($new_ar);
y_a_v_a
  • 122
  • 1
  • 4
0

If you want to import a var_export()'s variable, you can run the eval() function. Or if you save the contents into a file (with a return statement), you can use the return value of include() or require().

But I would rather use serialize() and unserialize() or json_encode() and json_decode().

define('EXPORT_JSON', 1);
define('EXPORT_SERIALIZE', 2);

function exportIntoFile($var, $filename, $method=EXPORT_JSON)
{
  if ( $method & EXPORT_JSON )
    file_put_contents( $filename, json_encode($var) );
  else if ($method & EXPORT_SERIALIZE)
    file_put_contents( $filename, serialize($var) );
}
function importFromFile($filename, $method=EXPORT_JSON)
{
  if ( $method & EXPORT_JSON )
    return json_decode( file_get_contents($filename) );
  else if ($method & EXPORT_SERIALIZE)
    return unserialize( file_get_contents($filename) );
}
ComFreek
  • 29,044
  • 18
  • 104
  • 156
-1

I'm not good at regex to code the final trash removal. Here is how far I could get though:

$str = 'Array ( [0] => foo [1] => bar [2] => baz)';
$t1 = explode('(', $str);
$t2 = explode(')', $t1[1]);
$t3 = explode(' => ', $t2[0]);
unset($t3[0]);

print_r($t3);

output:

Array
(
    [1] => foo [1]
    [2] => bar [2]
    [3] => baz
)
Majid Fouladpour
  • 29,356
  • 21
  • 76
  • 127