Embrace PHP namespaces

  Status: draft
  • Created: 2007-09-02 17:18:35+0200
  • Categories: <core>
  • Author: friebe
  • Contributors: kiesel

Scope of Change

Adapt to PHP namespaces once they're released officially.


Rationale

Once and for all remove the need to prefix classes.

Functionality

All XP classes will be namespaced.

Syntax example #1

This is an abbreviated version of the lang.Enum class:

  namespace lang;

class Enum extends Object {

public static function valueOf(XPClass $class, $name) {
if (!$class->isEnum()) {
throw new IllegalArgumentException(
'Argument class must be lang.XPClass<? extends lang.Enum>'
);
}
try {
return array_values($class->_reflect->getStaticProperties());
} catch (ReflectionException $e) {
throw new IllegalArgumentException($e->getMessage());
}
}

public final function __clone() {
raise
('lang.CloneNotSupportedException', 'Enums cannot be cloned');
}
}

What can be seen:

  • The namespace declaration comes at the top of the file. It is indented to the same level the class declaration starts at.
  • Classes from the lang package (Object, XPClass, IllegalArgumentException) are not fully qualified
  • The ReflectionException class (builtin) is without namespace and therefore explicitely referenced that way (though that would not be necessary in this case!)
  • The raise() core functionality is also referenced as being in the global namespace. This is absolutely necessary - the implicit import of builtin classes and functions does not work here!

Syntax example #2

  namespace iocollections;

class FileCollection extends langObject implements IOCollection {

public function open() {
if (!($this->_hd= opendir($this->uri))) {
throw new ioIOException('Could not open '.$this->uri);
}
}

public function createdAt() {
return new utilDate(filectime($this->uri));
}
}

What can be seen:

  • XP packages map to PHP namespaces by replacing the dots (.) with double colons (Package[io.collections] = Namespace[io\collections])
  • XP class names map to PHP namespaced names by replacing the dot (.) with double colons (XPClass[util.Date] = Class[util\Date]).
  • Classes from the same package are unqualified (IOCollection), while classes from foreign packages (IOException, Date, Object) are written using their fully qualified names.
  • The Object class is used in its fully qualified form. An auto-import for all classes in the "lang" package as known from the Java programming language is not available due to the generic way namespaces are implemented in the PHP language!

uses() vs. use

We figured the following would be rather ugly:

  uses('com.oneandone.qf.QfId');

use comoneandoneqfQfId;

$id= new QfId();

...because from looking at this, somehow the import seems to happen twice. In reality though, uses() loads classes by their fully qualified name by means which boil down to include.

We basically came up with the following alternatives:

  1. Add special syntax to uses() such as com.oneandone.qf.QfId:QfId or prefixing class names with "+" for importing
  2. Rely on autoloading
  3. Don't change anything and use the above
From these, the second sounds promising - given that autoload isn't as slow as everybody's saying (this will need to be profiled) - it's also the sexiest. Here's an idea:

QfId.class.php

  namespace comoneandoneqf;

class QfId extends langObject {
protected $value= 0;

public function __construct($value) {
$this->value= $value;
}

public function equals(langGeneric $cmp) {
return $cmp instanceof self && $cmp->value === $this->value;
}
}

QfIdTest.class.php

  namespace comoneandoneqftests;

use comoneandoneqfQfId;

class QfIdTest extends unittestTestCase {

#[@test]
public function equality() {
$this->assertEquals(new QfId(0), new QfId(0));
}
}

Security considerations

n/a

Speed impact

n/a

Dependencies

- PHP with namespaces support (current plans: 5.3)

- RFC #0037 - will be deprecated

- Increase major version number (that would make it XP6.0.0)

- XP5 branch

Related documents

- http://xp-framework.info/xml/xp.en_US/news/view?206 Namespaces briefing

- http://experiments.xp-framework.net/?arena,namespaces Sneak preview

- http://xp-framework.net/downloads/php5-namespaces/ Backported Diff and 5.2.5 w/ namespaces Windows releases

Comments

- friebe, Sun Sep 2 20:34:58 2007 The migrated version currently does not contain import statements but instead ::uses() and only fully qualified names for foreign packages. The reason for this is that an __autoload() / import constellation has some weird side effetcs that need to be investigated.

- friebe, Sun Sep 2 20:41:02 2007 Windows builds from above will need the Microsoft Visual C++ 2005 SP1 Redistributable Package to work (as they are built using VC++ 2005 Express). You can find them at: http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647

<EOF>


Table of contents