MASTERING NAMESPACES! Nick Belhomme Spetember 17, 2011 – PFCongres The Netherlands
Software Architect / Project Lead Author of the  Zend Framework 2.0 Cookbook International Conference Speaker Contributor ...
www.nickbelhomme.com @NickBelhomme facebook.com/NickBelhommeFanPage Freenode irc: NickBelhomme
 
Other big programming languages support them Introduced in PHP 5.3 – Two years ago Modern Next Gen Frameworks  (Symfony 2....
WHAT ARE THEY ?
Abstract container created to hold a logical grouping of unique identifiers. Unique identifiers are names. (in practice: c...
Abstract container created to hold a logical grouping of unique identifiers. Unique identifiers are names. (in practice: c...
Abstract container created to hold a logical grouping of unique identifiers. Unique identifiers are names. (in practice: c...
Abstract container created to hold a logical grouping of unique identifiers. Unique identifiers are names. (in practice: c...
Abstract container created to hold a logical grouping of unique identifiers. Unique identifiers are names. (in practice: c...
Namespace Separator
 
PEAR Naming Convention  R.I.P. No more clever workaround for lack of namespace support No more very long function and clas...
 
new Zend_Layout_Controller_Action_Helper_Layout() class NbeZf_Model_User extends Nbe_Model_Abstract
new Zend_Layout_Controller_Action_Helper_Layout() new Layout() class NbeZf_Model_User extends Nbe_Model_Abstract class Use...
100% PURE NAMESPACES No supplements – Pure Power
The container space is created per file at the absolute top <?php namespace NbeCollection; <?php declare(encoding='UTF-8')...
The container space is created per file at the absolute top <?php namespace NbeCollection; <?php declare(encoding='UTF-8')...
The container space is created per file at the absolute top <?php namespace NbeCollection; <?php declare(encoding='UTF-8')...
Mixing Container Spaces per file <?php namespace NbeModel; const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ...
Mixing Container Spaces per file <?php namespace NbeModel; const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ...
Common Mistakes <?php namespace  Nbe ; // rest of code Fatal error: Undefined constant 'Nbe' <?php namespace Nbe; class  I...
Different name types Fully Qualified Name  NbeModelAbstractModel Qualified Name ModelAbstractModel Unqualified Name Abstra...
Autoloading namespaces function __autoload($class) { require_once str_replace( '',  DIRECTORY_SEPARATOR,  $class ) . '.php...
Autoloading namespaces <?php namespace NbeLoader; function autoLoader($className) { require_once str_replace('', DIRECTORY...
Resolving namespace calls <?php namespace Nbe; class Model {} $model = new Model(); echo get_class($model); Output: Nbe Mo...
Resolving namespace calls <?php namespace Nbe; class Model {} $model = new Model(); echo get_class($model); Output: NbeMod...
Consequences <?php namespace Nbe; $collection = new ArrayObject(); Fatal error:  Class  'NbeArrayObject'  not found <?php ...
Function fallbacks happen at Runtime <?php namespace Nbe; var_dump(explode(';', ' some;cool;words '));
Warning system functions within namespaces – Procedural Code <?php namespace WackyCode; var_dump(  explode(';', 'some;cool...
(Procedural) Constants fallbacks <?php namespace Nbe { echo E_ERROR; }
(Procedural) Constants fallbacks <?php namespace Nbe { E_ERROR = 10; } <?php namespace Nbe { echo E_ERROR; } <?php namespa...
 
Fully Qualified Name Compile Time Qualified || Unqualified Name Runtime
Classses have no fallback to global scope Functions when not found in namespace fall back on global scope Constants when n...
 
Magic constants beware <?php namespace Nbe; echo __LINE__; echo __FILE__; echo __DIR__; echo __FUNCTION__; echo __CLASS__;...
Namespaces are per file // utils.php <?php function sayHello() { echo 'hello'; } <?php namespace Nbe; require '/utils.php'...
Mixing Namespaces Fully Qualified namespace calling is still tedious.  So how do we solve this?
Importing to the rescue! Keyword is  use
Importing to the rescue! <?php namespace  DancingQueenEntity ; use  NbeZfEntityAbstractEntity ; use ZendValidatorStaticVal...
Importing to the rescue! <?php namespace  DancingQueenEntity ; use  NbeZfEntityAbstractEntity , ZendValidatorStaticValidat...
OOOH Noes a naming collision :((( <?php namespace NbeZfValidator; use ZendValidator StaticValidator ; class  StaticValidat...
Aliasing to the rescue! <?php namespace NbeZfValidator; use ZendValidatorStaticValidator as ZfStaticValidator; class Stati...
Aliasing is in-explicitly used <?php namespace DancingQueenEntity; use NbeZfEntity AbstractEntity  as  AbstractEntity , Ze...
Aliasing for semantics <?php namespace Nbe; use NbeUserCollection as  Users ; class Group { public function setUsers( User...
Aliasing for semantics <?php namespace Nbe; use NbeUserCollection as  Users ; class Group { public function setUsers($user...
Dynamic Loading
Always at runtime … <?php namespace Nbe; $class = 'ArrayObject'; $object = new $class(); echo get_class($object); Output: ...
Always use fully qualified names for dynamic class names if they are used! <?php namespace Nbe; class Group { public funct...
From other namespace <?php namespace Nbe; $class = 'ZendViewPhpRenderer'; $object = new $class(); echo get_class($object);...
Dynamic Loading from current <?php namespace Nbe; $class = __NAMESPACE__ . '' .  'ArrayObject' ; $object = new $class(); e...
Resolution Rules  <?php namespace Nbe; use TataNbe; $object = new ArrayObject(); <?php namespace Nbe; use TataNbe; $object...
Resolution Rules  <?php namespace Nbe; use TataNbe; $object = new ArrayObject(); <?php namespace Nbe; use TataNbe; $object...
Resolution Rules for Dummies When an alias is available – and there is always an alias available when importing - all unqu...
Importing and Aliasing Impacts They don't cost you anything, they are a kind of memory mapping for the PHP interpreter The...
Explicitly Loading from current <?php namespace  Nbe ; use  Exception ; const ERROR_INFO = 10; try { try { if (1===1) { th...
Coming to an end, but first some Timeline changes PHP4 class constructor has the same name as the class > PHP5 class const...
And a quick recap on WHY Readability Dependencies can be indicated easily System functions and constants can be overwritte...
And some cool resources The PHP manual  http://www.php.net/namespaces Ralph Schindlers namespace convert tool https://gith...
And we reached the end, Any questions?
The End! THANK YOU [email_address] Slideshare, Twitter, IRC: NickBelhomme http://blog.nickbelhomme.com
Photo Credits Photos rights reserved by Sweetie187 , webtreats, royblumenthal, Brad montgomery, ktylerconk, vegetarians-do...
Upcoming SlideShare
Loading in...5
×

Mastering PHP Namespaces PFCongres11

5,265

Published on

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.

Published in: Technology
1 Comment
3 Likes
Statistics
Notes
No Downloads
Views
Total Views
5,265
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
59
Comments
1
Likes
3
Embeds 0
No embeds

No notes for slide
  • WHO USES NAMESPACES
  • Mastering PHP Namespaces PFCongres11

    1. 1. MASTERING NAMESPACES! Nick Belhomme Spetember 17, 2011 – PFCongres The Netherlands
    2. 2. Software Architect / Project Lead Author of the Zend Framework 2.0 Cookbook International Conference Speaker Contributor to various Open Source Projects Freelance PHP Consultant
    3. 3. www.nickbelhomme.com @NickBelhomme facebook.com/NickBelhommeFanPage Freenode irc: NickBelhomme
    4. 5. Other big programming languages support them Introduced in PHP 5.3 – Two years ago Modern Next Gen Frameworks (Symfony 2.0, Zend Framework 2.0 and others) Job market demands it Use it or loose it
    5. 6. WHAT ARE THEY ?
    6. 7. 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. Namespace ZendControllerAction Namespace ZendView Namespace Nbe HelperLoader HelperBroker HelperPriorityStack E_ERROR explode HelperLoader HelperBroker PhpRenderer Namespace ArrayObject explode E_ERROR ArrayObject
    7. 8. 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. Namespace ZendControllerAction Namespace ZendView Namespace Nbe HelperLoader HelperBroker HelperPriorityStack E_ERROR explode HelperLoader HelperBroker PhpRenderer Namespace ArrayObject explode E_ERROR ArrayObject
    8. 9. 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. Namespace ZendControllerAction Namespace ZendView Namespace Nbe HelperLoader HelperBroker HelperPriorityStack E_ERROR explode HelperLoader HelperBroker PhpRenderer Namespace ArrayObject explode E_ERROR ArrayObject
    9. 10. 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. Namespace ZendControllerAction Namespace ZendView Namespace Nbe HelperLoader HelperBroker HelperPriorityStack E_ERROR explode HelperLoader HelperBroker PhpRenderer Namespace ArrayObject explode E_ERROR ArrayObject
    10. 11. 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. Namespace ZendControllerAction Namespace ZendView Namespace Nbe HelperLoader HelperBroker HelperPriorityStack E_ERROR explode HelperLoader HelperBroker PhpRenderer Namespace ArrayObject explode E_ERROR ArrayObject
    11. 12. Namespace Separator
    12. 14. PEAR Naming Convention R.I.P. No more clever workaround for lack of namespace support No more very long function and class names R.I.P. Poor man's namespacing
    13. 16. new Zend_Layout_Controller_Action_Helper_Layout() class NbeZf_Model_User extends Nbe_Model_Abstract
    14. 17. new Zend_Layout_Controller_Action_Helper_Layout() new Layout() class NbeZf_Model_User extends Nbe_Model_Abstract class User extends AbstractModel
    15. 18. 100% PURE NAMESPACES No supplements – Pure Power
    16. 19. The container space is created per file at the absolute top <?php namespace NbeCollection; <?php declare(encoding='UTF-8'); namespace NbeCollection; <?php /** * @namespace */ namespace NbeCollection;
    17. 20. The container space is created per file at the absolute top <?php namespace NbeCollection; <?php declare(encoding='UTF-8'); namespace NbeCollection; <?php /** * @namespace */ namespace NbeCollection;
    18. 21. The container space is created per file at the absolute top <?php namespace NbeCollection; <?php declare(encoding='UTF-8'); namespace NbeCollection; <?php /** * @namespace */ namespace NbeCollection;
    19. 22. Mixing Container Spaces per file <?php namespace NbeModel; const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ... */ } function draw() { /* ... */ } namespace NbeZf; const LIBRARY_PATH = '/www/libs/NbeZf'; class AbstractModel { /* ... */ } function sayHello() { /* ... */ } <?php namespace NbeModel { const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ... */ } function draw() { /* ... */ } } namespace { const APP_PATH = '/www/libs/NbeZf'; function __autoload() { /* ... */ } }
    20. 23. Mixing Container Spaces per file <?php namespace NbeModel; const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ... */ } function draw() { /* ... */ } namespace NbeZf; const LIBRARY_PATH = '/www/libs/NbeZf'; class AbstractModel { /* ... */ } function sayHello() { /* ... */ } <?php namespace NbeModel { const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ... */ } function draw() { /* ... */ } } namespace { const APP_PATH = '/www/libs/NbeZf'; function __autoload() { /* ... */ } }
    21. 24. Common Mistakes <?php namespace Nbe ; // 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
    22. 25. Different name types Fully Qualified Name NbeModelAbstractModel Qualified Name ModelAbstractModel Unqualified Name AbstractModel
    23. 26. Autoloading namespaces function __autoload($class) { require_once str_replace( '', DIRECTORY_SEPARATOR, $class ) . '.php'; } new NbeZfModelUser() maps to NbeZfModelUser require_once NbeZf/Model/User.php
    24. 27. Autoloading namespaces <?php namespace NbeLoader; function autoLoader($className) { require_once str_replace('', DIRECTORY_SEPARATOR, $className) . '.php'; } <?php require 'Nbe/Loader/autoloader.php'; spl_autoload_register('NbeLoaderautoloader'); $user = new NbeEntityUser();
    25. 28. Resolving namespace calls <?php namespace Nbe; class Model {} $model = new Model(); echo get_class($model); Output: Nbe Model <?php namespace Nbe; function model() { return __FUNCTION__; } echo model(); Output: Nbemodel
    26. 29. Resolving namespace calls <?php namespace Nbe; class Model {} $model = new Model(); echo get_class($model); Output: NbeModel <?php namespace Nbe; function model() { return __FUNCTION__; } echo model(); Output: Nbemodel
    27. 30. Consequences <?php namespace Nbe; $collection = new ArrayObject(); Fatal error: Class 'NbeArrayObject' not found <?php namespace Nbe; $collection = new ArrayObject(); Indicate global namespace with a single backslash <----
    28. 31. Function fallbacks happen at Runtime <?php namespace Nbe; var_dump(explode(';', ' some;cool;words '));
    29. 32. Warning system functions within namespaces – Procedural Code <?php namespace WackyCode; var_dump( explode(';', 'some;cool;words')); Don't override system functions Or explicitly call global space FULLY QUALIFIED NAMES Compile time <---- <?php namespace WackyCode; function explode($separator, $string) { // do some freaky stuff }
    30. 33. (Procedural) Constants fallbacks <?php namespace Nbe { echo E_ERROR; }
    31. 34. (Procedural) Constants fallbacks <?php namespace Nbe { E_ERROR = 10; } <?php namespace Nbe { echo E_ERROR; } <?php namespace Nbe { echo E_ERROR; } Do not override system constants or Explicitly call global space Fully quaylified names, compile time
    32. 36. Fully Qualified Name Compile Time Qualified || Unqualified Name Runtime
    33. 37. Classses have no fallback to global scope Functions when not found in namespace fall back on global scope Constants when not found in namespace fall back on global scope
    34. 39. 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
    35. 40. Namespaces are per file // utils.php <?php function sayHello() { echo 'hello'; } <?php namespace Nbe; require '/utils.php'; sayHello();
    36. 41. Mixing Namespaces Fully Qualified namespace calling is still tedious. So how do we solve this?
    37. 42. Importing to the rescue! Keyword is use
    38. 43. Importing to the rescue! <?php namespace DancingQueenEntity ; use NbeZfEntityAbstractEntity ; use ZendValidatorStaticValidator ; class User extends AbstractEntity { public function setId($id) { If (! StaticValidator ::execute($id, 'digits')) { throw new InvalidArgumentException ('User id needs to be numeric'); } ... } }
    39. 44. Importing to the rescue! <?php namespace DancingQueenEntity ; use NbeZfEntityAbstractEntity , ZendValidatorStaticValidator ; class User extends AbstractEntity { public function setId($id) { If (! StaticValidator ::execute($id, 'digits')) { throw new InvalidArgumentException ('User id needs to be numeric'); } ... } }
    40. 45. OOOH Noes a naming collision :((( <?php namespace NbeZfValidator; use ZendValidator StaticValidator ; class StaticValidator extends StaticValidator { public static function getBroker() { if (null === self::$broker) { static::setBroker(new ValidatorBroker()); } return self::$broker; } } Fatal error: Cannot declare class NbeZfValidatorStaticValidator because the name is already in use
    41. 46. Aliasing to the rescue! <?php namespace NbeZfValidator; use ZendValidatorStaticValidator as ZfStaticValidator; class StaticValidator extends ZfStaticValidator { public static function getBroker() { if (null === self::$broker) { static::setBroker(new ValidatorBroker()); } return self::$broker; } } Aliasing only supported for classes
    42. 47. Aliasing is in-explicitly used <?php namespace DancingQueenEntity; use NbeZfEntity AbstractEntity as AbstractEntity , ZendValidator StaticValidator as StaticValidator ; class User extends AbstractEntity { public function setId($id) { If (! StaticValidator ::execute($id, 'digits')) { throw new InvalidArgumentException('User id needs to be numeric'); } ... } } Aliasing is done at compile time
    43. 48. Aliasing for semantics <?php namespace Nbe; use NbeUserCollection as Users ; class Group { public function setUsers( Users $users) { $this->users = $users; } } Great for typehinting Focusing on the WHAT IS – instead on language type
    44. 49. Aliasing for semantics <?php namespace Nbe; use NbeUserCollection as Users ; class Group { public function setUsers($users) { if ($users instanceof Users ) { $this->users = $users; } } } Great for typehinting Focusing on the WHAT IS – instead on language type
    45. 50. Dynamic Loading
    46. 51. Always at runtime … <?php namespace Nbe; $class = 'ArrayObject'; $object = new $class(); echo get_class($object); Output: ArrayObject … Implies absolute path or Fully Qualified Names
    47. 52. Always use fully qualified names for dynamic class names if they are used! <?php namespace Nbe; class Group { public function setUsers($users) { $class = 'NbeUserCollection'; if ($users instanceof $class ) { $this->users = $users; } } } Even if you are in the current namespace
    48. 53. From other namespace <?php namespace Nbe; $class = 'ZendViewPhpRenderer'; $object = new $class(); echo get_class($object); Ouput: ZendViewPhpRenderer
    49. 54. Dynamic Loading from current <?php namespace Nbe; $class = __NAMESPACE__ . '' . 'ArrayObject' ; $object = new $class(); echo get_class($object); Output: NbeArrayObject User Magic Constant __NAMESPACE__
    50. 55. Resolution Rules <?php namespace Nbe; use TataNbe; $object = new ArrayObject(); <?php namespace Nbe; use TataNbe; $object = new NbeArrayObject(); Resolves to NbeArrayObject Resolves to TataNbeArrayObject
    51. 56. Resolution Rules <?php namespace Nbe; use TataNbe; $object = new ArrayObject(); <?php namespace Nbe; use TataNbe; $object = new NbeArrayObject(); Resolves to NbeArrayObject Resolves to TataNbeArrayObject
    52. 57. 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.
    53. 58. Importing and Aliasing Impacts They don't cost you anything, they are a kind of memory mapping for the PHP interpreter The classes imported aren't effectively loaded into memory unless the class itself is used Added bonus when importing all the classes used at the top of the file is you get A quick dependency overview. There are static tools being developed which will read those dependencies
    54. 59. Explicitly Loading from current <?php namespace Nbe ; use Exception ; const ERROR_INFO = 10; try { try { if (1===1) { throw new Exception ('instantiates Exception'); } } catch (Exception $e) { throw new namespaceException ('instantiates NbeException', ERROR_INFO, $e); } } catch ( namespaceException $e) { echo 'error: '.$e->getMessage(); echo PHP_EOL; echo 'nested exception error: '.$e-> getPrevious() ->getMessage(); } with namespace keyword <?php namespace Nbe ; class Exception extends Exception {} ?>
    55. 60. 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.
    56. 61. And a quick recap on WHY Readability Dependencies can be indicated easily System functions and constants can be overwritten It is the future, evolve with the language or loose it The market will soon require the namespace skill
    57. 62. 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 Evans 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
    58. 63. And we reached the end, Any questions?
    59. 64. The End! THANK YOU [email_address] Slideshare, Twitter, IRC: NickBelhomme http://blog.nickbelhomme.com
    60. 65. Photo Credits Photos rights reserved by Sweetie187 , webtreats, royblumenthal, Brad montgomery, ktylerconk, vegetarians-dominate-meat-eaters-01, endless lazlo, DebilzBG, J. Star, quadrant6ix, notemily taken from Flickr.com
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×