With PHP5.3.3 recently released I really feel it is time that php developers are taking namespaces seriously. If you don’t I guarantee you will be out of a job within five years. Namespaces are a fundamental part of the future of PHP. The talk explains the usage on importing third party libraries, using it in your own code and aliasing. The full works.
2. About Me @NickBelhomme Freelance PHP Consultant International Conference Speaker Zend Framework 2.0 Cookbook Author Contributor to various Open Source Projects ZCE ZFCE
4. Dreams A world of unbounded potential. Where everybody believes they can Be, do and have whatever they think about. Think your idea Act upon your idea Refine later
6. Why Other big programming languages support them Introduced in PHP 5.3 – One and a half years ago Modern Next Gen Frameworks (Symfony 2.0, Zend Framework 2.0 and others) Job market demands it Use it or loose it
7. What are they? Abstract container created to hold a logical grouping of unique identifiers. Unique identifiers are names. (in practice: classes, functions, constants) Each identifier is associated with the namespace where it is defined.
8. PEAR Naming Convention R.I.P. No more clever workaround for lack of namespace support No more very long function and class names
9. Welcome Readability new Zend_Layout_Controller_Action_Helper_Layout() new Layout() class NbeZf_Model_User extends Nbe_Model_Abstract class User extends AbstractModel
10. How to create the container space <?php namespace Nbeollection; <?php declare(encoding='UTF-8'); namespace Nbeollection; Per file <?php /** * @namespace */ namespace Nbeollection;
11. How to create the container space <?php namespace Nbeodel; const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ... */ } function draw() { /* ... */ } namespace NbeZf; const LIBRARY_PATH = '/www/libs/NbeZf'; class AbstractModel { /* ... */ } function sayHello() { /* ... */ } Mixing spaces per file <?php namespace Nbeodel { const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ... */ } function draw() { /* ... */ } } namespace { const APP_PATH = '/www/libs/NbeZf'; function __autoload() { /* ... */ } }
12. Common Mistakes <?php namespace be; // rest of code Fatal error: Undefined constant 'Nbe' <?php namespace Nbe; class Interface {} <?php namespace Nbe; class Abstract {} Parse error: syntax error, unexpected T_INTERFACE Parse error: syntax error, unexpected T_ABSTRACT
13. Different name types Fully Qualified Name beodelbstractModel Qualified Name ModelbstractModel Unqualified Name AbstractModel
14. Autoloading namespaces function __autoload($class) { require_once str_replace( '', DIRECTORY_SEPARATOR, $class ) . '.php'; } new beZfodelser() maps to NbeZfodelser require_once /NbeZf/Model/User.php
16. Resolving namespace calls <?php namespace Nbe; class Model {} $model = new Model(); echo get_class($model); Output: Nbeodel <?php namespace Nbe; function model() { return __FUNCTION__; } echo model(); Output: Nbeodel
17. Consequences <?php namespace Nbe; $collection = new ArrayObject(); Fatal error: Class 'NberrayObject' not found <?php namespace Nbe; $collection = new rrayObject(); Indicate global namespace with a single backslash <----
18. Function fallbacks <?php namespace Nbe; var_dump(explode(';', ' some;cool;words ')); <?php namespace Nbe; ar_dump( explode(';', 'some;cool;words')); Better practice. Explicitly call global space FULLY QUALIFIED NAMES Compile time <---- Runtime and potential happy debugging feature <----
20. Magic constants beware <?php namespace Nbe; echo __LINE__; echo __FILE__; echo __DIR__; echo __FUNCTION__; echo __CLASS__; echo __METHOD__; echo __NAMESPACE__; Magic constants cannot be overwritten so no global namespace prefix is allowed
21. Namespaces are per file <?php function sayHello() { echo 'hello'; } <?php namespace Nbe; require '/utils.php'; ayHello();
22. But what about using other namespaces? Fully Qualified namespace calling is still tedious. So how do we solve this? ?
23. Importing to the rescue! <?php namespace DancingQueenntity; use NbeZfntitybstractEntity, ZendalidatortaticValidator; class User extends AbstractEntity { public function setId($id) { If (!StaticValidator::execute($id, 'digits')) { throw new InvalidArgumentException('User id needs to be numeric'); } ... } }
24. OOOH Noes a naming collision :((( <?php namespace NbeZfalidator; use ZendalidatortaticValidator; class StaticValidator extends StaticValidator { public static function getBroker() { if (null === self::$broker) { static::setBroker(new ValidatorBroker()); } return self::$broker; } } Fatal error: Cannot declare class NbeZfalidatortaticValidator because the name is already in use
25. Aliasing to the rescue! <?php namespace NbeZfalidator; use ZendalidatortaticValidator as ZfStaticValidator; class StaticValidator extends ZfStaticValidator { public static function getBroker() { if (null === self::$broker) { static::setBroker(new ValidatorBroker()); } return self::$broker; } }
26. Aliasing is in-explicitly used <?php namespace DancingQueenntity; use NbeZfntitybstractEntity as AbstractEntity, ZendalidatortaticValidator as StaticValidator; class User extends AbstractEntity { public function setId($id) { If (!StaticValidator::execute($id, 'digits')) { throw new InvalidArgumentException('User id needs to be numeric'); } ... } }
28. Dynamic Loading from other namespace <?php namespace Nbe; $class = 'endiewhpRenderer'; $object = new $class(); echo get_class($object); Ouput: ZendiewhpRenderer Fully qualified names
29. Dynamic Loading from current <?php namespace Nbe; $class = __NAMESPACE__ . '' . 'ArrayObject'; $object = new $class(); echo get_class($object); Output: NberrayObject
30. Resolution Rules <?php namespace Nbe; use Tatabe; $object = new ArrayObject(); <?php namespace Nbe; use Tatabe; $object = new NberrayObject(); Resolves to NberrayObject Resolves to TataberrayObject
31. Resolution Rules for Dummies When an alias is available – and there is always an alias available when importing - all unqualified and qualified names are translated using the current import rules. When no alias is available all unqualified and qualified names have the current namespace prepended. Constants and functions have fallbacks to global namespace for unqualified names.
32. Explicitly Loading from current <?php namespace Nbe; class Exception extends xception{} ?> <?php namespace Nbe; use Exception; const ERROR_INFO = 10; try { try { if (1===1) { throw new Exception('instantiates xception'); } } catch (xception $e) { throw new namespacexception('instantiates bexception', ERROR_INFO, $e); } } catch (namespacexception $e) { echo 'error: '.$e->getMessage(); echo PHP_EOL; echo 'nested exception error: '.$e->getPrevious()->getMessage(); } File 1 File 2 namespace keyword
33. Coming to an end, but first some Timeline changes PHP4 class constructor has the same name as the class > PHP5 class constructor is __construct but accepts PHP4 convention >5.3 namespaces are introduced, nothing changes >= 5.3.3 Backward compatibility change. Only __construct is now regarded as the constructor for namespaced code.
34. And some cool resources The PHP manual http://www.php.net/namespaces Ralph Schindlers namespace convert tool https://github.com/ralphschindler/PHPTools Plus comments on it by Cal Evan http://blog.calevans.com/2010/03/27/zends-new-namespace-converter/ Google: php namespaces http://www.google.be/search?q=php+namespaces Zend Framework 2.0 Cookbook http://blog.nickbelhomme.com/php/zend-framework-2-0-cookbook_324