The patch: PHP5 packages (a.k.a. "namespaces") - basics

at 2004-12-02 in PHP5 by friebe (0 comments)

When asked in a reader's poll in George Schlossnagle's blog what people thought PHP5 was missing, request #1 was namespaces (or packages), or short: A way to avoid name clashes between classes.

With SPL and the new dom extension, the number of builtin classes has risen enormously (4.3.8: 21, 5.0.0: 55, 5.1.0-dev: 63), with a lot of good names taken, Iterator, Exception, Reflection and Traversable, to name only the most eminent. Any person having a halfway decent object-oriented framework will maybe have used these names already, asking him- or herself: When will it stop? Which class name will pollute the global namespace (the only in current PHP5 releases) next? How many more classes will I have to rename (and introduce API breaks with it)?

This is exactly the case with the XP framework. As you know, we have had Exception and Iterator for a long long time. Both of these are defined as built-in classes as of the first release of PHP5.

One solution to that is naming all your classes with pseudo-namespace prefixes, as Sebastian Bergmann does in his PHPUnit2 PEAR package (PHPUnit2_Extensions_ExceptionTestCase being an example). This has the following disadvantages:

  1. The framework inevitably gets unusable without an IDE supporting tab completion
  2. The underscore does not relate to anything. It represents a fictive hierarchy, but what about folks whose coding styles require them to use underscores in class names?
  3. It looks very *very* ugly. I would not want to present anyone with a framework where the Date class is not named Date but Framework_Name_Date. Would you want to use this framework?

Now the solution should be clear: PHP needs some kind of namespacing feature.

The patch implements packages (alongside with many more features, such as annotations, an exception interface, operator overloading, etc.).

Basic syntax:
package [name] {
class ...
}

A class within a package is actually named <package>~<classname>. The tilde is not ambiguous as it is currently allowed only left of an expression, being a binary operator there. You might know this from error_reporting(E_ALL & ~E_NOTICE);

Whithin a package you may ommit the fully qualified name in favor of the "package local" name. To clarify:
<?php 
class Test { }

package PHPUnit
{
class Test { }
class TestCase extends Test { }
}
?>

The class "TestCase" in the package PHPUnit extends the class Test from the same package, not the "global" one. If you wanted to do this, you'd have to write:

class TestCase extends main~Test { }

instead - "main" is the indicator a class is declared outside of any package (such as the built-in class Exception, for instance). Thus, packages may not be called "main".

To add some more sugar, package names themselves may again contain the tilde (~). The following:
<?php 
package de~schlund~webservices
{
class ServiceLocator {
}
}
?>

would make the class' fully qualified name be de~schlund~webservices~ServiceLocator.

As I said before, we wouldn't be any better with this if it wasn't for import. As the name suggests, this language construct imports classes from packages into the global namespace (or into another package, if you like). Thus, instead of having to type the afforementioned long name, the class can be imported as follows:

import de~schlund~webservices~ServiceLocator;

This makes the class available with its short name "ServiceLocator".

More to come in future "the patch" showcases: Importing into packages, aliasing, autoload, conditional and variable import, and the gory implementation details.



Subscribe

You can subscribe to the XP framework's news by using RSS syndication.


Categories

News
General
PHP5
Announcements
RFCs
Further reading
Examples
Editorial
EASC
Experiments
Unittests
Databases

Related

Find related articles by a search for «The».