10

I've stored some website configuration data in a config.json file, with things like database connection parameters and routes. Something like this:

{
    "production" : { ... },
    "test" : { ... },
    "development" : { ... }
}

And the content is loaded with:

$config = json_decode(file_get_contents('config'), true);

However, inspecting some frameworks, I see direct usage of PHP scripts for configuration storage:

<?php
return array(
    'production' => array( ... ),
    'test' => array( ... ),
    'development' => array( ... )
);
<?php $config = (require 'config.php');

Which approach is the best?

Tasso Evangelista
  • 1,612
  • 1
  • 16
  • 23
  • 8
    If you're loading from JSON, make for absolute certain that the .json file resides outside the document root, or the web server is configured _not_ to allow access to it. PHP files would be executed as PHP, and their contents not served down to the client. – Michael Berkowski Jul 16 '13 at 01:47
  • Loading pure PHP will always be faster than parsing a JSON file. Plus as @Petah said in the answer below, there are certain things that just don't store well in JSON that are perfectly simple to stuff into a PHP Array/Object/etc. A lot of frameworks will use a Singleton style object with a static method to pull a single instance of the object to reduce overhead and make sure your config data remains consistent throughout the scope regardless of where it is included/modified/etc. – Brian Jul 16 '13 at 01:56
  • 4
    One other argument against JSON - it doesn't support _comments_! – Michael Berkowski Jul 16 '13 at 01:57
  • Data files (such as JSON or XML or YAML or INI) are mostly used in lieu of php config scripts because they are seen as more rewritable/editable through admin interfaces. PHP scripts often require human editing, while data files (usually without comments) can be labeled as such and therefore discarded and rewritten. – mario Jul 16 '13 at 02:03
  • 1
    @Brian, why would loading pure PHP always be faster than parsing a JSON file? While there are plenty of PHP bytecode caching mechanisms out there, the actual work involved in reading and parsing JSON is much, much less than compiling and running PHP code. (Note that I still think config.php is the better approach though) – Nils Jun 09 '14 at 09:41
  • @Nils Loading a PHP file containing an array or object would be much quicker than loading the contents of a text file (JSON) into memory and running it through a higher level parser like `json_decode()`. Plus as mentioned in the answer below, you have a lot more flexibility with a PHP file in terms of datatypes, and if your server is using any kind of caching mechanism (which most would be), you'll gain performance there as well. – Brian Jun 13 '14 at 20:15
  • @Brian, I realize you're saying that, but I don't believe that's true. `json_decode()` deals with data only, while PHP code needs not only to be parsed but also evaluated. What you are saying about loading the file into memory naturally applies to loading a PHP file into memory too. You call `json_decode` a higher-level parser, but is PHP if not that with additional logic? (that said, it's hardly going to be significant difference in any real application - but `json_decode(file_get_contents('config.json'))` is likely to be faster than `require 'config.php';`) – Nils Jun 14 '14 at 08:35
  • (just to emphasize again; using PHP is usually a better option still, but let's make decisions for the right reasons) – Nils Jun 14 '14 at 08:38
  • For posterity sake I benchmarked it on a machine without any optimizer or cache mechanism for PHP. The JSON is indeed a little faster. PHP config file loaded through `$config = include('file.php')` was 0.000324ms and the json loaded via `json_decode( file_get_contents( 'file.json' ) )` was 0.000312ms so there's definitely a performance boost to the JSON approach. I'll leave it to someone else to do benchmarking with a PHP optimizer if they want to as it may close that gap. – Brian Jun 24 '14 at 18:23
  • @Brian Can you do this benchmark in triplicate and with large data? – Tasso Evangelista Jun 24 '14 at 19:24
  • That benchmark time was the average time per iteration over 5000 iterations of each method. The data being loaded was an array containing string indexes with 1 string, 1 array of integers, 1 integer, and 1 float as values. I won't be personally doing any more benchmarks on it as I think the point has been made that the JSON approach, while less flexible than the PHP one, is faster without any PHP caching/optimizers in place. Given the negligible amount of time spent on either method, and given that most apps only load their config file into memory once per run, I'm satisfied here ;) – Brian Jun 24 '14 at 20:12

3 Answers3

20

There are several advantages to using the config.php approach:

  1. The PHP compiler will tell you quickly if you have a syntax error in the config.php file when it gets loaded, whereas you would have to wait until you parse the JSON file to pick up any errors
  2. The PHP file will load faster than parsing the JSON file for the 2nd and subsequent page loads because the script will be cached by the web server (if cacheing is supported & enabled).
  3. There is less chance of security breach. As Michael Berkowski pointed out in his comment, if you don't store your JSON file outside the document root or configure the web server settings properly, web clients will be able to download your JSON file and get your database username & password and gain direct access to your database. By contrast, if the web server is configured properly to process *.php files via the PHP script engine, a client cannot directly download config.php even if it resides under the document root directory.

Not sure there are really any advantages to using JSON rather than config.php other than if you had multiple applications written in different languages (perl, python, and php for example) that all needed access to the same shared configuration information. There may be other advantages to JSON, but none come to mind at the moment.

linguanerd
  • 751
  • 3
  • 11
  • 2
    "[...] should load faster[...]", why? Also, I think that even application PHP files must not be in public folder. – Tasso Evangelista Jul 16 '13 at 02:57
  • 2
    @tassoevan - Added some clarifications to hopefully better explain the issues you bring up in your comment. – linguanerd Jul 16 '13 at 03:13
  • But a PHP config file can run code :O, which can be a security risk. JSON does not run code. – ESL Oct 27 '14 at 20:50
  • 1
    1. Whether its PHP or JSON, some parser has to go through it before throwing an error, so that is certainly not an advantage. 2. That's completely wrong. If the page is getting cached by the browser, it won't matter where your config was loaded... the resulting application output is cached. 3. Always keep this stuff outside of the document root, always. I've seen servers all the time that get upgraded and then have broken config, with all the source code and config (including passwords) visible to all. If your code isn't in the document root anyway, it isn't a problem. -1 – Brad Nov 16 '14 at 00:51
  • Nowadays, in dockerized environments with separated data/config files and code files, loading configs as PHP directives is no longer superior, or may be even an obstacle (especially if the app is brought to you as a docker container with all code compiled using repo-authoritative and sources removed). – Lukasz032 Sep 23 '20 at 01:22
3

It is generally faster to load from a PHP config file, plus it also supports more features, such as closures and byte code caching (if enabled).

Petah
  • 45,477
  • 28
  • 157
  • 213
  • Caching is nice, but why closures? – Tasso Evangelista Jul 16 '13 at 02:58
  • @tassoevan for things such as only connect to your database/external providers when required. – Petah Jul 16 '13 at 03:06
  • Can you give me a example? I love closures, but I can't see usage for it here. – Tasso Evangelista Jul 16 '13 at 13:06
  • @tassoevan a simplified example of something I use: http://pastebin.com/2DhMvJTr basically, in my config, I have closures that return a data storage interface, so only when pages that require it will create the connection. – Petah Jul 16 '13 at 13:23
  • @tassoevan and what would be your suggested way? – Petah Jul 16 '13 at 21:58
  • It can be dangerous, imagine users with access to config (configuring their profile, their minisite, etc.) with php access… they could read tables and other scripts and files (containing passwords or sensible data), sending mails, etc. – ESL Oct 27 '14 at 21:09
  • @ESL users should not have access to server level configuration. – Petah Oct 28 '14 at 01:14
2

Just a note - PHP has a special function for fast loading .ini files that can parse your configuration file

as mentioned in : PHP parse_ini_file() performance?

it is one of the faster method to load configuration files.

Here is the man for it:

http://php.net/manual/en/function.parse-ini-file.php

Community
  • 1
  • 1
azngunit81
  • 1,574
  • 2
  • 20
  • 38