26

What is the fastest way to store config data in PHP so that it is easily changeable (via PHP)? First I thought about having config.php file, but I can't edit it on fly with PHP, at least not very simply? Then I thought about having XML files, but parsing them for each HTTP request is overwhelming. So, I thought about INI files, but then I figured that INI files are restricted to int/string values. In the end, I have come to the conclusion that JSON encoded file is the best:

$config['database']['host'] = ...;
$config['another']['something'] = ...;
...
json_encode($config);

Since JSON can store arrays, I can create quite complex configurations with it, and it parses faster than INI files.

My question: did I miss something or is there a better way to do this?

Tower
  • 98,741
  • 129
  • 357
  • 507

7 Answers7

43

Serialize is a better option than JSON for storing PHP variables.

I like to use var_export for saving config file, and using include for loading config info. This makes it easy to save config data progmatically AND makes the data easy to read/write for a person as well:

config.php:

return array(
 'var1'=> 'value1',
 'var2'=> 'value2',
);

test.php:

$config = include 'config.php';
$config['var2']= 'value3';
file_put_contents('config.php', '<?php return ' . var_export($config, true) . '; ?>');

Updated config.php now contains the following data:

return array(
 'var1'=> 'value1',
 'var2'=> 'value3',
);
Saghachi
  • 851
  • 11
  • 19
leepowers
  • 37,828
  • 23
  • 98
  • 129
  • Why not just `file_put_contents('config.php', '$config = ' . var_export($config));`? – Alix Axel Jan 06 '10 at 21:53
  • 2
    That would work to - either way finding a way to get it into a global variable. – leepowers Jan 06 '10 at 21:58
  • 2
    Oh, how could I have forgotten var_export()! – Tower Jan 07 '10 at 11:03
  • This is a very nice example in terms of creating config files that can be edited easily by PHP and by hand. It is however going to be slower in comparison to serialize and JSON etc. as PHP has to bytecode compile and interpret the file on each request – Inspire Jan 07 '10 at 12:36
  • 1
    With bytecode caching (such as APC, XCache, Zend, etc.) I would expect this method to be faster than decoding config strings. Config data rarely changes - so the accelerator can use a long cache lifetime for the file. When the config data is stored in a separate text file PHP has to parse that string every request via the JSON or unserialize decoders, plus open/close a filehandle each request. Of course, this is all academic without benchmarking. – leepowers Jan 07 '10 at 20:43
  • You have to remember though that APC, XCache, eAccelerator etc. are not default PHP extensions and are not installed on a surprising amount of servers, so in terms of speed you cannot assume these extensions are available. To be perfectly honest, I usually use config.php files for human-editable config files and they work fine on very high-traffic sites. Using a config.php file instead of json for example is not going to have an impact on the scalability of your site. But I was under the impression this question was about raw speed, so serialize is the fastest method that is always available. – Inspire Jan 08 '10 at 09:23
  • i'd like to add that var_export wont work with Objects unless you provide a __set_state method. So if you have Objects or StdObjects in your config use serialize or json. – ivoba Jun 25 '12 at 15:40
  • Can someone weigh-in to compare serialize-write-read-unserialize to " – nshew13 Dec 19 '13 at 16:48
  • According to the following link `serialize` is most performant with JSON being the fastest for very large data sets. As always be sure to benchmark your own code: http://techblog.procurios.nl/k/n618/news/view/34972/14863/cache-a-large-array-json-serialize-or-var_export.html#results – leepowers Dec 19 '13 at 20:02
  • about the first comment, @Alix Axel, the advantage of `return array` is that you can assign the data to whatever variable you want, like `"$my_desire_config_variable_name = include config.php"` but the comment one mode is just loading a `$config` variable name that can be duplicated in your scope or whatever – Saghachi Dec 05 '22 at 07:43
2

You should use serialize as opposed to json_encode:

http://docs.php.net/serialize

Inspire
  • 2,052
  • 15
  • 14
  • 3
    +1 for being the quickest form, but serialized PHP strings aren't easy on the eye. I wuold stick with something like JSON or investigate using YAML if you're trying to do something that is more user friendly than serialized PHP strings. – Andrew Noyes Jan 06 '10 at 19:58
  • 1
    I know serialize(), but I don't know any reason to use it over json_encode(). It's better for objects, but that's not needed for config data. JSON is also faster. – Tower Jan 07 '10 at 11:06
  • @Tower - JSON is primarily designed to work with javascript (JavaScript Object Notation) and the json functions require that the PHP JSON extension has been installed. serialize is a part of the PHP core and will always be available. I have benchmarked the two and in some tests json is faster and in others serialize is faster. Either way, the difference is negligible. If you want the config file to be editable by PHP and by hand then choose JSON or another format, otherwise you should use the native serialize function – Inspire Jan 07 '10 at 12:24
  • @Inspire I think you're confusing "PRIMARILY designed to work with javascript" with "ORIGINALLY designed to work with javascript". JSON has been widely adopted and is now a cross-platform standard. – voidstate Nov 06 '15 at 09:43
2

The way I store configuration is to put some variables in an external .php file and then when I want to use those files, I say:

<?php include("fileName"); ?>

And that would allow you to share configuration information across many pages. I am not, however, sure that this is the most efficient method, but it seemed to be the easiest to me.

zmbush
  • 2,790
  • 1
  • 17
  • 35
  • 8
    Tip: if you make the config file `return` its array, you can load the values like this: `$config = include('filename');`. – Geert Jan 06 '10 at 20:00
2

Whilst it's most likely overkill for what you're after, but what I tend to do is store the config data in a database using a PHP class to control the changes to the name/value pairs within. (i.e.: There's no direct DB access from outside this class.)

When a call is made to the PHP config class to change a value, this then writes out a standard PHP include file with all of various values defined on it.

As such, there's no load time performance hit when reading the config data and all config data can be changed within the database via a CMS module.

John Parker
  • 54,048
  • 11
  • 129
  • 129
  • These config data must be loaded before any database connections. One reason being that without config data, the application does not know how to connect to the database. – Tower Jan 07 '10 at 11:07
  • @Tower - Read what I said - the config data is written out to a standard PHP include file. (The database is only used to store the 'master' values that the include file is generated from.) If you wanted to store the database config info in there you'd have to bootstrap it somehow that said. – John Parker Jan 07 '10 at 16:07
0

I am pretty sure you are correct about the int/string values and yes JSON is a way but serialize and unserializing a string will be faster for speed optimization:

This link will help you:

http://docs.php.net/serialize

ninu
  • 890
  • 2
  • 10
  • 26
  • 1
    What makes you say serializing is faster? I did some testing, and I found out that JSON is about 20% faster than serialize(). – Tower Jan 07 '10 at 11:09
0

I use a database with a table called config or settings. The table has two columns:

name [varchar(255)]
value [varchar(255)]

This allows the easy storage of int's, float's, and short strings.

Then I create two functions, GetSetting and SetSetting. These store a row and retrieve a row, respectively. I find that this simplifies the storing of values tremendously.

Nathan Osman
  • 71,149
  • 71
  • 256
  • 361
  • 1
    These config data must be loaded before any database connections. One reason being that without config data, the application does not know how to connect to the database. – Tower Jan 07 '10 at 11:08
  • It's the same in my case. I just store the database config in something like dbconfig.php with $user = 'username', $pass = 'password', and so on. This way, I'm only storing enough to connect to the db and the rest is in the DB. – Nathan Osman Jan 07 '10 at 19:11
0

If you use require instead of include for the config file you will gain a little bit of performance. You can do this if you know that the config file will always be in place, or when you have your own mechanism for checking if it exists.