You are on page 1of 84
Using PHP 5.3 Namespaces for Fame and Fortune Matthew Weier O'Phinney Project Lead, Zend Framework

Using PHP 5.3 Namespaces for Fame and Fortune

Using PHP 5.3 Namespaces for Fame and Fortune Matthew Weier O'Phinney Project Lead, Zend Framework ©

Matthew Weier O'Phinney Project Lead, Zend Framework

© All rights reserved. Zend Technologies, Inc.

What are “namespaces”?

What are “namespaces”? © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

What are “namespaces”? © All rights reserved. Zend Technologies, Inc.

What are “namespaces”?

"A way in which to group related classes, functions and constants"

– http://php.net/namespace

related classes, functions and constants" – http://php.net/namespace © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

related classes, functions and constants" – http://php.net/namespace © All rights reserved. Zend Technologies, Inc.

Basics

Basics © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

Basics © All rights reserved. Zend Technologies, Inc.

Namespace Separator

“\”

Get over it!

Namespace Separator “\” Get over it! © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

Namespace Separator “\” Get over it! © All rights reserved. Zend Technologies, Inc.

What can live in namespaces

Classes

Constants

Functions

What can live in namespaces ● Classes ● Constants ● Functions © All rights reserved. Zend

© All rights reserved. Zend Technologies, Inc.

What can live in namespaces ● Classes ● Constants ● Functions © All rights reserved. Zend

Declaring namespaces

Single line declaration

namespace namespace Zend; Zend;
namespace namespace Zend; Zend;
namespaces ● Single line declaration namespace namespace Zend; Zend; © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

namespaces ● Single line declaration namespace namespace Zend; Zend; © All rights reserved. Zend Technologies, Inc.

Declaring namespaces

Block declaration

namespace namespace Zend Zend

{

{

}

}

namespace namespace Phly Phly

{

{

}

}

{ { } } namespace namespace Phly Phly { { } } © All rights reserved.

© All rights reserved. Zend Technologies, Inc.

{ { } } namespace namespace Phly Phly { { } } © All rights reserved.

Subnamespaces

Separate the subnamespaces using the namespace separator

namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;
namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;
namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;

namespace namespace Zend\Log; Zend\Log;

namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;
namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;

namespace namespace Zend\Log\Writer; Zend\Log\Writer;

namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;
namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;
namespace namespace Zend\Log; Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer;
Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer; © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

Zend\Log; namespace namespace Zend \Log\Writer; Zend\Log\Writer; © All rights reserved. Zend Technologies, Inc.

Referring to namespaced elements

From non-namespaced code:

$class $class = = new new My\Registry(); My\Registry(); $class $class = = new new My\Log\Logger();
$class $class = = new new My\Registry(); My\Registry();
$class $class = = new new My\Log\Logger(); My\Log\Logger();
My\str_split($s); My\str_split($s); // // function function call call
$val $val = = My\APIKEY; My\APIKEY; // // constant constant value value
$val $val = = My\APIKEY; My\APIKEY; // // constant constant value value © All rights reserved.

© All rights reserved. Zend Technologies, Inc.

$val $val = = My\APIKEY; My\APIKEY; // // constant constant value value © All rights reserved.

Referring to namespaced elements

From code using the same namespace:

namespace namespace My; My; $class $class = = new new Registry(); Registry(); $class $class =
namespace namespace My; My;
$class $class = = new new Registry(); Registry();
$class $class = = new new Log\Logger(); Log\Logger();
str_split($s); str_split($s); // // function function call call
$val $val = = APIKEY; APIKEY; // // constant constant value value
call $val $val = = APIKEY; APIKEY; // // constant constant value value © All rights

© All rights reserved. Zend Technologies, Inc.

call $val $val = = APIKEY; APIKEY; // // constant constant value value © All rights

Referring to namespaced elements

From code in a different namespace:

namespace namespace Your; Your; $class $class = = new new \My\Registry(); \My\Registry(); $class $class =
namespace namespace Your; Your;
$class $class = = new new \My\Registry(); \My\Registry();
$class $class = = new new \My\Log\Logger(); \My\Log\Logger();
\My\str_split($s); \My\str_split($s); // // function function call call
$val $val = = \My\APIKEY; \My\APIKEY; // // constant constant value value
$val $val = = \My\APIKEY; \My\APIKEY; // // constant constant value value © All rights reserved.

© All rights reserved. Zend Technologies, Inc.

$val $val = = \My\APIKEY; \My\APIKEY; // // constant constant value value © All rights reserved.

Using namespaced code:

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)

functions, constants) ▶ Global namespace (functions, constants) © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

functions, constants) ▶ Global namespace (functions, constants) © All rights reserved. Zend Technologies, Inc.

This means:

You can override system functions within namespaces!

namespace namespace My; My;

function function str_split($string, str_split($string, $splitlen $splitlen = = 2) 2)

{

}

{

}

 

return return preg_split('/\W/', preg_split('/\W/', $string, $string, $splitlen); $splitlen);

$a $a = = str_split("Foo, str_split("Foo, Bar"); Bar"); // // invokes invokes My\str_split() My\str_split() /* /* array array ( (

 

*

*

0 0 => => 'Foo', 'Foo',

1 1 => => ' ' Bar', Bar',

*

*

*

*

)

*/ */

)

' Bar', Bar', * * * * ) */ */ ) © All rights reserved. Zend

© All rights reserved. Zend Technologies, Inc.

' Bar', Bar', * * * * ) */ */ ) © All rights reserved. Zend

Importing namespaces

A way to bring code from another namespace into the current namespace.

Import:

Classes

Other namespaces

Keyword used is use

● Import: ▶ Classes ▶ Other namespaces ● Keyword used is use © All rights reserved.

© All rights reserved. Zend Technologies, Inc.

● Import: ▶ Classes ▶ Other namespaces ● Keyword used is use © All rights reserved.

Importing namespaces

namespace namespace My; My; class class Registry Registry {} {} namespace namespace Your; Your; use
namespace namespace My; My;
class class Registry Registry {} {}
namespace namespace Your; Your;
use use My; My;
// // imports imports namespace namespace
use use My\Registry; My\Registry; // // imports imports class class
use use My\Registry; My\Registry; // // imports imports class class © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

use use My\Registry; My\Registry; // // imports imports class class © All rights reserved. Zend Technologies,

Using imported code

namespace namespace Your; Your;

use use My; My;

// // imports imports namespace namespace

$r $r = = new new My\Registry(); My\Registry();

namespace namespace Your; Your;

use use My\Registry; My\Registry; // // imports imports class class

$r $r = = new new Registry(); Registry();

imports class class $r $r = = new new Registry (); Registry(); © All rights reserved.

© All rights reserved. Zend Technologies, Inc.

imports class class $r $r = = new new Registry (); Registry(); © All rights reserved.

Aliasing

"import namespace or class, but refer to it using this name"

PHP utilizes the as keyword to alias

to it using this name" ● PHP utilizes the as keyword to alias © All rights

© All rights reserved. Zend Technologies, Inc.

to it using this name" ● PHP utilizes the as keyword to alias © All rights

Aliasing

namespace namespace Your; Your; use use My My as as m; m; $r $r =
namespace namespace Your; Your;
use use My My as as m; m;
$r $r = = new new m\Registry(); m\Registry();
namespace namespace Your; Your;
use use My\Registry My\Registry as as reg; reg;
$r $r = = new new reg(); reg();
My\Registry My\Registry as as reg; reg; $r $r = = new new reg(); reg(); © All

© All rights reserved. Zend Technologies, Inc.

My\Registry My\Registry as as reg; reg; $r $r = = new new reg(); reg(); © All

Make typehinting more semantic!

namespace namespace App; App; use use Zend\EventManager\EventManager Zend\EventManager\EventManager as as Events; Events;

class class Foo Foo

{ {

public public function function events(Events events(Events $events $events = = null) null)

{

{

if if ($events ($events instanceof instanceof Events) Events) { { $this->events $this->events = = $events; $events;

} } elseif elseif (!$this->events (!$this->events instanceof instanceof Events) Events) { {

$this->events = new Events( CLASS

$this->events = new

Events(

CLASS

} }

return return $this->events; $this->events;

); );

} }

} }

return $this ->events; $this ->events; ); ); } } } } © All rights reserved. Zend

© All rights reserved. Zend Technologies, Inc.

return $this ->events; $this ->events; ); ); } } } } © All rights reserved. Zend

Importing multiple namespaces/classes

Multiple use statements

namespace namespace Their; Their; use use My ; My; use use Your ; Your;
namespace namespace Their; Their; use use My ; My; use use Your ; Your;
namespace namespace Their; Their; use use My ; My; use use Your ; Your;

namespace namespace Their; Their; use use My; My; use use Your; Your;

namespace namespace Their; Their; use use My ; My; use use Your ; Your;
namespace namespace Their; Their; use use My ; My; use use Your ; Your;
namespace namespace Their; Their; use use My ; My; use use Your ; Your;
namespace Their; Their; use use My ; My; use use Your ; Your; © All rights

© All rights reserved. Zend Technologies, Inc.

namespace Their; Their; use use My ; My; use use Your ; Your; © All rights

Importing multiple namespaces/classes

Or use a comma (“,”) to separate statements

namespace namespace Their; Their; use use My , My, Your; Your;
namespace namespace Their; Their; use use My , My, Your; Your;
namespace namespace Their; Their; use use My , My, Your; Your;

namespace namespace Their; Their; use use My, My, Your; Your;

namespace namespace Their; Their; use use My , My, Your; Your;
namespace namespace Their; Their; use use My , My, Your; Your;
namespace namespace Their; Their; use use My , My, Your; Your;
namespace namespace Their; Their; use use My , My, Your; Your; © All rights reserved. Zend

© All rights reserved. Zend Technologies, Inc.

namespace namespace Their; Their; use use My , My, Your; Your; © All rights reserved. Zend

Importing multiple namespaces/classes

With aliases

namespace namespace Their; Their;

use use My My as as m, m, // // aliased aliased

Your; Your;

// // not not aliased aliased

aliased aliased Your; Your; // // not not aliased aliased © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

aliased aliased Your; Your; // // not not aliased aliased © All rights reserved. Zend Technologies,

What namespace are you in?

NAMESPACE

What namespace are you in? ● NAMESPACE © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

What namespace are you in? ● NAMESPACE © All rights reserved. Zend Technologies, Inc.

Comprehensive example

The setup:

namespace namespace My\Package; My\Package; const const APIKEY APIKEY = = 1; 1; function function get($data)
namespace namespace My\Package; My\Package;
const const APIKEY APIKEY = = 1; 1;
function function get($data) get($data) {} {}
class class Service Service {} {}
namespace namespace My\OtherPackage; My\OtherPackage;
const const APIKEY APIKEY = = 2; 2;
function function get($data) get($data) {} {}
class class Service Service {} {}
function get($data) get($data) {} {} class class Service Service {} {} © All rights reserved. Zend

© All rights reserved. Zend Technologies, Inc.

function get($data) get($data) {} {} class class Service Service {} {} © All rights reserved. Zend

Comprehensive example

namespace namespace Test; Test; use use My\Package\Service My\Package\Service as as PackageService, PackageService, My\OtherPackage; My\OtherPackage;

const const APIKEY APIKEY = = 3; 3; echo echo APIKEY; APIKEY;

echo echo OtherPackage\APIKEY; OtherPackage\APIKEY; // // 2 2 echo echo \My\Package\APIKEY; \My\Package\APIKEY; // // 1 1

// // 3 3

$s $s = = new new PackageService(); PackageService(); // // My\Package\Service My\Package\Service

$s $s = = new new Service(); Service();

$s $s = = new new OtherPackage\Service(); OtherPackage\Service(); // // My\OtherPackage\Service My\OtherPackage\Service

// // E_FATAL E_FATAL (no (no match) match)

get($baz); get($baz);

// // current current namespace) namespace) OtherPackage\get($baz); OtherPackage\get($baz); // // My\OtherPackage\get() My\OtherPackage\get()

// // E_FATAL E_FATAL (no (no matching matching function function in in

E_FATAL E_FATAL (no (no matching matching function function in in © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

E_FATAL E_FATAL (no (no matching matching function function in in © All rights reserved. Zend Technologies,

Pitfalls

Pitfalls © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

Pitfalls © All rights reserved. Zend Technologies, Inc.

Referencing namespaced code in strings

Classes, constants, and functions referenced in a string MUST be fully qualified

No namespace separator prefix is necessary

MUST be fully qualified ● No namespace separator prefix is necessary © All rights reserved. Zend

© All rights reserved. Zend Technologies, Inc.

MUST be fully qualified ● No namespace separator prefix is necessary © All rights reserved. Zend

Referencing namespaced code in strings

Example 1

namespace namespace My; My; // // Assume Assume My\Log\Logger My\Log\Logger is is a a defined defined class class

$class $class = = 'Log\Logger'; 'Log\Logger';

$o $o

= = new new $class; $class; // // E_FATAL; E_FATAL; can't can't find find // // relative relative names names

$class $class = = 'My\Log\Logger'; 'My\Log\Logger';

$o $o

= = new new $class; $class; // // Success Success

$class $class = = '\My\Log\Logger'; '\My\Log\Logger';

$o $o

= = new new $class; $class; // // Also Also success, success,

// // but but not not necessary necessary

success, success, // // but but not not necessary necessary © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

success, success, // // but but not not necessary necessary © All rights reserved. Zend Technologies,

Referencing namespaced code in strings

Example 2

namespace namespace My; My; // // Assume Assume My\Log\Logger My\Log\Logger is is a a defined
namespace namespace My; My;
// // Assume Assume My\Log\Logger My\Log\Logger is is a a defined defined class class
$class $class = = 'Log\Logger'; 'Log\Logger';
if if ($o ($o instanceof instanceof $class) $class) { { } } // // Fails; Fails; can't can't
// // resolve resolve class class
$class $class = = 'My\Log\Logger'; 'My\Log\Logger';
if if ($o ($o instanceof instanceof $class) $class) { { } } // // Success Success
($o instanceof instanceof $class) $class) { { } } // // Success Success © All rights

© All rights reserved. Zend Technologies, Inc.

($o instanceof instanceof $class) $class) { { } } // // Success Success © All rights

Why use namespaces?

Why use namespaces? © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

Why use namespaces? © All rights reserved. Zend Technologies, Inc.

Code Organization: Filesystem

Namespace separator has an affinity for the directory separator

Suggests a 1:1 relationship with file system

namespace namespace My\Log; My\Log; class class Logger Logger {} {} /* /* My/Log/Logger.php My/Log/Logger.php (*nix)
namespace namespace My\Log; My\Log;
class class Logger Logger {} {}
/* /* My/Log/Logger.php My/Log/Logger.php (*nix) (*nix)
My\Log\Logger.php My\Log\Logger.php (Windows) (Windows) */ */
(*nix) My\Log\Logger.php My\Log\Logger.php (Windows) (Windows) */ */ © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

(*nix) My\Log\Logger.php My\Log\Logger.php (Windows) (Windows) */ */ © All rights reserved. Zend Technologies, Inc.

Code Organization: By Responsibility

Interfaces

Use cases:

instanceof: $class instanceof Adapter implements: SomeClass implements Adapter

Natural language is easiest to understand

Natural language suggests a hierarchy

is easiest to understand ▶ Natural language suggests a hierarchy © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

is easiest to understand ▶ Natural language suggests a hierarchy © All rights reserved. Zend Technologies,

Code Organization: By Responsibility

namespace namespace Translator\Adapter; Translator\Adapter; use use Translator\Adapter; Translator\Adapter; class class
namespace namespace Translator\Adapter; Translator\Adapter;
use use Translator\Adapter; Translator\Adapter;
class class ConcreteAdapter ConcreteAdapter implements implements Adapter Adapter
{} {}

interface Translator\Adapter in Translator/Adapter.php

class Translator\Adapter\ConcreteAdapter in Translator/Adapter/ConcreteAdapter.php

in Translator/Adapter/ConcreteAdapter.php © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

in Translator/Adapter/ConcreteAdapter.php © All rights reserved. Zend Technologies, Inc.

Code Organization: By Responsibility

Takeaway: we're referencing the capabilities, not the language type

Takeaway: we're referencing the capabilities , not the language type © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

Takeaway: we're referencing the capabilities , not the language type © All rights reserved. Zend Technologies,

Readability

When within a namespace, reference classes directly, keeping usage succinct

namespace namespace Zend\Http; Zend\Http; $client $client = = new new Client(); Client();
namespace namespace Zend\Http; Zend\Http;
$client $client = = new new Client(); Client();
Zend\Http; Zend\Http; $client $client = = new new Client(); Client(); © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

Zend\Http; Zend\Http; $client $client = = new new Client(); Client(); © All rights reserved. Zend Technologies,

Readability

Importing and aliasing make names more succinct

namespace namespace Application; Application; use use Zend\Http\Client Zend\Http\Client as as HttpClient, HttpClient,
namespace namespace Application; Application;
use use Zend\Http\Client Zend\Http\Client as as HttpClient, HttpClient,
Zend\Logger\Logger; Zend\Logger\Logger;
$client $client = = new new HttpClient(); HttpClient();
$log $log
= = new new Logger(); Logger();
HttpClient(); HttpClient(); $log $log = = new new Logger(); Logger(); © All rights reserved. Zend Technologies,

© All rights reserved. Zend Technologies, Inc.

HttpClient(); HttpClient(); $log $log = = new new Logger(); Logger(); © All rights reserved. Zend Technologies,

Readability

Aliasing allows giving names context

namespace namespace Application\Controller; Application\Controller; use use Zend\Controller\Action Zend\Controller\Action
namespace namespace Application\Controller; Application\Controller;
use use Zend\Controller\Action Zend\Controller\Action
as as ActionController; ActionController;
class class FooController FooController
extends extends ActionController ActionController {} {}
FooController extends extends ActionController ActionController {} {} © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

FooController extends extends ActionController ActionController {} {} © All rights reserved. Zend Technologies, Inc.

Dependency declarations

Suggestion: import every class outside the current namespace that you consume

namespace namespace Application\Controller; Application\Controller; use use Zend\Controller\Action Zend\Controller\Action
namespace namespace Application\Controller; Application\Controller;
use use Zend\Controller\Action Zend\Controller\Action
as as ActionController, ActionController,
My\ORM\Mapper My\ORM\Mapper as as DataMapper, DataMapper,
My\Entity\BlogEntry, My\Entity\BlogEntry,
Zend\EventManager\EventManager; Zend\EventManager\EventManager;
Zend\EventManager\EventManager; Zend\EventManager\EventManager; © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

Zend\EventManager\EventManager; Zend\EventManager\EventManager; © All rights reserved. Zend Technologies, Inc.

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

up front ● Allows static analysis to determine dependencies © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

up front ● Allows static analysis to determine dependencies © All rights reserved. Zend Technologies, Inc.

Resources

Resources © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

Resources © All rights reserved. Zend Technologies, Inc.

PHP Manual: http://php.net/namespace

● PHP Manual: http://php.net/namespace © All rights reserved. Zend Technologies, Inc.

© All rights reserved. Zend Technologies, Inc.

● PHP Manual: http://php.net/namespace © All rights reserved. Zend Technologies, Inc.

Basically, a language-supported mechanism for grouping these language features, as well as a language-supported mechanism for avoiding naming conflicts.

Namespace Separator

“\”

Get over it!

© All rights reserved. Zend Technologies, Inc.
© 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.

What can live in namespaces

Classes

Constants

Functions

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Declaring namespaces

Single line declaration

namespace namespace Zend; Zend;
namespace namespace Zend; Zend;
© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

You _can_ declare multiple namespaces in the same file in this way, but it's not recommended

Declaring namespaces

Block declaration

namespace namespace Zend Zend

{

} }

{

namespace namespace Phly Phly

{

} }

{

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

This is the recommended way to declare multiple namespaces when in a single file.

Subnamespaces

Separate the subnamespaces using the namespace separator

namespace namespace Zend\Log; Zend\Log;

namespace namespace Zend\Log\Writer; Zend\Log\Writer;

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Referring to namespaced elements

From non-namespaced code:

$class $class = = new new My\Registry(); My\Registry();

$class $class = = new new My\Log\Logger(); My\Log\Logger();

My\str_split($s); My\str_split($s); // // function function call call

$val $val = = My\APIKEY; My\APIKEY; // // constant constant value value

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Referring to namespaced elements

From code using the same namespace:

namespace namespace My; My;

$class $class = = new new Registry(); Registry();

$class $class = = new new Log\Logger(); Log\Logger();

str_split($s); str_split($s); // // function function call call

$val $val = = APIKEY; APIKEY; // // constant constant value value

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Referring to namespaced elements

From code in a different namespace:

namespace namespace Your; Your;

$class $class = = new new \My\Registry(); \My\Registry();

$class $class = = new new \My\Log\Logger(); \My\Log\Logger();

\My\str_split($s); \My\str_split($s); // // function function call call

$val $val = = \My\APIKEY; \My\APIKEY; // // constant constant value value

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Using namespaced code:

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)

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

classes outside the current namespace must be referenced using a fully (globally) qualified name, or _imported

This means:

You can override system functions within namespaces!

namespace namespace My; My;

function function str_split($string, str_split($string, $splitlen $splitlen = = 2) 2)

{

{

} }

return return preg_split('/\W/', preg_split('/\W/', $string, $string, $splitlen); $splitlen);

$a $a = = str_split("Foo, str_split("Foo, Bar"); Bar"); // // invokes invokes My\str_split() My\str_split() /* /* array array ( (

*

*

)

*/ */

*

* 0 0 => => 'Foo', 'Foo',

* 1 1 => => ' ' Bar', Bar',

*

)

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Importing namespaces

A way to bring code from another namespace into the current namespace.

Import:

Classes

Other namespaces

Keyword used is use

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Importing namespaces

namespace namespace My; My; class class Registry Registry {} {}

namespace namespace Your; Your; use use My; My;

use use My\Registry; My\Registry; // // imports imports class class

// // imports imports namespace namespace

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Note: importing top-level namespaces in code with no namespace has no effect and results in a warning.

Using imported code

namespace namespace Your; Your;

use use My; My;

$r $r = = new new My\Registry(); My\Registry();

// // imports imports namespace namespace

namespace namespace Your; Your;

use use My\Registry; My\Registry; // // imports imports class class

$r $r = = new new Registry(); Registry();

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Aliasing

"import namespace or class, but refer to it using this name"

PHP utilizes the as keyword to alias

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Aliasing

namespace namespace Your; Your; use use My My as as m; m; $r $r = = new new m\Registry(); m\Registry();

namespace namespace Your; Your;

use use My\Registry My\Registry as as reg; reg;

$r $r = = new new reg(); reg();

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Make typehinting more semantic!

namespace namespace App; App; use use Zend\EventManager\EventManager Zend\EventManager\EventManager as as Events; Events;

class class Foo Foo

{ {

} }

public public function function events(Events events(Events $events $events = = null) null)

{

{

if if ($events ($events instanceof instanceof Events) Events) { { $this->events $this->events = = $events; $events;

} } elseif elseif (!$this->events (!$this->events instanceof instanceof Events) Events) { {

$this->events = new Events( CLASS

$this->events = new

Events( CLASS );

);

} }

return return $this->events; $this->events;

} }

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Importing multiple namespaces/classes

Multiple use statements

namespace namespace Their; Their; use use My; My; use use Your; Your;

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Importing multiple namespaces/classes

Or use a comma (“,”) to separate statements

namespace namespace Their; Their; use use My, My, Your; Your;

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Importing multiple namespaces/classes

With aliases

namespace namespace Their; Their;

use use My My as as m, m, // // aliased aliased

Your; Your;

// // not not aliased aliased

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

What namespace are you in?

NAMESPACE

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Comprehensive example

The setup:

namespace namespace My\Package; My\Package;

const const APIKEY APIKEY = = 1; 1; function function get($data) get($data) {} {} class class Service Service {} {}

namespace namespace My\OtherPackage; My\OtherPackage; const const APIKEY APIKEY = = 2; 2;

function function get($data) get($data) {} {} class class Service Service {} {}

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Comprehensive example

namespace namespace Test; Test; use use My\Package\Service My\Package\Service as as PackageService, PackageService, My\OtherPackage; My\OtherPackage;

const const APIKEY APIKEY = = 3; 3; echo echo APIKEY; APIKEY;

echo echo OtherPackage\APIKEY; OtherPackage\APIKEY; // // 2 2 echo echo \My\Package\APIKEY; \My\Package\APIKEY; // // 1 1

// // 3 3

$s $s = = new new PackageService(); PackageService(); // // My\Package\Service My\Package\Service

$s $s = = new new Service(); Service();

$s $s = = new new OtherPackage\Service(); OtherPackage\Service(); // // My\OtherPackage\Service My\OtherPackage\Service

// // E_FATAL E_FATAL (no (no match) match)

get($baz); get($baz);

// // current current namespace) namespace) OtherPackage\get($baz); OtherPackage\get($baz); // // My\OtherPackage\get() My\OtherPackage\get()

// // E_FATAL E_FATAL (no (no matching matching function function in in

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Referencing namespaced code in strings

Classes, constants, and functions referenced in a string MUST be fully qualified

No namespace separator prefix is necessary

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Referencing namespaced code in strings

Example 1

namespace namespace My; My; // // Assume Assume My\Log\Logger My\Log\Logger is is a a defined defined class class

$class $class = = 'Log\Logger'; 'Log\Logger';

$o $o

= = new new $class; $class; // // E_FATAL; E_FATAL; can't can't find find // // relative relative names names

$class $class = = 'My\Log\Logger'; 'My\Log\Logger';

$o $o

= = new new $class; $class; // // Success Success

$class $class = = '\My\Log\Logger'; '\My\Log\Logger';

$o $o

= = new new $class; $class; // // Also Also success, success,

// // but but not not necessary necessary

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Referencing namespaced code in strings

Example 2

namespace namespace My; My; // // Assume Assume My\Log\Logger My\Log\Logger is is a a defined defined class class

$class $class = = 'Log\Logger'; 'Log\Logger';

if if ($o ($o instanceof instanceof $class) $class) { { } } // // Fails; Fails; can't can't // // resolve resolve class class

$class $class = = 'My\Log\Logger'; 'My\Log\Logger';

if if ($o ($o instanceof instanceof $class) $class) { { } } // // Success Success

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Code Organization: Filesystem

Namespace separator has an affinity for the directory separator

Suggests a 1:1 relationship with file system

namespace namespace My\Log; My\Log;

class class Logger Logger {} {} /* /* My/Log/Logger.php My/Log/Logger.php (*nix) (*nix)

My\Log\Logger.php My\Log\Logger.php (Windows) (Windows) */ */

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Code Organization: By Responsibility

Interfaces

Use cases:

instanceof: $class instanceof Adapter implements: SomeClass implements Adapter

Natural language is easiest to understand

Natural language suggests a hierarchy

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Code Organization: By Responsibility

namespace namespace Translator\Adapter; Translator\Adapter;

use use Translator\Adapter; Translator\Adapter;

class class ConcreteAdapter ConcreteAdapter implements implements Adapter Adapter {} {}

interface Translator\Adapter in Translator/Adapter.php

class Translator\Adapter\ConcreteAdapter in Translator/Adapter/ConcreteAdapter.php

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Code Organization: By Responsibility

Takeaway: we're referencing the capabilities, not the language type

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Readability

When within a namespace, reference classes directly, keeping usage succinct

namespace namespace Zend\Http; Zend\Http;

$client $client = = new new Client(); Client();

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Readability

Importing and aliasing make names more succinct

namespace namespace Application; Application;

use use Zend\Http\Client Zend\Http\Client as as HttpClient, HttpClient,

Zend\Logger\Logger; Zend\Logger\Logger;

$client $client = = new new HttpClient(); HttpClient();

$log $log

= = new new Logger(); Logger();

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Readability

Aliasing allows giving names context

namespace namespace Application\Controller; Application\Controller;

use use Zend\Controller\Action Zend\Controller\Action as as ActionController; ActionController;

class class FooController FooController extends extends ActionController ActionController {} {}

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Dependency declarations

Suggestion: import every class outside the current namespace that you consume

namespace namespace Application\Controller; Application\Controller;

use use Zend\Controller\Action Zend\Controller\Action as as ActionController, ActionController,

My\ORM\Mapper My\ORM\Mapper as as DataMapper, DataMapper,

My\Entity\BlogEntry, My\Entity\BlogEntry,

Zend\EventManager\EventManager; Zend\EventManager\EventManager;

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

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

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.

Click to add title

PHP Manual: http://php.net/namespace

© All rights reserved. Zend Technologies, Inc.
© All rights reserved. Zend Technologies, Inc.