What’s new in PHP 5.3 – part 1: namespaces

Date November 13, 2007

In my previous post I mentioned that PHP 5.3 will be released in early 2008 so I think it’s just in time to talk about the features of this version. It is started by this polling (in detail, in an ordered version) on the internal list. The big gun features are namespaces, late static binding and mysqlnd, but there are other interesting improvements, for example __callStatic, dynamic static calls. In this part of this series we are going to analyze namespaces in detail.

Namespaces basic

Namespace support in PHP was a long-felt want feature. In PHP the main motivation behind adding namespace support to the language was to solve the problem of long class names. If you develop a bigger library, you have to use long class names to avoid naming conflicts, for example look at this monster: Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive.

From the version 5.3 you can group your code into namespaces. Different namespaces can contains classes, functions, constants with the same name. Defining a namespace is very straightforward, you should use the namespace statement in the very beginning of the file, for example:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
/** classes/my/foo/MyClass.php */

namespace my::foo;

class MyClass {}

// You can define functions and constants in the namespace too.
function myFunc() { }
const MY_CONST = 'foo';

?>

You have a lot of options to use items defined in this namespace:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
/** test.php */
include('classes/my/foo/MyClass.php');

// You can always access anything ∈an object with fully qualified name.
$foo = new my::foo::MyClass();

// You can use the use statement to import a namespace.
use my::foo;
// After the above statement you can reffer for the my::foo namespace with foo.
$foo = new foo::MyClass();

// You can import only one class.
use my::foo::MyClass;
$foo = new MyClass;

// You can create aliases.
use my::foo as MyFoo;
use my::foo::MyClass as MyFooClass;
$foo = new MyFoo::MyClass();
$foo = new MyFooClass();

// Note, that the following two statements are equivalent:
use my::foo;
use my::foo as foo;

// You can access functions and constants in the same way:
my::foo::myFunc();
myFoo::myFunc();
my::foo::MY_CONST;
myFoo::MY_CONST;

?>

Only namespaces and classes can be imported with the use statement, for example you can’t say: use my::foo::MY_CONST;. A use statement takes effect from its definition to the end of the file, you can use it everywhere in the global scope. You can use the same namespace in more files, but one file should contain only one namespace (this behavior maybe will changed in the final version, or the maybe the namespace keyword will be replaced with package :) ). While you can’t import a function or a constant, you should always use some kind of prefix if you want to access any of them from a namespace. In the earlier versions of PHP 5.3 the import keyword was used insted of use, but few weeks ago it was changed.

The “empty” namespace (::)

If you use the :: prefix by function and class names, they are interpreted as global independently from the current import rules. This is useful inside a namespace.

Life with namesapces (porting code to PHP 5.3)

If you decide to use namespaces there are some pitfalls you should pay attention.

Class naming convention

You should forget to use reserved words in you class names. Consider the following code:

1
2
3
4
<?php
/** classes/my/form/element/static.php */
class MyFormElementStatic {}
?>

The equivalent would be this using namespace:

1
2
3
4
5
<?php
/** classes/my/form/element/static.php */
namespace my::form::element;
class Static {}
?>

But DateStatic is a reserved word (and an existent internal class) so this code ends in fatal error. This could be a bad news if you have a lot of similar classes.

Autoloading

From PHP 5.3 __autoload() will get the fully qualified class name. This mean that you have to modify you __autoload funciton if you have used one. A basic example:

1
2
3
4
5
6
7
8
9
<?php
/** test.php */
function __autoload($className)
{
    require 'classes/'.str_replace('::', DIRECTORY_SEPARATOR, $className).'.php';
}
       
$foo = new my::foo::MyClass();
?>

Or you prefer the SPL way:

1
2
3
4
5
6
7
8
9
/** classes/my/core/classloader.php */
namespace my::core;

function classLoader($className)
{
    require 'classes/'.str_replace('::', DIRECTORY_SEPARATOR, $className).'.php';
}

spl_autoload_register('my::core::classLoader');
1
2
3
/** test.php */
require 'classes/my/core/classLoader.php';
$foo = new my::foo::MyClass();

get_class(), get_parent_class(), etc.

When you use these type of functions you should take into consideration that they returns fully qualified class names too.

Reflection API

The Reflection API should reflect (;)) to this new language feature. The plan is the following:

  • Create a new ReflectionNamespace class with the following methods: getName(), getClasses(), getFunctions(), getFiles()
  • Extend the ReflectionClass and ReflectionFunction classes with a new getNamespace() method.

Life inside a namespace

There is some special knowledge you should be familiar with, if you want to write codes in namespaces.

The __NAMESPACE__ constant

There is a new special constant: __NAMESPACE__, which contains the name of the current namespace. For example you can write the SPL autoloader in the following way:

1
2
3
4
5
6
7
8
9
/** classes/my/core/classloader.php */
namespace my::core;

function classLoader($className)
{
    require 'classes/'.str_replace('::', DIRECTORY_SEPARATOR, $className).'.php';
}

spl_autoload_register(__NAMESPACE__.'::classLoader');

Resolving names inside a namespace

I don’t want to describe the complete rule set here, you can read it in the PHP namespaces README. The main point is, that PHP try to resolve a name first according to the current namesapce. Let’s see some example:

1
2
3
4
5
6
7
<?php
namespace my::foo;
...
bar();
...
::bar();
?>

When you call bar() then PHP try to find the function in the my::foo namespace. If it finds it will call it, if not it will try to call the internal bar() function, so it is important to notice, that using this notation, you can’t call user defined function inside a namespace. Using the ::bar() form PHP will call the bar() function in the global namespace, so it could be an internal or a user defined function. This logic is true when you try to create a new object.

1
2
3
4
5
6
7
<?php
namespace my::foo;

core::bar();

::core::bar();
?>

In this case of core::bar() PHP first tries to call function bar() from namespace my::foo::core then calls method bar() of internal class core. In the case of ::core::bar() it first tries to call function bar() from namespace core then calls method bar() of class core from global scope.

The namespace support in PHP is not yet finished, it is possible some modifications in the future.

29 Responses to “What’s new in PHP 5.3 – part 1: namespaces”

  1. Lukas said:

    “But Date is a reserved word (and an existent internal class) so this code ends in fatal error. This could be a bad news if you have a lot of similar classes.”

    That should not be the case as it would defeat the key point of the namespace patch. How did you come to the conclusion that it would throw a fatal error?

    BTW: maybe you want to register your blog on planet php?

  2. developercast.com » Gergely Hodicska’s Blog: What’s new in PHP 5.3 - part 1: namespaces said:

    [...] centering about what’s going to be coming in the next major release of PHP, version 5.3. The first article has been posted today focusing on one of the more popular topics – namespaces. In my previous [...]

  3. Felho said:

    @Lukas:

    “That should not be the case as it would defeat the key point of the namespace patch. How did you come to the conclusion that it would throw a fatal error?”
    Thx, you have absolutely right. I updated the code with the class name with which I played when I tried first the capabilities of namespaces. I just wanted a fancier example, but my bluff failed. :)

    “BTW: maybe you want to register your blog on planet php?”
    I tried to post my blog to Tobias but I haven’t been answered for the present. I created a feedburner feed for this purpose: http://feeds.feedburner.com/felho/php.

  4. David Coallier said:

    Are you trying to steal my PHP Namespaces hype ? :D haha joking, good article

  5. Felho said:

    @David: :D , THX!!!

  6. What’s new in PHP 5.3 - part 2: late static binding | Gergely Hodicska said:

    [...] the first part of this series I wrote about namespaces, in the second part we will deal with static late binding, [...]

  7. Andra P žurnāls » Blog Archive » Tiem, kam interesÄ“, kas bÅ«s jauns PHP 5.3 said:

    [...] izskriet cauri šim Gergely Hodicska rakstam, kurā viņš runā par, jā, jūs uzminējāt, namespaces. Izskatās, ka tas būs pirmais raksts [...]

  8. Charles said:

    In this case of core::bar() PHP first tries to call function bar() from namespace my::foo::core then calls method bar() of internal class core.
    how about if I defined a static method bar() in the class core which is under my::foo

  9. Felho said:

    @Charles: the static method of the core class in namspace my::foo has precedence over the method of the internal core class.

  10. What is new in PHP 5.3 - part 3: mysqlnd | Gergely Hodicska said:

    [...] the first two parts of this series I wrote about namaspaces and late static binding. In this part I will cover mysqlnd (MySQL native driver for PHP), which is [...]

  11. Namespace no PHP 5.3 « DeCo said:

    [...] tutorial mais completo com vários exemplos: What’s new in PHP 5.3 – part 1: namespaces Posted by DeCo Filed in PHP Tags: namespace, [...]

  12. DeCo said:

    Nice tuto :)

  13. What is new in PHP 5.3 - part 4: __callStatic, OpenID support, user.ini, XSLT profiling and more | Gergely Hodicska said:

    [...] are already familiar with namespaces, late static binding and mysqlnd but PHP 5.3 has a lot more cool features. We can find some [...]

  14. warpedvisions.org » Blog Archive » New features in Php 5.3 said:

    [...] 2007 in Links Here’s a great set of articles showing off the new features in Php 5.3: Part 1, 2, 3, 4. It’s fun to watch languages [...]

  15. Undefined variable » Blog Archive » What is new in PHP 5.3? said:

    [...] http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html [...]

  16. PHP 5.3 : le tour des nouveautés said:

    [...]  What is new in PHP 5.3 – part 1 (0 visite) [...]

  17. iGeek » Namespaces y MySQL Native Driver en PHP 5.3 said:

    [...] Aca tambien les dejo un link con un articulo que nos muestra algunos de los nuevos aspectos que nos …. [...]

  18. PHP 5.3: Just keeps getting better and better « PHP::Impact ( [str blog] ) said:

    [...] 1: Namespaces Part 2: Late Static Binding Part 3: mysqlnd Part 4: OpenID support, callStatic, user.ini, XSLT [...]

  19. PHP::Impact ( [str blog] ) » Blog Archive » PHP 5.3: Just keeps getting better and better said:

    [...] 1: Namespaces Part 2: Late Static Binding Part 3: mysqlnd Part 4: OpenID support, callStatic, user.ini, XSLT [...]

  20. Novidades do PHP 5.3 said:

    [...] = new minhaClasse::executar(); Para mais informações sobre namespaces, visite aqui(em portugues), aqui ou [...]

  21. What’s new in PHP 5.3 « we’re only gonna die from our arrogance said:

    [...] What’s new in PHP 5.3 – part 1: namespaces [...]

  22. mma said:

    I find this blog very interesting, i will be here everyday till now. Greetings

  23. Rafael Dohms » The road to PHP 5.3: Namespaces said:

    [...] You can read more details here: http://blog.felho.hu/whats-new-in-php-53-part-1-namespaces.html [...]

  24. Anjanesh said:

    Its no more scope resolution operator since alpha3. They’ve changed it to backslash(\). Also bracketed syntax is available.

    namespace my\foo
    {
    class MyClass {}
    function myFunc() { }
    const MY_CONST = 'foo';
    }

    namespace you\foo
    {
    class MyException extends \Exception
    {
    }
    }

    But the weirdest thing is extends Exception tries to look for Exception in the current namespace and doesnt automatically look for it in the global namespace. This seems to hold for any class in the namespace.

    class MyClass extends MyGlobalClass fails to look for MyGlobalClass in the global namespace. We need to explicitly specify \MyGlobalClass

  25. Lambda functions in PHP? said:

    [...] What’s new in PHP 5.3. [...]

  26. PHP 5.3 RC3 released « PHP Programming said:

    [...] haven’t already downloaded it and tested it out now is the time to do it. PHP 5.3 brings a whole plethera of new features including the SPLFxiedArray class (you can no longer disable this) as well as PHP’s native [...]

  27. Phil said:

    RC3 is now out :o ) Shouldn’t be long now till the final release. I really like the SPL class and the mysqlnd driver

  28. gabriel #CoGUMm. » PHP 5.3.0 RELEASE said:

    [...] mais informações sobre namespaces, visite aqui(em portugues), aqui ou [...]

  29. PHP 5.3 Zone virtuaalserverites « ZONE.EE said:

    [...] Loe veel… Tähelepanu väärib ka asjaolu, et käesoleva versiooniga hakatakse välja juurima mõningaid omadusi, mis PHP-le läbi ajaloo on omajagu halba kuulsust toonud. [...]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>