Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to save config variables in a PHP web app?

I often switch between .NET and PHP development. With ASP.NET sites I save configuration information (e.g. connection strings, directories, application setting) in the web.config file which is appropriately protected and easy to access the values, etc.

In PHP, I solve this with a class that has static methods for each variable:

class webconfig {     public static function defaultPageIdCode() {         return 'welcome';     } } 

The file is included by the app variables are accessed with a one-line:

$dp = webconfig::defaultPageIdCode(); 

And since PHP isn't compiled, it is easy to telnet in and change a value for a website anyway, so this solution works fairly well and gives me these two advantages:

  • I can add logic to a config variable without breaking its interface with the application
  • these config variables appear as intellisense in my e.g. Eclipse, NetBeans, etc.

But I can imagine there are other ways people solve saving web config settings in PHP which may have other advantages.

Especially those who have experience with a number of PHP frameworks, what are other ways of saving config variables and their advantages and disadvantages?

like image 469
Edward Tanguay Avatar asked Sep 16 '10 07:09

Edward Tanguay


People also ask

Where can get configuration variables be stored?

The configuration variables are stored in the Moodle database, in the "config" table. They are loaded from there into the $CFG variable when one of the Moodle scripts starts up. If you want to have a look at $CFG, you could create a script file called "show-cfg.

Where is config php stored?

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.


2 Answers

I've decided to list all known methods along with their advantages and disadvantages.

I've marked this answer as a community wiki so collaboration is easier.


Global Constants

Assigning:

  • define('CONFIG_DIRECTIVE', 'value');

Accessing:

  • $object = new MyObject(CONFIG_DIRECTIVE);

Advantages:

  • Has global scope.
  • Autocompleted by most IDEs.
  • Has an agreed upon naming convention (UPPERCASE_UNDERSCORE_SEPARATED).

Disadvantages:

  • Directives cannot contain arrays (prior to v7.0.0).

Special Notes:

  • Cannot be reassigned.

Alternate Syntax Files

For example: XML, INI, YAML, etc.

Assigning:

  • Simply edit the file in it's specific language. (For example, for INI files: config_directive = value.)

Accessing:

  • The config file needs to be parsed. (For example, for INI's: parse_ini_file().)

Advantages:

  • Most likely has a syntax more suited for a config file.

Disadvantages:

  • Possible overhead of accessing and parsing the file.

Array

Assigning:

  • $config['directive'] = 'value';

Accessing:

  • The cleanest method of accessing configuration values using this method is to pass the required values to the object that needs them on creation, or pass them to your container object and let it handle passing them out internally.
    • $object = new MyObject($config['directive']);
    • $container = new MyContainer($config);

Advantages:

  • Directives can be arrays.

Disadvantages:

  • No autocompletion.

Special Notes:

  • Variable collisions can occur. If this is a concern, name your array appropriately to avoid them.

Class

Assigning:

  • There are many different class based implementations.
    • Static class.
      • myCfgObj::setDirective('DIRECTIVE', 'value');
    • Instanced class.
      • myCfgObj->setDirective('DIRECTIVE', 'value');

Accessing:

  • Again there are various class based implementations.
    • Static class.
      • $object = new MyObject(myCfgObj::getDirective('DIRECTIVE'));
    • Instanced class.
      • $object = new MyObject(myCfgObj->getDirective('DIRECTIVE'));

Advantages:

  • Can be autoloaded.

Disadvantages:

  • Tends to be a bit verbose.
  • Can be hard to maintain if a container class is not being used.
like image 112
6 revs, 4 users 67% Avatar answered Oct 13 '22 22:10

6 revs, 4 users 67%


I tend to use a Settings static class in PHP, this is because

  • It has a global scope.
  • You can enable/disable changes to protected configs.
  • You can add any settings during anywhere within runtime.
  • You can make the class automated to fetch public configs from a file/database.

Example:

abstract class Settings {     static private $protected = array(); // For DB / passwords etc     static private $public = array(); // For all public strings such as meta stuff for site      public static function getProtected($key)     {         return isset(self::$protected[$key]) ? self::$protected[$key] : false;     }      public static function getPublic($key)     {         return isset(self::$public[$key]) ? self::$public[$key] : false;     }      public static function setProtected($key,$value)     {         self::$protected[$key] = $value;     }      public static function setPublic($key,$value)     {         self::$public[$key] = $value;     }      public function __get($key)     {//$this->key // returns public->key         return isset(self::$public[$key]) ? self::$public[$key] : false;     }      public function __isset($key)     {         return isset(self::$public[$key]);     } } 

Then within your runtime, if you loaded this file first, followed by your database config file, your database config file would look like so:

<?php Settings::setProtected('db_hostname', 'localhost'); Settings::setProtected('db_username', 'root'); Settings::setProtected('db_password', ''); Settings::setProtected('db_database', 'root'); Settings::setProtected('db_charset', 'UTF-8'); //... echo Settings::getProtected('db_hostname'); // localhost //... Settings::setPublic('config_site_title', 'MySiteTitle'); Settings::setPublic('config_site_charset', 'UTF-8'); Settings::setPublic('config_site_root', 'http://localhost/dev/'); 

As you can see the we have a method __get that should only be allowed to grab public variables, An example of why we have this is as follows:

$template = new Template(); $template->assign('settings', new Settings()); 

Regardless the fact that we have used this object as a static object, the values should still stand so within the template you can now do, lets say.

<html>     <head>         <?php echo isset($settings->config_site_title) ? $settings->config_site_title : 'Fallback Title'; ?>     </head> </html> 

And this will only allow you to have access to the public data during the initialized period.

This can get a lot more complex but more system friendly, some examples:

  • A loadConfig method to automatically parse a config file, xml, php, yaml.
  • If you register an shutdown_function you can auto update the database with new settings.
  • You can auto-populate the class with config from that database.
  • You can implement iterators to make it compatible with looping.
  • Lots more.

This too me is by far the best methods to complete this job.

like image 32
RobertPitt Avatar answered Oct 13 '22 22:10

RobertPitt