Mastering Namespaces in PHP

  • 17,171 views
Uploaded 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 …

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.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
17,171
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
170
Comments
2
Likes
13

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. MASTERING NAMESPACES! Nick Belhomme January 29, 2011 – PHPBenelux Conference
  • 2. About Me @NickBelhomme Freelance PHP Consultant International Conference Speaker Zend Framework 2.0 Cookbook Author Contributor to various Open Source Projects ZCE ZFCE
  • 3. Passions Life Traveling People Sharing Ideas Networking
  • 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
  • 5. BACK TO NAMESPACES <----
  • 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 NbeCollection; <?php declare(encoding='UTF-8'); namespace NbeCollection; Per file <?php /** * @namespace */ namespace NbeCollection;
  • 11. How to create the container space <?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() { /* ... */ } Mixing spaces per file <?php namespace NbeModel { const LIBRARY_PATH = '/www/libs/Nbe'; class AbstractModel { /* ... */ } function draw() { /* ... */ } } namespace { const APP_PATH = '/www/libs/NbeZf'; function __autoload() { /* ... */ } }
  • 12. 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
  • 13. Different name types Fully Qualified Name NbeModelAbstractModel Qualified Name ModelAbstractModel Unqualified Name AbstractModel
  • 14. Autoloading namespaces function __autoload($class) { require_once str_replace( '', DIRECTORY_SEPARATOR, $class ) . '.php'; } new NbeZfModelUser() maps to NbeZfModelUser require_once /NbeZf/Model/User.php
  • 15. 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();
  • 16. 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
  • 17. 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 <----
  • 18. Function fallbacks <?php namespace Nbe; var_dump(explode(';', ' some;cool;words ')); <?php namespace Nbe; var_dump( explode(';', 'some;cool;words')); Better practice. Explicitly call global space FULLY QUALIFIED NAMES Compile time <---- Runtime and potential happy debugging feature <----
  • 19. Constants fallbacks <?php namespace { const APP = 'test'; } namespace Nbe { const E_ERROR = 10; echo APP; echo E_ERROR; } Better practice. Explicitly call global space Fully quaylified names, compile time <?php namespace { const APP = 'test'; } namespace Nbe { const E_ERROR = 10; echo APP; echo E_ERROR; } 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'; sayHello();
  • 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 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'); } ... } }
  • 24. OOOH Noes a naming collision :((( <?php namespace NbeZfValidator; use ZendValidatorStaticValidator; 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
  • 25. 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; } }
  • 26. Aliasing is in-explicitly used <?php namespace DancingQueenEntity; use NbeZfEntityAbstractEntity as AbstractEntity, ZendValidatorStaticValidator as StaticValidator; class User extends AbstractEntity { public function setId($id) { If (!StaticValidator::execute($id, 'digits')) { throw new InvalidArgumentException('User id needs to be numeric'); } ... } }
  • 27. Dynamic Loading <?php namespace Nbe; $class = 'ArrayObject'; $object = new $class(); echo get_class($object); Output: ArrayObject Always Absolute Path
  • 28. Dynamic Loading from other namespace <?php namespace Nbe; $class = 'ZendViewPhpRenderer'; $object = new $class(); echo get_class($object); Ouput: ZendViewPhpRenderer Fully qualified names
  • 29. Dynamic Loading from current <?php namespace Nbe; $class = __NAMESPACE__ . '' . 'ArrayObject'; $object = new $class(); echo get_class($object); Output: NbeArrayObject
  • 30. Resolution Rules <?php namespace Nbe; use TataNbe; $object = new ArrayObject(); <?php namespace Nbe; use TataNbe; $object = new NbeArrayObject(); Resolves to NbeArrayObject Resolves to TataNbeArrayObject
  • 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 Exception{} ?> <?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(); } 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
  • 35. And we reached the end, Any questions?
  • 36. The End! THANK YOU [email_address] Slideshare, Twitter, IRC: NickBelhomme http://blog.nickbelhomme.com