31

There are lots of questions and answers around the subject of valid php syntax from var outputs, what I am looking for is a quick and clean way of getting the output of var_export to use valid php5.4 array syntax.

Given

$arr = [
    'key' => 'value',
    'mushroom' => [
        'badger' => 1
    ]
];


var_export($arr);

outputs

array (
  'key' => 'value',
  'mushroom' => 
  array (
    'badger' => 1,
  ),
)

Is there any quick and easy way to have it output the array as defined, using square bracket syntax?

[
    'key' => 'value',
    'mushroom' => [
        'badger' => 1
    ]
]

Is the general consensus to use regex parsing? If so, has anyone come across a decent regular expression? The value level contents of the arrays I will use will all be scalar and array, no objects or classes.

designermonkey
  • 1,078
  • 2
  • 16
  • 28
  • 1
    you really cant go back to the source and not use var_export ? –  Jun 19 '14 at 21:18
  • `array(...)` is still a valid syntax for declaring arrays in PHP. Square brackets are nothing but a syntactic sugar. – Crozin Jun 19 '14 at 21:18
  • Oh, I understand that, yes. I'm using it for configuration files, and it would be nice to be able to return back to the original declaration syntax. – designermonkey Jun 19 '14 at 21:20
  • What about just looping through the array and printing it out however you please? – Mark Miller Jun 19 '14 at 21:22
  • 4
    You know the old chinese saying, "If you don't like the default `var_export` syntax, write your own". – mario Jun 19 '14 at 21:22
  • Well, thats kind of what I'm asking for... I wouldn't really know where to start there ;) – designermonkey Jun 19 '14 at 21:23
  • I have many flavours of configuration, php arrays, json, xml, ini. I'm writing readers and writers for all of them. – designermonkey Jun 19 '14 at 21:26
  • But do you actually need to write this non-standard format? Why support a non-standard configuration format that you have to, in essence, write your own parser for? – Mike Brant Jun 19 '14 at 21:34
  • I don't need to, just trying to leverage less code each time it is parsed. They will initially be provided that way, so for them to change when any new configuration is written back out by the app would be weird in my view. – designermonkey Jun 19 '14 at 21:37
  • I guess that is understandable, but is it really that much of a stretch for a user to work in JSON as opposed to that config? In essence, all you would do is change `[]` to `{}`, `=>` to `:`, and `'` to `"`. – Mike Brant Jun 19 '14 at 21:40

5 Answers5

37

I had something similar laying around.

function var_export54($var, $indent="") {
    switch (gettype($var)) {
        case "string":
            return '"' . addcslashes($var, "\\\$\"\r\n\t\v\f") . '"';
        case "array":
            $indexed = array_keys($var) === range(0, count($var) - 1);
            $r = [];
            foreach ($var as $key => $value) {
                $r[] = "$indent    "
                     . ($indexed ? "" : var_export54($key) . " => ")
                     . var_export54($value, "$indent    ");
            }
            return "[\n" . implode(",\n", $r) . "\n" . $indent . "]";
        case "boolean":
            return $var ? "TRUE" : "FALSE";
        default:
            return var_export($var, TRUE);
    }
}

It's not overly pretty, but maybe sufficient for your case.

Any but the specified types are handled by the regular var_export. Thus for single-quoted strings, just comment out the string case.

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

For anyone looking for a more modern-day solution, use the Symfony var-exporter, also available as a standalone library on composer, but included in Symfony by default.

composer require symfony/var-exporter
use Symfony\Component\VarExporter\VarExporter;

// ...

echo VarExporter::export($arr)
robsch
  • 9,358
  • 9
  • 63
  • 104
Rein Baarsma
  • 1,466
  • 13
  • 22
12

I realize this question is ancient; but search leads me here. I didn't care for full iterations or using json_decode, so here's a preg_replace-based var_export twister that gets the job done.

function var_export_short($data, $return=true)
{
    $dump = var_export($data, true);

    $dump = preg_replace('#(?:\A|\n)([ ]*)array \(#i', '[', $dump); // Starts
    $dump = preg_replace('#\n([ ]*)\),#', "\n$1],", $dump); // Ends
    $dump = preg_replace('#=> \[\n\s+\],\n#', "=> [],\n", $dump); // Empties

    if (gettype($data) == 'object') { // Deal with object states
        $dump = str_replace('__set_state(array(', '__set_state([', $dump);
        $dump = preg_replace('#\)\)$#', "])", $dump);
    } else { 
        $dump = preg_replace('#\)$#', "]", $dump);
    }

    if ($return===true) {
        return $dump;
    } else {
        echo $dump;
    }
}

I've tested it on several arrays and objects. Not exhaustively by any measure, but it seems to be working fine. I've made the output "tight" by also compacting extra line-breaks and empty arrays. If you run into any inadvertent data corruption using this, please let me know. I haven't benchmarked this against the above solutions yet, but I suspect it'll be a good deal faster. Enjoy reading your arrays!

Markus AO
  • 4,771
  • 2
  • 18
  • 29
  • On a note of disclaimer... If there's variance between the formatting of `var_export` output on different PHP versions or platforms, this may obviously do some funnies. I was unable to find any information on that, so I presume there's none. Tested OK on PHP 5.6.2 and 7.0.2 on W7x64. – Markus AO Feb 04 '16 at 17:16
  • Does the job well with nested arrays, thanks for sharing. – Mahn May 09 '19 at 13:50
12

With https://github.com/zendframework/zend-code :

<?php
use Zend\Code\Generator\ValueGenerator;
$generator = new ValueGenerator($myArray, ValueGenerator::TYPE_ARRAY_SHORT);
$generator->setIndentation('  '); // 2 spaces
echo $generator->generate();
B.Asselin
  • 978
  • 10
  • 19
2

As the comments have pointed out, this is just an additional syntax. To get the var_export back to the bracket style str_replace works well if there are no ) in the key or value. It is still simple though using JSON as an intermediate:

$output = json_decode(str_replace(array('(',')'), array('&#40','&#41'), json_encode($arr)), true);
$output = var_export($output, true);
$output = str_replace(array('array (',')','&#40','&#41'), array('[',']','(',')'), $output);

I used the HTML entities for ( and ). You can use the escape sequence or whatever.

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87