Best practices when using XML for PHP configuration?
I was planning to use an XML document to store configuration for my next PHP project, in a format similar to ASP.NET Web.Config files. Just two concerns:
- Cannot be served to the browser.
- Must be viable in shared hosting.
The best way I could think to prevent it from being served is to change the filetype to PHP and add the following comment:
<?xml version="1.0" ?>
<!-- <?php if(!defined('FW_LOADED')){ exit; } ?> -->
<configuration>
....
</configuration>
This is working fine, but I don't feel like it is the best solution.
Has anybody else used XML to store configuration for a PHP project? What are some good alternate solutions (instead of putting a comment at the beginning of the file which exits the script if a constant is not defined)?
Update:
Changed the question title to better reflect what I'm looking for. Sorry for the misleading original question title. Using XML for configuration is not the question. I am asking for the best practices when using XML for configuration. Please stop suggesting that I use arrays or INI files...
I want the config file to be as easy as possible to use, even for non php developers. I chose XML because it is language neutral. I am already using SimpleXML to parse the config (partially). I am also not worried about compiling or making it faster because that can be achieved using memcached or other utilities.
The best solutions so far are:
- Moving it out of web root.
- Possible, but would like to keep the config as close as possible to the application.
- Using htaccess to hide the config file.
- I don't want to risk the chance that someone breaks the .htaccess file, leaving the config file exposed.
I would like to hear from someone who has experience using XML for configuration settings in an application, and how they prevent the config file fr开发者_Python百科om being served.
This is what I usually do for config files - actually, this is more of the basic setup, usually it's wrapped in custom class that combines multiple config files into a single config object:
config.php:
return array(
'config1'=> 'config1value',
'config2'=> 'config2value',
);
some_page.php:
$config= include('config.php');
if ($config['config1'])
...
The config is stored as a PHP array in a PHP file file, so it is parsed by the PHP engine and never returned to the browser. (You can protect the config files further by storing them outside the web root, setting a mod_rewrite rule to prevent serving config files/directories, etc.)
Storing configuration info in an XML file adds the overhead of parsing an XML file to every request. Database storage of advanced configuration data is nice, but also costly (obviously, the database won't be storing your database connection info, so you'll still need a config solution for some basic info). Config data is usually very static (written rarely / read every request), so it's ripe caching via memcached or other cache schemes.
Either put them outside the document root or if you can't or won't then restrict it from being accessed externally, just use Apache mod_rewrite. For example:
RewriteEngine On
RewriteRule ^config.xml [R=404,L]
PHP has multiple libraries for reading/writing XML so there are no issues there. If it's relatively simple (flat) data consider using INI files instead. PHP has parse_ini_file()
as an inbuilt function and anything on .Net will read .ini files.
I think the best way to prevent files from being accessed from outside is to store them outside the root web folder.
I wasn't looking for alternatives to an XML config solution I was looking for alternatives to the way I prevent the config file from being served. I should have phrased my question better.
The best solutions so far are to move the file out of web root or use use htaccess. I already decided not to do either of these before posting here, I should have mentioned that as well.
Nobody has said anything bad about using a exit
statement at the top of the XML file so I guess I will keep doing that, for now.
If you can put it outside the public folder, that would be the optimal solution. Other than that, the mod_rewrite specified by cletus is a good option.
When thinking about application config there is a question to answer who is going to manage it. If it is going to be managed by you as developer and not expected that some third party be involved the best way is to keep them in PHP arrays since at the end you always end up converting any format to some kind of object or array. This way you are protected since unless you print it it will be parsed as PHP and not shown in output.
PHP now has convenient SimpleXML http://php.net/manual/en/book.simplexml.php lib to manipulate XML data. Although, I would prefer YAML http://www.yaml.org/ as config language since it is not so verbose as XML and have nice means of composing hierarchical config files which are usually needed when you have multiple development environments like dev
, test
, live
. There are various PHP libs for working with YAML files as well.
Since configs are included in every request you could cache them somehow in memory like mamcache, apc or similar in order not to read from the disk on every request.
Regarding protecting the access to the file that is not parsed by PHP interpreter .xml or .yml as others suggested keep it out of the serving folder, or use rewrite rules.
XML configs are slow. You will need to compile them to PHP, I think. Or use PEAR_Config to simplify the job. As to preventing access from browser... The simple, Apache directive together with "Order allow,deny deny from all" will do. Check apache docs.
You can store the xml file outside the web root, in which case it will be impossible to access without being logged into the computer's filesystem, or you can use .htaccess (or the IIS equivalent) to block access to your config directory.
Shared hosting should allow both of these scenarios.
I would suggest using normal arrays for configurations. Have a file with:
$conf['item1'] = 'value';
$conf['item2'] = 'value2';
etc..
And then have a file call the file where all those $conf items are defined and add the paths or the server url or something and save all that data to a file using var_export.
In the end you will have a 'compiled' file which you can easily call.
Note: var_export only gets the contents of the array, not it's name nor the end ';'
精彩评论