Was just wondering if anyone had a good system for storing / updating dynamic settings in php?
What i mean by dynamic is settings that change automatically by other scripts.
Currently we use a system that basically file_get_contents our settings php file, treats that as a string, changes settings and file_put_contents the updated settings.
It works but its a bit dirty. Any other recommendations where we can store / modify / pull these settings from? Mysql is NOT an option, we want to avoid the extra queries.
As an added bonus, some system that can share this data over multiple servers as many of these settings are used across multiple boxes. But i suppose we can deal with that seperatly.
Thx!
Things to keep in mind if you stick with a file-based approach:
Using a native parser
A parser written in C will most likely be quicker than one in PHP.
The two options that spring to mind are
Use a settings.php
file, that contains well-formed PHP code. One approach I've used in the past is having a file that looks like
<?php return
array(
'key' => 'value'
);
This file can be include
-d one or more times, and the include
statement will return the configuration array. When you're writing the new settings, use var_export()
to get valid php code.
The other approach is using a settings.csv
file. Read using fgetcsv()
, write using fputcsv()
.
Avoiding "partial" saves
To avoid a partial file being read while the settings are being updated, first write the new settings to a temporary file, then move this file to the setting file location (preferrably using mv (1)
on *nix).
You really don't want to store dynamic data in files, particularly if its common data. PHP does not have the sophisticated file locking semantics to support this. If you know what you're doing you could implement your own advisory locaking system on top of PHP - but if you knew what you were doing you wouldn't be asking the question.
Mysql is NOT an option, we want to avoid the extra queries
Oh dear.
MySQL is probably the best option given the information you've provided. And if you've load problems on your database, trying to use different substrates for your data is not going to help.
Indeed, I would recommend implementing the storage and retrieval of values within a custom database bound session handler (and enabling sessions for all requests).
There are other tools you could use - nosql databases and memcache being obvious candidates - but they make less sense when you've already got a MySQL instance available.
(shared memory and the APC variable store have the same issues as file based storage)
If you don't want to use MySql I think what you are doing right now is the best solution, any kind of properties/ini file writing system would be a lot more expensive and will not solve the concurrent access issues. To eliminate the issue I suggest you write the updated file to a temporary file in the same folder delete the old settings.php and rename the temp file to settings.php. there is still a small chance that a request be made just after settings.php is deleted and before temp file is renamed which can be handled by doing something like this when you include the file:
if( file_exists( 'settings.php' ) ) {
include( 'settings.php' );
} else {
/* ... wait 100 miliseconds or so and try again... do this a few times and then fail ... */
}
this should be quite safe.
I'd say ini files. parse_ini_file()
(http://php.net/manual/en/function.parse-ini-file.php) is an excellent function which takes care of the reading and the answer to writing is right here: create ini file, write values in PHP
For this purpose we use this: http://projects.jgotti.net/projects/simplemvc/browse/trunk/includes/fx-conf.php
it read and write to simple text files that contains key = values pairs.
parse_conf_file can load the confs as defined values or return an associative array of key values. Write_conf_file allow you to overwrite only the needed values by passing an array of key values as parameters.
If you have allow_url_fopen set to true then you can load the configuration file from another server without problem.
Hope this help