Documente Academic
Documente Profesional
Documente Cultură
Basics
Namespace Separator
\
Get over it!
All rights reserved. Zend Technologies, Inc.
Declaring namespaces
Declaring namespaces
Block declaration
namespace Zend namespace Zend { { } } namespace Phly namespace Phly { { } }
Subnamespaces
Prefixing with a namespace separator resolves as a fully qualified name Resolution order:
Globally qualified: known; otherwise: Current namespace, or relative to it (Classes, functions, constants) Global namespace (functions, constants)
This means:
Importing namespaces
A way to bring code from another namespace into the current namespace. Import:
Importing namespaces
namespace My; namespace My; class Registry {} class Registry {} namespace Your; namespace Your; use My; // imports namespace use My; // imports namespace use My\Registry; // imports class use My\Registry; // imports class
Aliasing
"import namespace or class, but refer to it using this name" PHP utilizes the as keyword to alias
Aliasing
namespace Your; namespace Your; use My as m; use My as m; $r = new m\Registry(); $r = new m\Registry(); namespace Your; namespace Your; use My\Registry as reg; use My\Registry as reg; $r = new reg(); $r = new reg();
With aliases
namespace Their; namespace Their; use My as m, // aliased use My as m, // aliased Your; // not aliased Your; // not aliased
__NAMESPACE__
Comprehensive example
The setup:
namespace My\Package; namespace My\Package; const APIKEY = 1; const APIKEY = 1; function get($data) {} function get($data) {} class Service {} class Service {} namespace My\OtherPackage; namespace My\OtherPackage; const APIKEY = 2; const APIKEY = 2; function get($data) {} function get($data) {} class Service {} class Service {}
Comprehensive example
namespace Test; namespace Test; use My\Package\Service as PackageService, use My\Package\Service as PackageService, My\OtherPackage; My\OtherPackage; const APIKEY = 3; const APIKEY = 3; echo APIKEY; // 3 echo APIKEY; // 3 echo OtherPackage\APIKEY; // 2 echo OtherPackage\APIKEY; // 2 echo \My\Package\APIKEY; // 1 echo \My\Package\APIKEY; // 1 $s = new PackageService(); // My\Package\Service $s = new PackageService(); // My\Package\Service $s = new Service(); // E_FATAL (no match) $s = new Service(); // E_FATAL (no match) $s = new OtherPackage\Service(); $s = new OtherPackage\Service(); // My\OtherPackage\Service // My\OtherPackage\Service get($baz); get($baz); // E_FATAL (no matching function in // E_FATAL (no matching function in // current namespace) // current namespace) OtherPackage\get($baz); // My\OtherPackage\get() OtherPackage\get($baz); // My\OtherPackage\get()
All rights reserved. Zend Technologies, Inc.
Pitfalls
Classes, constants, and functions referenced in a string MUST be fully qualified No namespace separator prefix is necessary
Example 1
namespace My; namespace My; // Assume My\Log\Logger is a defined class // Assume My\Log\Logger is a defined class $class = 'Log\Logger'; $class = 'Log\Logger'; $o = new $class; // E_FATAL; can't find $o = new $class; // E_FATAL; can't find // relative names // relative names $class = 'My\Log\Logger'; $class = 'My\Log\Logger'; $o = new $class; // Success $o = new $class; // Success $class = '\My\Log\Logger'; $class = '\My\Log\Logger'; $o = new $class; // Also success, $o = new $class; // Also success, // but not necessary // but not necessary
All rights reserved. Zend Technologies, Inc.
Example 2
namespace My; namespace My; // Assume My\Log\Logger is a defined class // Assume My\Log\Logger is a defined class $class = 'Log\Logger'; $class = 'Log\Logger'; if ($o instanceof $class) { } // Fails; can't if ($o instanceof $class) { } // Fails; can't // resolve class // resolve class $class = 'My\Log\Logger'; $class = 'My\Log\Logger'; if ($o instanceof $class) { } // Success if ($o instanceof $class) { } // Success
Namespace separator has an affinity for the directory separator Suggests a 1:1 relationship with file system
namespace My\Log; namespace My\Log; class Logger {} class Logger {} /* My/Log/Logger.php (*nix) /* My/Log/Logger.php (*nix) My\Log\Logger.php (Windows) */ My\Log\Logger.php (Windows) */
Interfaces
Use cases:
interface Translator\Adapter in
Translator/Adapter.php
class Translator\Adapter\ConcreteAdapter in
Translator/Adapter/ConcreteAdapter.php
Readability
Readability
Readability
Dependency declarations
Suggestion: import every class outside the current namespace that you consume
namespace Application\Controller; namespace Application\Controller; use Zend\Controller\Action use Zend\Controller\Action as ActionController, as ActionController, My\ORM\Mapper as DataMapper, My\ORM\Mapper as DataMapper, My\Entity\BlogEntry, My\Entity\BlogEntry, Zend\EventManager\EventManager; Zend\EventManager\EventManager;
Dependency declarations
Imports are hints to the interpreter, and don't cost anything Helps to document dependencies up front Allows static analysis to determine dependencies
Resources
k Z L j 'y O W w M u F f p m a N 3 5 H P g s U I , o c T n Z . d v e s t h g i r l A
? p s m a W I , T Z . d v s h g r A 2 l n o i t c e S
/ : f u g y w " ? p s m a W I , T Z . d v s h g r A 3 l n o i t c e S
Basically, a language-supported mechanism for grouping these language features, as well as a language-supported mechanism for avoiding naming conflicts.
s a B I , T Z . d v s h g r A 4 l n o i t c e S
Namespace Separator
\
Get over it!
All rights reserved. Zend Technologies, Inc.
There are a ton of reasons why the backslash was used, ranging from length of token to position of the token on most keyboards to previous use of other tokens to understanding the scope of a given operator/operation visually. Just use it, and move along.
Declaring namespaces
You _can_ declare multiple namespaces in the same file in this way, but it's not recommended
Declaring namespaces
Block declaration
namespace Zend namespace Zend { { } } namespace Phly namespace Phly { { } }
This is the recommended way to declare multiple namespaces when in a single file.
Subnamespaces
Prefixing with a namespace separator resolves as a fully qualified name Resolution order:
Globally qualified: known; otherwise: Current namespace, or relative to it (Classes, functions, constants) Global namespace (functions, constants)
classes outside the current namespace must be referenced using a fully (globally) qualified name, or _imported_.
This means:
Importing namespaces
A way to bring code from another namespace into the current namespace. Import:
Importing namespaces
namespace My; namespace My; class Registry {} class Registry {} namespace Your; namespace Your; use My; // imports namespace use My; // imports namespace use My\Registry; // imports class use My\Registry; // imports class
Note: importing top-level namespaces in code with no namespace has no effect and results in a warning.
Aliasing
"import namespace or class, but refer to it using this name" PHP utilizes the as keyword to alias
Aliasing
namespace Your; namespace Your; use My as m; use My as m; $r = new m\Registry(); $r = new m\Registry(); namespace Your; namespace Your; use My\Registry as reg; use My\Registry as reg; $r = new reg(); $r = new reg();
With aliases
namespace Their; namespace Their; use My as m, // aliased use My as m, // aliased Your; // not aliased Your; // not aliased
__NAMESPACE__
Comprehensive example
The setup:
namespace My\Package; namespace My\Package; const APIKEY = 1; const APIKEY = 1; function get($data) {} function get($data) {} class Service {} class Service {} namespace My\OtherPackage; namespace My\OtherPackage; const APIKEY = 2; const APIKEY = 2; function get($data) {} function get($data) {} class Service {} class Service {}
Comprehensive example
namespace Test; namespace Test; use My\Package\Service as PackageService, use My\Package\Service as PackageService, My\OtherPackage; My\OtherPackage; const APIKEY = 3; const APIKEY = 3; echo APIKEY; // 3 echo APIKEY; // 3 echo OtherPackage\APIKEY; // 2 echo OtherPackage\APIKEY; // 2 echo \My\Package\APIKEY; // 1 echo \My\Package\APIKEY; // 1 $s == new PackageService(); // My\Package\Service $s new PackageService(); // My\Package\Service $s == new Service(); // E_FATAL (no match) $s new Service(); // E_FATAL (no match) $s == new OtherPackage\Service(); $s new OtherPackage\Service(); // My\OtherPackage\Service // My\OtherPackage\Service get($baz); get($baz); // E_FATAL (no matching function in // E_FATAL (no matching function in // current namespace) // current namespace) OtherPackage\get($baz); // My\OtherPackage\get() OtherPackage\get($baz); // My\OtherPackage\get()
All rights reserved. Zend Technologies, Inc.
s a f P I , T Z . d v s h g r A 7 2 l n o i t c e S
Classes, constants, and functions referenced in a string MUST be fully qualified No namespace separator prefix is necessary
Example 1
namespace My; namespace My; // Assume My\Log\Logger is a defined class // Assume My\Log\Logger is a defined class $class = 'Log\Logger'; $class = 'Log\Logger'; $o = new $class; // E_FATAL; can't find $o = new $class; // E_FATAL; can't find // relative names // relative names $class = 'My\Log\Logger'; $class = 'My\Log\Logger'; $o = new $class; // Success $o = new $class; // Success $class = '\My\Log\Logger'; $class = '\My\Log\Logger'; $o = new $class; // Also success, $o = new $class; // Also success, // but not necessary // but not necessary
All rights reserved. Zend Technologies, Inc.
Example 2
namespace My; namespace My; // Assume My\Log\Logger is a defined class // Assume My\Log\Logger is a defined class $class = 'Log\Logger'; $class = 'Log\Logger'; if ($o instanceof $class) { } // Fails; can't if ($o instanceof $class) { } // Fails; can't // resolve class // resolve class $class = 'My\Log\Logger'; $class = 'My\Log\Logger'; if ($o instanceof $class) { } // Success if ($o instanceof $class) { } // Success
? p m a s u y W I , T Z . d v s h g r A 1 3 l n o i t c e S
Namespace separator has an affinity for the directory separator Suggests a 1:1 relationship with file system
namespace My\Log; namespace My\Log; class Logger {} class Logger {} /* My/Log/Logger.php (*nix) /* My/Log/Logger.php (*nix) My\Log\Logger.php (Windows) */ My\Log\Logger.php (Windows) */
Interfaces
Use cases:
interface Translator\Adapter in
Translator/Adapter.php
class Translator\Adapter\ConcreteAdapter in
Translator/Adapter/ConcreteAdapter.php
Readability
Readability
Readability
Dependency declarations
Suggestion: import every class outside the current namespace that you consume
namespace Application\Controller; namespace Application\Controller; use Zend\Controller\Action use Zend\Controller\Action as ActionController, as ActionController, My\ORM\Mapper as DataMapper, My\ORM\Mapper as DataMapper, My\Entity\BlogEntry, My\Entity\BlogEntry, Zend\EventManager\EventManager; Zend\EventManager\EventManager;
Dependency declarations
Imports are hints to the interpreter, and don't cost anything Helps to document dependencies up front Allows static analysis to determine dependencies
u s R I , T Z . d v s h g r A 1 4 l n o i t c e S