A primer on PHP namespaces
16th February 2012I know that there are a lot of posts now about namespaces in PHP 5.3. This is mine which is how I learnt how they work.
What are namespaces?
From the PHP manual:
namespaces are a way of encapsulating items
Hardly the most useful of definitions, but it's a starting point! A namespace is a way of grouping code that exists across multiple files without having a naming collision. That is, you can have the same named class in two different places if they are encapsulated within namespaces.
Of course the way that ZF1 solves this problem is with Extra_Long_Classnames which are obviously unique. Namespaces allow us to reference the classname by the important bit (the last section and not have to carry the meta data (where it lives) in every use of the class.
That is, namespaces allow us to:
Note that namespaces do not just affect classes. They also affect functions and constants.
Defining a namespace
There is a new keyword called namespace which is used to declare a namespace for a file. This is file-wide:
namespace Zend\Db\Statement; class Sqlsrv extends AbstractStatement { }
Note that we can have multiple sub-namespaces, separated by the backslash. When we extend the Sqlsrv class the extended class is within the namespace too, but not in the same file.
We can then use the class like this:
$stmt = new \My\Db\Statement\Sqlsrv();
You can have multiple namespaces in a file, but the first namespace must be the first line of code in the file.
Working within the same namespace
When you are working within the same namespace, then any unqualified functions and classes will be resolved to the current namespace. i.e:
namespace My\Db\Statement; function testSqlsrv() { $stmt = new Sqlsrv(); }
In this case, the SqlSrv class is in the namespace \\My\\Db\\Statement.
Namespace importing: the use keyword
We can import a namespace into a different file using the use keyword.
namespace My\Application; use My\Db\Statement; $stmt = new Statement\Sqlsrv();
Note that we don't use a leading \\ in the new statement as we are using a qualified namespace, not a fully-qualified one.
or you can import a specific class from a namespace;
namespace My\Application; use \My\Db\Statement\Sqlsrv; $stmt = new Sqlsrv();
It follows you can use multiple use statements:
use \My\Db\Statement; use \My\Db\Adapter; $stmt = new Statement\Sqlsrv(); $adapter = new Adapter\Sqlsrv();
You cannot do this though:
use \My\Db\Statement\Sqlsrv; use \My\Db\Adapter\Sqlsrv; $stmt = new Sqlsrv(); $adapter = new Sqlsrv();
as clearly PHP cannot resolve which Sqlsrv class to instantiate.
You can also alias namespaces. This allows us to reference a long namespace with a shorter name or to import two namespaces having the same name and give them different names.
use \My\Db\Statement\Sqlsrv as DbStatement; use \My\Db\Adapter\Sqlsrv as DbAdapter; $stmt = new DbStatement(); $adapter = new DbAdapter();
This also allows you to write code the focusses on the functionality of the class rather than the specific type. For example, we could start using the Mysqli versions of the statement and adapter by just changing the use statements.
The __NAMESPACE__ constant
The constant __NAMESPACE__ provides the current namespace name. In the global space it will be an empty string.
Namespace resolution
This bit is really important!
An unqualified class name is resolved in this order:
An unqualified function name has different rules:
This means that within a namespace'd file, you can do:
$date = date('Y-m-d');
but not:
$datetime = new DateTime();
Instead, you have to use:
$datetime = new \DateTime();
Conclusion
That's really all you need to know to use namespaces in a PHP application. They aren't so hard really.


