1

Following my last post about better syntax for arrays, I've decided to use JSON format for arrays and use a method to convert them into PHP code.

Note that the ultimate goal of this is to be write a $config array in JSON and translate that into PHP code (so I can avoid having to use PHP's ugly array syntax):

The function works fine for arrays of arbitrary size and dimension, maybe I could improve it by having it automatically indent, but there isn't much more. Does anyone here any suggestions on how to make it better?

Community
  • 1
  • 1
quantumSoup
  • 27,197
  • 9
  • 43
  • 57
  • 1
    This seems to replace the ugliness of PHP's array syntax with the ugliness of a piece of code designed to get around it. – Amber Jul 14 '10 at 18:04
  • Indeed, but the ultimate goal is to simplify the writing of the config array, which can get really cluttered if written in PHP. This code will run a handful of times but will make my life (and whoever is going to maintain the rest of the code) easier. – quantumSoup Jul 14 '10 at 18:07
  • You're using json_decode ... why not use json_encode as well? See http://php.net/JSON – Cfreak Jul 14 '10 at 18:07
  • 5
    If you're code is ever going to be maintained by someone else this is a bad idea. IMHO – Cfreak Jul 14 '10 at 18:09
  • Why do you write your config files with PHP anyway? Why don't you use something like [ **YAML** ](http://en.wikipedia.org/wiki/YAML) which is easy to read and to write (or one of the many others like XML, INI, etc.) ? – Felix Kling Jul 14 '10 at 18:15
  • The idea is to generate PHP code without having to write (what I personally believe to be) ugly PHP array syntax. This will let me use JSON but anyone else looking at the config file will still see native PHP code. – quantumSoup Jul 14 '10 at 18:16
  • @Felix-Kling and @Cfreak For the same reason I am not writing the config files in JSON... I won't have the overhead of decoding that data every time I run the script. – quantumSoup Jul 14 '10 at 18:17
  • 3
    As the author of this json_decode solution yesterday, I have to say that this is kind of insane. There's no way that this will be easier to maintain than the language-provided standard way of creating arrays that everybody already knows about because it's the first thing you learn in PHP 101. Arrays aren't that ugly, and you've now spent far more time creating a workaround to prevent having to write the word 'array()' a few times than you would've spent had you just bit the bullet and created the arrays by hand. – okalex Jul 14 '10 at 18:21
  • @okalex I am writing many of these config files (which also happen to be huge). You'd see what I am talking about if you saw one of them. I am definitely way before the break-even point in terms of time spent. – quantumSoup Jul 14 '10 at 18:24
  • @Aircule this is not feasible. If you are so turned off by arrays then consider switching to Ruby or Python, where you can use named params. PHP does not provide them. The code above is a nightmare already and Json won't allow you to use Typed Objects anyway. – Gordon Jul 14 '10 at 18:45
  • This is a maintenance nightmare. Specifying your PHP config files in JavaScript is insane. Suck it up and write the config file in vanilla PHP. It will be just as clean, far faster and *far* easier to maintain. If you absolutely will not do this, look into YAML and use an off-the-shell YAML parser. – user229044 Jul 14 '10 at 19:38
  • @meager I don't plan on having this generate code every time I run the scripts. I'll just use it when I am generating the config file itself. – quantumSoup Jul 14 '10 at 19:40
  • @Aircule That is so much worse... You're functionally compiling your JavaScript config files to PHP, introducing a build step which must run every time your source JS config file is updated, and which *will* eventually be forgotten. Worst of all is that you're already using a PHP config file, to which updates might be made and lost by somebody unfamiliar with your JS build process. – user229044 Jul 14 '10 at 19:41
  • @meager The source JSON files aren't meant to be be updated. I didn't make myself very clear, but the main reason why I am using the JSON format because many other people will be looking at these config files. Most of them are not PHP-savvy and JSON is a much more human-readable format. – quantumSoup Jul 14 '10 at 19:45

5 Answers5

7

Have you seen var_export? It looks like you've reinvented it.

Also, if you're defining your config in JSON, why are you turning it into PHP syntax? Why not just read it in as JSON, json_decode it, and then use it as is? It seems like maintaining the data serialized in both PHP format, and JSON format is really ugly and unnecessary.

I would also echo what amber said in the comments... it seems like you've replaced the somewhat ugly, but very straightforward PHP array syntax with a much uglier hack. No offense, but this doesn't seem like a very good idea. Here's an example of a config file from the Kohana PHP framework. I don't find this file to be particularly ugly to read, and it's native PHP, so any PHP developer can work with it.

davidtbernal
  • 13,434
  • 9
  • 44
  • 60
  • var_export lacks the $cleanKeys functionality (ie: generate `array(1,2)` instead of `array(0 => 1, 1 => 2)`) – quantumSoup Jul 14 '10 at 18:12
  • @Aircule Is that so important? – luiscubal Jul 14 '10 at 18:15
  • Not extremely, but makes things even more cluttered. – quantumSoup Jul 14 '10 at 18:19
  • Aircule, those things are actually identical. You should format your array like the example I posted, so that it's readable. This would make it feel less cluttered. – davidtbernal Jul 14 '10 at 18:23
  • @Aircule - Also, your code seems vulnerable to code injections(like SQL injections, but for PHP), since you don't escape your strings. – luiscubal Jul 14 '10 at 18:23
  • @luiscubal Irrelevant, since only me (or another developer, if any) will be using this. – quantumSoup Jul 14 '10 at 18:26
  • @notJim The problem with formatting that is that each of these files is going to be huge, with several levels of indentation. None of the PHP beautifiers do the trick. I guess I should code that, huh? – quantumSoup Jul 14 '10 at 18:27
  • @Aircule Not irrelevant, because one day you'll forget, and use this function with some data - ANY data - that's user-provided(and, as a result, untrusted). Then you'll regret it. Also, it'll be a huge inconvenience later since your code won't work properly if strings include the ' character and you spend ten hours trying to figure out why. Also, if you get used to code like this, you might get used to write unsafe code, even for projects that interact with real(aka evil) users, which might be a problem. – luiscubal Jul 14 '10 at 18:29
  • @luiscubal Sanitizing user input is something I definitely won't forget. And letting users directly inject PHP code is something I will never do. About the ' character; nice catch, but the PHP error would (hopefully) be verbose enough for me to catch that. – quantumSoup Jul 14 '10 at 18:35
  • @Aircule - Still, if you're really going with this function instead of JSON or var_export, then I'd solve the ' problem sooner rather than later. – luiscubal Jul 14 '10 at 19:08
5

I will make one last effort to convince you not to do this. You asked for ways to improve upon your idea, and the best improvement you could make would be to not do it.

Here's is the PHP version of a config file from Kohana:

$test = array(
    'default' => array(
        'type'       => 'mysql',
        'connection' => array(
            'hostname'   => 'localhost',
            'database'   => 'kohana',
            'username'   => FALSE,
            'password'   => FALSE,
            'persistent' => FALSE,
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'caching'      => FALSE,
        'profiling'    => TRUE,
    ),
    'alternate' => array(
        'type'       => 'pdo',
        'connection' => array(
            'dsn'        => 'mysql:host=localhost;dbname=kohana',
            'username'   => 'root',
            'password'   => 'r00tdb',
            'persistent' => FALSE,
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'caching'      => FALSE,
        'profiling'    => TRUE,
    ),
);

And here is the JSON version:

var test = {
    "default": {
        "type": "mysql",
        "connection": {
            "hostname": "localhost",
            "database": "kohana",
            "username": false,
            "password": false,
            "persistent": false
        },
        "table_prefix": "",
        "charset": "utf8",
        "caching": false,
        "profiling": true
    },
    "alternate": {
        "type": "pdo",
        "connection": {
            "dsn": "mysql:host=localhost;dbname=kohana",
            "username": "root",
            "password": "r00tdb",
            "persistent": false
        },
        "table_prefix": "",
        "charset": "utf8",
        "caching": false,
        "profiling": true
    }
};

They're nearly identical. I really fail to see what you're gaining.

davidtbernal
  • 13,434
  • 9
  • 44
  • 60
2

var_export is your answer! Makes your a lot easier.

Dennis Haarbrink
  • 3,738
  • 1
  • 27
  • 54
0

Here is my solution for that

$data = json_decode(file_get_contents(__DIR__ . '/data.json'));
$code = var_export((array)$data, true);
$code = "<?php\n return " . preg_replace('/stdClass::__set_state/', '(object)', $code) . ';';
file_put_contents(__DIR__ . '/data.array.php', $code);

Data are taken from JSON file, but can be replaced with something else.

OzzyCzech
  • 9,713
  • 3
  • 50
  • 34
0

OK, after hearing all the feedback from everybody here, I've decided to make a "compromise." My main beef with the existing array syntax is its bad readability, which can certainly be improved (a lot) by using indentation.

Because I am lazy to indent (and the files I am writing are huge), I opted for JSON (or any syntax that's more readable than PHP's). I didn't make myself very clear, but another strong reason why I am using the JSON format because many other people will be looking at these config files. Most of them are not PHP-savvy and JSON is a much more human-readable format.

Unfortunately PHP code formatters/beautifiers out there don't do anything to array formatting, so I coded my own. It is based on that ugly piece of code I wrote above (and it is uglier), but it does the job.

The result is now I basically have an array beautifier, and I can generate readable native PHP code while being lazy. That's all I wanted, thanks everybody for the suggestions and pointers.

PS: Here's the beautified Kohana config array I generated with my function:

array (
    'default'   => array (
        'type'         => 'mysql',
        'connection'   => array (
            'hostname'   => 'localhost',
            'database'   => 'kohana',
            'username'   => false,
            'password'   => false,
            'persistent' => false
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'caching'      => false,
        'profiling'    => true
    ),
    'alternate' => array (
        'type'         => 'pdo',
        'connection'   => array (
            'dsn'        => 'mysql:host=localhost;dbname=kohana',
            'username'   => 'root',
            'password'   => 'r00tdb',
            'persistent' => false
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'caching'      => false,
        'profiling'    => true
    )
);

Which doesn't look bad at all.

quantumSoup
  • 27,197
  • 9
  • 43
  • 57