__autoload vs class configuration
Posted: Tue Jun 03, 2008 8:34 am
I've been messing about with __autoload() which turns out to be surprisingly effective.
I had heard rumors saying that __autoload() was terribly inefficient and caused all sorts of problems. But it's working pretty good for me so far.
What I would like to share here, is a problem (and solution) related to __autoload(), although you may also find this useful for PHP programming in general.
To the point:
Most people, when they create a class library, the library comes with a configuration file of some sort - typically, this comes in the form of a script that you copy and edit, which is filled with define() statements:
This is all fine and works well.
However, as I was experimenting with autoloading, I came across a problem. Normally, I used to have a main file (header.php or something similar) that you're supposed to load, which includes the configuration file and the core classes.
But with autoload, the configuration file is no longer loaded. The impulsive way to sort this out, is to just add require_once() statements to the top of every class file, to ensure the configuration file is always loaded whenever a class autoloads.
Trouble is, the net result of that, is even more unnecessary include/require statements than you had before you started autoloading.
So, I thought, how can I get the class configuration to autoload?
Simply, my configuration file now looks like this:
Because my configuration is contained in a class, it can autoload - and an added benefit is, the code that referes to these configuration values becomes a bit more legible, since MyClassConfig::PATH actually tells you where to look for the configuration value.
So, I thought, what is the performance penalty for adding and loading the extra class, and performing the static class resolution every time you need a configuration value?
I created two simple test scripts.
The classical way:
and what I call the classy way 
The perhaps surprising result, is that using a class instead of flat define()'s is approximately twice as fast!
Nope, declaring the class, and resolving the constants, does not result in any performance penalty whatsoever, quite the contrary.
The explanation is, that regular define()'d constants exist in the global PHP namespace, which is already littered with built-in constants, constants defined by various modules, etc. - whereas your own isolated little island configuration class has a much smaller scope to search for the necessary constant. Hence, faster.
Nice!
Whether you use (or like) autoloading, this is definitely not a bad technique. I would highly recommend using classes as configuration files in the future, as this results in a cleaner namespace, more legible code, and, apparently, even a minute performance bonus!
I had heard rumors saying that __autoload() was terribly inefficient and caused all sorts of problems. But it's working pretty good for me so far.
What I would like to share here, is a problem (and solution) related to __autoload(), although you may also find this useful for PHP programming in general.
To the point:
Most people, when they create a class library, the library comes with a configuration file of some sort - typically, this comes in the form of a script that you copy and edit, which is filled with define() statements:
Code: Select all
define("MYCLASS_PATH", "/var/www/someapp/files");
define("MYCLASS_URL", "http://www.somewhere.com/something.php");
// etc.However, as I was experimenting with autoloading, I came across a problem. Normally, I used to have a main file (header.php or something similar) that you're supposed to load, which includes the configuration file and the core classes.
But with autoload, the configuration file is no longer loaded. The impulsive way to sort this out, is to just add require_once() statements to the top of every class file, to ensure the configuration file is always loaded whenever a class autoloads.
Trouble is, the net result of that, is even more unnecessary include/require statements than you had before you started autoloading.
So, I thought, how can I get the class configuration to autoload?
Simply, my configuration file now looks like this:
Code: Select all
abstract class MyClassConfig {
const PATH = "/var/www/someapp/files";
const URL = "http://www.somewhere.com/something.php";
// etc.
}So, I thought, what is the performance penalty for adding and loading the extra class, and performing the static class resolution every time you need a configuration value?
I created two simple test scripts.
The classical way:
Code: Select all
$start = microtime(true);
define("CONFIG_0", "0");
define("CONFIG_1", "1");
define("CONFIG_2", "2");
define("CONFIG_3", "3");
define("CONFIG_4", "4");
define("CONFIG_5", "5");
define("CONFIG_6", "6");
define("CONFIG_7", "7");
define("CONFIG_8", "8");
define("CONFIG_9", "9");
echo CONFIG_0."<br/>";
echo CONFIG_1."<br/>";
echo CONFIG_2."<br/>";
echo CONFIG_3."<br/>";
echo CONFIG_4."<br/>";
echo CONFIG_5."<br/>";
echo CONFIG_6."<br/>";
echo CONFIG_7."<br/>";
echo CONFIG_8."<br/>";
echo CONFIG_9."<br/>";
echo number_format(1000*(microtime(true)-$start),8);Code: Select all
$start = microtime(true);
abstract class Config {
const _0 = "0";
const _1 = "1";
const _2 = "2";
const _3 = "3";
const _4 = "4";
const _5 = "5";
const _6 = "6";
const _7 = "7";
const _8 = "8";
const _9 = "9";
}
echo Config::_0."<br/>";
echo Config::_1."<br/>";
echo Config::_2."<br/>";
echo Config::_3."<br/>";
echo Config::_4."<br/>";
echo Config::_5."<br/>";
echo Config::_6."<br/>";
echo Config::_7."<br/>";
echo Config::_8."<br/>";
echo Config::_9."<br/>";
echo number_format(1000*(microtime(true)-$start),8);Nope, declaring the class, and resolving the constants, does not result in any performance penalty whatsoever, quite the contrary.
The explanation is, that regular define()'d constants exist in the global PHP namespace, which is already littered with built-in constants, constants defined by various modules, etc. - whereas your own isolated little island configuration class has a much smaller scope to search for the necessary constant. Hence, faster.
Nice!
Whether you use (or like) autoloading, this is definitely not a bad technique. I would highly recommend using classes as configuration files in the future, as this results in a cleaner namespace, more legible code, and, apparently, even a minute performance bonus!