How to Use PHP Namespaces, Part 3: Keywords and Autoloading

Contributing Editor

PHP namespacesIn parts 1 and 2 of this series, we looked at PHP namespace basics, the use operator, and name resolution. In this final article we discuss some of the more advanced namespace options.

The __NAMESPACE__ Constant

__NAMESPACE__ is a PHP string that always returns the current namespace name. In the global space it will be an empty string.


<?php
namespace AppLib1;
echo __NAMESPACE__; // outputs: AppLib1
?>

The value has obvious benefits during debugging. It can also be used to dynamically generate a fully-qualified class name, e.g.


<?php
namespace AppLib1;

class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}

$c = __NAMESPACE__ . '\MyClass';
$m = new $c;
echo $m->WhoAmI(); // outputs: AppLib1MyClass::WhoAmI
?>

The namespace Keyword

The namespace keyword can be used to explicitly reference an item within the current namespace or a sub-namespace. It is the namespace equivalent of self within classes:


<?php
namespace AppLib1;

class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}

$m = new namespaceMyClass;
echo $m->WhoAmI(); // outputs: AppLib1MyClass::WhoAmI
?>

Autoloading Namespaced Classes

One of the best time-saving features of PHP 5 is autoloading. In global (non-namespaced) PHP code, a standard autoload function could be written:


<?php
$obj1 = new MyClass1(); // classes/MyClass1.php is auto-loaded
$obj2 = new MyClass2(); // classes/MyClass2.php is auto-loaded

// autoload function
function __autoload($class_name) {
	require_once("classes/$class_name.php");
}
?>

In PHP 5.3, you can create an instance of a namespaced class. In that situation, the fully-qualified namespace and class name is passed to the __autoload function, e.g. the value of $class_name could be “AppLib1MyClass”. You could continue to place all your PHP class files in the same folder and strip the namespace from the string, however, that could result in file name clashes.

Alternatively, your class file hierarchy could be organized in the same way as your namespace structure. For example, a MyClass.php file could be created in the folder /classes/App/Lib1:

/classes/App/Lib1/MyClass.php:


<?php
namespace AppLib1;

class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}
?>

A file in root folder could then use the following code:

myapp.php:


<?php
use AppLib1MyClass as MC;

$obj = new MC();
echo $obj->WhoAmI();

// autoload function
function __autoload($class) {

	// convert namespace to full file path
	$class = 'classes/' . str_replace('\', '/', $class) . '.php';
	require_once($class);

}
?>

Explanation:

  1. The class AppLib1MyClass is aliased as MC.
  2. new MC() is translated to new AppLib1MyClass() during compilation.
  3. The string “AppLib1MyClass” is passed to the __autoload function. This replaces all namespace backslashes with file path forward slashes, and modifies the string so the file “classesAppLib1MyClass.php” is loaded.

I hope you found this series of PHP namespace articles useful. Will you be namespacing in your PHP code?

See also:

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Mihai

    I think the require_once will be more faster then use & __autoload.

  • http://www.optimalworks.net/ Craig Buckler

    @Mihai
    Undoubtedly, a list of require_once() statements will be faster than autoloading the same list of files.

    However, it’s not necessarily true for larger applications. The require_once method means you must load every file even if you do not need it. For example, a CMS showing a page won’t need to check user login credentials so the ‘User’ class is never required. Autoloading means that PHP never fetches the ‘User’ file.

    Autoloading is also safer (you don’t need to remember the requires), less time-consuming, and results in fewer lines of code. The speed difference will be negligible in most cases.

  • http://www.cybergeeksoftware.com/ CGSS-CyberGeek

    @Mihai: Also… cleaner code :) (In my opinion)

  • http://www.mikehealy.com.au cranial-bore

    I did find this series useful. Hopefully real world, shared webhosting, PHP5.3 isn’t too far off. I’ll have to read up on compatibility to guage how long upgrades are likely to take.
    I think many open source projects will be slow to implement features such as name spacing. WordPress for example is still PHP4 compatible, probably will be for 10 more years.

  • http://www.optimalworks.net/ Craig Buckler

    @cranial-bore
    I’m glad you found it useful.

    I agree that PHP4-compatible applications such as WordPress are unlikely to add new 5.3 features in the near future (even though WP would benefit from namespacing more than most).

    However, if you’re starting a major new PHP project today, then I’d recommend namespacing your code.

  • http://fdd.no-ip.com utahcon

    @Craig Buckler
    “Autoloading is also safer” – How do you figure? I have never seen an instance where Autoloading is safer. Autoloading a lazy developers tool, and it most often leads to more confusion than required.

    Furthermore when possible you should use a require() versus require_once() as require_once() requires php to look through the already loaded code and see what it does and doesn’t have before loading your file. Unless you are in an instance where it is truly possible you will load the same file twice you should avoid require_once.

    All that aside… Namespacing is neat. Honestly though I only see this as another naming convention that isn’t going to add a lot to the realm of PHP. Namepspacing won’t stop all the conflicts, but it will help.

  • Greg Beaver

    First of all, in every example, require_once should be include. The __autoload is only called once, so the _once is an unnecessary performance hog with no benefit.

    As to the performance of autoload, facebook.com uses autoload in their code base to improve performance for pages that have a large number of possible execution paths. Last I checked, facebook handles high volume just fine.

    use does not affect performance of either autoload or require_once, because use is a compile-time process.

    In addition, other factors affect performance more than the choice of require_once vs. autoload, such as the presence of an opcode cache, the kind of code in the autoload, and the include_path.

    The benefit of the approach outlined is that it is flexible. As shown by multiple indepedent benchmarks, the fastest way of loading an individual file is to use the include (not require, not include_once, not require_once) statement with absolute paths. If your code is designed with autoload, and a few key components *are* loaded on every execution, one can simply include those directly with a full path in the bootstrap code, and let the other fragments that are only occasionally used be loaded by autoload. This strategy results in faster code if (and only if) other factors are in place, such as a single-element include_path that does not begin with “.”, an opcode cache is present, and so on.

  • Greg Beaver

    facebook.com uses autoloading to improve performance in some of their code. It is useful in situations where the number of execution branches is quite high. Designing your code to be autoloaded also gives you the flexibility to later decide to use absolute paths with include, which is the fastest way to load a single file, especially when paired with an opcode cache.

    Of course, if you rely upon include_path at all, the value of include_path can have a significant effect on performance, so there are many factors.

    The important thing is that autoload has no intrinsic problems and is a viable solution to the problem of loading dependencies at the most performance-intensive level.

  • http://www.optimalworks.net/ Craig Buckler

    Thanks for all the comments.

    It’s a good point about replacing require_once. The __autoload function is only called if a class cannot be found, so the file has to be loaded. You could use require if you wanted to capture the error in __autoload, but the ‘new Class()’ statement would fire it otherwise. However, performance gains are likely to be negligible in all but the largest/complex PHP apps.

    @utahcon
    By “safer” I mean less prone to human error. A list of require statements must be maintained; you need to remember to add, remove or alter them as necessary. Coding’s hard enough — let PHP handle the donkey work.

  • GMic

    Thanks for this great article! It was worth reading and learning about namepaces in PHP. Official documentation sucks at time (Or maybe it’s me who’s slow learner and need easy and concrete examples).
    I love autoloading and with namespaces it will be easier than before.
    With namespaces we are done with long class names like class Toto_Tata_DOThis_DOThat_LongName extends Toto_Tata_DOThis_DOThat_LongName_Abstract implements EVENLongerInterfaceClassName and having to write something like this Toto_Tata_DOThis_DOThat_LongName::staticFunction($params,...) to access a class static function. Ok we will have to write something like TotoTataDOThisDOThatLongName but with namespace Aliases it can get shorter in our own library using our own namespace it’s up to us!

  • Carl Anderson

    In your example every class method will execute in its own namespace. How is this helpful? Seems like it causes more problems than it solves.