PHP Configuration Storage
Ways to store confi开发者_StackOverflowguration for a Web App written in PHP?
I've seen people use .ini, basic .php, etc. Also,define()
or simple global variables?
Most information as you can find.
Also, are databases good methods of storing configuration?There is no “Best Way (tm)” to store your application configurations. It really all depends on your application, the kind of configurations, how often they can/need to change, and how easy you want to make it to change them.
Some people use a full singleton (or static) Config
class for their application. Which looks something like this (with varying levels of complexity):
<?php
class Config
{
protected static $config = array();
private function __construct() {} // make this private so we can't instanciate
public static function set($key, $val)
{
self::$config[$key] = $val;
}
public static function get($key)
{
return self::$config[$key];
}
}
This is handy because you can call it wherever you want in your application with Config::set()
or Config::get()
. You then have a central place that your entire application is configured, and you can make it as complex or as simple as you like. You can back things up to the database, memcached, etc, whatever.
Which brings me to the next thing. Using the database is fine for things that need to be able to be changed on the fly and don't necessarily have to have an “initial setting”. An example would be site application customization features (eg. currency, background color, header image, etc). The problem here is, you have to load that every time a page is loaded in your application. So to solve that, you can use a middle layer caching technology (like memcached if you like). That would be fast, way faster than the database, but still adds overhead because you have to load it on every page load.
The fastest way, and consequently the “hardest” to change, is to use a config.php
file or the like. This file would have $_GLOBALS
array key definitions, or define()
's for values that you need access to throughout your application. This is fast because it's included in the request and hard coded in PHP, so all PHP has to do is interpret the file - no network IO or any added overhead other than the minimal overhead of including a file into your script. The things you’d store in these PHP files are things like your MySQL connection credentials, web service connection credentials, etc.
For an application which has a lot of users and a lot of customizations, you’ll probably need to deploy a ‘hybrid’ of the methods, or come up with your own. For something that is just a standard application deployment, you might be able to get away with a very simple config.php
type approach.
I don't think there is a best way, every method has its advantages and disadvantages. Just make sure the configuration file (especially when it contains passwords) is not available in the public directory, but somewhere private.
Storing the configuration in a database might work, but you'd still need to store the database connection information somewhere to get the connection. I've personally never been a fan of this method. The only advantage would be easy online changing the values of configuration items, or having configuration on a user-level for example.
Using define();
will create constants, of which you cannot change the value during runtime. In some cases this works, in other cases this doesn't. If you want your configuration to be available everywhere - in every scope - you could consider reading the configuration into a class (maybe a Singleton Pattern?) so that you can access the configuration values everywhere.
I've used a included php file, .ini files, XML files, and JSON files for configuration, personally I prefer to avoid .php configuration files as I share my configuration files amongst multiple languages for different applications within my web applications, and stick with the other 'standards'.
.ini is not good way to store configs, as webserver is going to display it to public. Don't do it.
Store configs on .php file. You can use global variables, define() or normal variables. Define is usually the best one to go with. For more security place it outside of the public directory.
I usually place database settings on config.php and all the dynamic settings on a database. All settings that don't change much are usually good to be placed to config file. Like paths, etc.
As actually @Roger Ng pointed out, the accepted answer actually doesn't work. The problem there is that you can't use $this
in a static method.
PHP: Static Keyword - Manual
I've thought of handling this in a following manner:
class Config {
protected static $config=array();
private function __construct(){}
public static function set($k,$v){
self::$config[$k]=$v;
}
public static function get($k){
return self::$config[$k];
}
public static function init($a){
self::$config=$a;
}
public static function merge($a){
self::$config=array_merge(self::$config,$a);
}
}
I'm using function Config::init()
to create an default config to fall back to, and Config::merge()
function to merge the default configs with for example a production values.
So here my default_config.php might look like following:
Config::init(array(
'key' => 'value',
'key2' => 'value2',
));
And my config.php something like following:
Config::merge(array(
'key' => 'newvalue',
'key3' => 'value3',
));
In the actual code I'll fetch my config values in the exact way it's done in the accepted answer, by writing Config::get('key')
.
IMO, it makes most sense today to store your config data in a JSON file.
Some advantages of JSON :
- native support in many programming languages
- easy to read for humans
- easy to read for machines
- small filesize
Example code :
Json file :
{
"version" : "0.0.1",
"title" : "My first web app",
"database" : {
"host" : "localhost",
"name" : "DB",
"user" : "JJ",
"password" : "Passw0rd"
}
}
PHP class :
namespace App;
class Config {
protected static $config = array();
public static function load($filename) {
static::$config = json_decode(file_get_contents($filename), true);
}
[...]
}
Loading your Json file :
\App\Config::load('myConfigFile.json');
This is what I do.
First, I define a generic Dataset
class that I can use use for global datastorage :
<?php
namespace MyNamespace\Core;
class Dataset {
protected static $_data = array();
public static function set($key, $value) {
static::$_data[$key] = $value;
}
public static function get($key) {
return static::$_data[$key];
}
public static function remove($key) {
unset(static::$_data[$key]);
}
}
?>
Then, I define a Config
Class that extends this, where I can add methods specific to this class.
<?php
namespace MyNamespace\Core;
class Config extends Factory {
protected static $_data = array();
}
?>
Note that it's important to add the rule protected static $_data = array();
to the Config
class or any other child classes if you don't want them to share the same array.
I have tweaked the code by James & Zachu. Here's my implementation. When a value is searched and if exists it is returned otherwise an empty string is returned. That way no notices will be shown. There's a delete method. comments, and code formatting.
<?php
/*
* This file can be used to store config values. It is based on discussion below.
* @see https://stackoverflow.com/questions/5923778/php-configuration-storage
* @author https://stackoverflow.com/users/2632129/james
* @author https://stackoverflow.com/users/3173125/zachu
* @author Slavi Marinov | http://orbisius.com
*/
class App_Config {
protected static $config = array();
/**
* Do not instantiate this class
*/
private function __construct() {}
/**
* Initializes or resets the config if nothing is supplied
* App_Config::init();
* @param array $a
*/
public static function init($a = array()) {
self::$config = $a;
}
/**
* App_Config::get();
* @param str $k
* @return mixed
*/
public static function get($k) {
return empty(self::$config[$k]) ? '' : self::$config[$k];
}
/**
* Sets a value
* App_Config::set();
* @param str $k
* @param mixed $v
*/
public static function set($k, $v) {
self::$config[$k] = $v;
}
/**
* Removes a key
* App_Config::remove();
* @param str $k
* @param mixed $v
*/
public static function remove($k) {
unset(self::$config[$k]);
}
/**
* Removes a key
* App_Config::delete();
* @param str $k
* @param mixed $v
*/
public static function delete($k) {
self::remove($k);
}
/**
* App_Config::exists();
* @param str $k
* @return bool
*/
public static function exists($k) {
return isset(self::$config[$k]) ? true : false;
}
/**
* App_Config::merge();
* @param str $k
* @return array
*/
public static function merge($a) {
self::$config = array_merge(self::$config, $a);
return self::$config;
}
}
精彩评论