From 76640844cfac8e3f295b7af860e3db882ed27d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nilg=C3=BCn=20Belma=20Bug=C3=BCner?= <nilgun@php.net> Date: Wed, 26 Nov 2008 01:48:48 +0000 Subject: [PATCH] fix validity error and WS git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@269850 c90b9560-bf6c-de11-be94-00142212c4b1 --- language/namespaces.xml | 2981 +++++++++++++++++++-------------------- 1 file changed, 1490 insertions(+), 1491 deletions(-) diff --git a/language/namespaces.xml b/language/namespaces.xml index bd8e9a000e..43541f3b4a 100644 --- a/language/namespaces.xml +++ b/language/namespaces.xml @@ -1,1491 +1,1490 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- $Revision: 1.5 $ --> -<chapter xml:id="language.namespaces" xmlns="http://docbook.org/ns/docbook" - version="1.1"> - <title>Namespaces</title> - - <sect1 xml:id="language.namespaces.rationale"> - <title>Namespaces overview</title> - <simpara> - What are namespaces? In the broadest definition namespaces are a way of encapsulating - items. This can be seen as an abstract concept in many places. For example, in any - operating system directories serve to group related files, and act as a namespace for - the files within them. As a concrete example, the file <literal>foo.txt</literal> can - exist in both directory <literal>/home/greg</literal> and in <literal>/home/other</literal>, - but two copies of <literal>foo.txt</literal> cannot co-exist in the same directory. In - addition, to access the <literal>foo.txt</literal> file outside of the - <literal>/home/greg</literal> directory, we must prepend the directory name to the file - name using the directory separator to get <literal>/home/greg/foo.txt</literal>. This - same principle extends to namespaces in the programming world. - </simpara> - <simpara> - In the PHP world, namespaces are designed to solve two problems that authors - of libraries and applications encounter when creating re-usable code elements - such as classes or functions: - </simpara> - <para> - <orderedlist> - <listitem> - <simpara> - Name collisions between code you create, and - internal PHP classes/functions/constants or third-party classes/functions/constants. - </simpara> - </listitem> - <listitem> - <simpara> - Ability to alias (or shorten) Extra_Long_Names designed to alleviate the first problem, - improving readability of source code. - </simpara> - </listitem> - </orderedlist> - </para> - <simpara> - PHP Namespaces provide a way in which to group related classes, - functions and constants. Here is an example of namespace syntax in PHP: - </simpara> - <programlisting role="php"> - <![CDATA[ -<?php -namespace my\name; // see "Defining Namespaces" section - -class MyClass {} -function myfunction() {} -const MYCONST = 1; - -$a = new MyClass; -$c = new \my\name\MyClass; // see "Global Space" section - -$a = strlen('hi'); // see "Using namespaces: fallback to global - // function/constant" section - -$d = namespace\MYCONST; // see "namespace operator and __NAMESPACE__ - // constant" section -$d = __NAMESPACE__ . '\MYCONST'; -echo constant($d); // see "Namespaces and dynamic language features" section -?> - ]]> - </programlisting> - <simpara> - Namespaces are available in PHP as of PHP 5.3.0. - </simpara> - </sect1> - - <sect1 xml:id="language.namespaces.definition"> - <title>Defining namespaces</title> - <para> - Although any valid PHP code can be contained within a namespace, only three - type of code are affected by namespaces: classes, functions and constants. - </para> - <para> - Namespaces are declared using the <literal>namespace</literal> - keyword. A file containing a namespace must declare the namespace - at the top of the file before any other code. - <example> - <title>Declaring a single namespace</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject; - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } - -?> -]]> - </programlisting> - </example> - The only code construct allowed before a namespace declaration is the - <literal>declare</literal> statement, for defining encoding of a source file. In addition, - no non-PHP code may precede a namespace declaration, including extra whitespace: - <example> - <title>Declaring a single namespace</title> - <programlisting role="php"> - <![CDATA[ -<html> -<?php -namespace MyProject; // fatal error - namespace must be the first statement in the script -?> -]]> - </programlisting> - </example> - </para> - <para> - In addition, unlike any other PHP construct, the same namespace may be defined - in multiple files, allowing splitting up of a namespace's contents across the filesystem. - </para> - </sect1> - <sect1 xml:id="language.namespaces.nested"> - <title>Declaring sub-namespaces</title> - <para> - Much like directories and files, PHP namespaces also contain the ability to specify - a hierarchy of namespace names. Thus, a namespace name can be defined with - sub-levels: - <example> - <title>Declaring a single namespace with hierarchy</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject\Sub\Level; - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } - -?> -]]> - </programlisting> - </example> - The above example creates constant <literal>MyProject\Sub\Level\CONNECT_OK</literal>, - class <literal>MyProject\Sub\Level\Connection</literal> and function - <literal>MyProject\Sub\Level\Connection</literal>. - </para> - </sect1> - <sect1 xml:id="language.namespaces.definitionmultiple"> - <title>Defining multiple namespaces in the same file</title> - <para> - Multiple namespaces may also be declared in the same file. There are two allowed - syntaxes. - </para> - <para> - <example> - <title>Declaring multiple namespaces, simple combination syntax</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject; - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } - -namespace AnotherProject; - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } -?> -]]> - </programlisting> - </example> - </para> - <para> - This syntax is not recommended for combining namespaces into a single file. - Instead it is recommended to use the alternate bracketed syntax. - </para> - <para> - <example> - <title>Declaring multiple namespaces, bracketed syntax</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject { - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } -} - -namespace AnotherProject { - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } -} -?> -]]> - </programlisting> - </example> - </para> - <para> - It is strongly discouraged as a coding practice to combine multiple namespaces into - the same file. The primary use case is to combine multiple PHP scripts into the same - file. - <para> - </para> - To combine global non-namespaced code with namespaced code, only bracketed syntax is - supported. Global code should be - encased in a namespace statement with no namespace name as in: - <example> - <title>Declaring multiple namespaces and unnamespaced code</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject { - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } -} - -namespace { // global code -session_start(); -$a = MyProject\connect(); -echo MyProject\Connection::start(); -} -?> -]]> - </programlisting> - </example> - </para> - <para> - No PHP code may exist outside of the namespace brackets except for an opening - declare statement. - <example> - <title>Declaring multiple namespaces and unnamespaced code</title> - <programlisting role="php"> - <![CDATA[ -<?php -declare(encoding='UTF-8'); -namespace MyProject { - -const CONNECT_OK = 1; -class Connection { /* ... */ } -function connect() { /* ... */ } -} - -namespace { // global code -session_start(); -$a = MyProject\connect(); -echo MyProject\Connection::start(); -} -?> -]]> - </programlisting> - </example> - </para> - </sect1> - <sect1 xml:id="language.namespaces.basics"> - <title>Using namespaces: Basics</title> - <para> - Before discussing the use of namespaces, it is important to understand how PHP - knows which namespaced element your code is requesting. A simple analogy can be made - between PHP namespaces and a filesystem. There are three ways to access a file in a - file system: - <orderedlist> - <listitem> - <simpara> - Relative file name like <literal>foo.txt</literal>. This resolves to - <literal>currentdirectory/foo.txt</literal> where currentdirectory is the - directory currently occupied. So if the current directory is - <literal>/home/foo</literal>, the name resolves to <literal>/home/foo/foo.txt</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - Relative path name like <literal>subdirectory/foo.txt</literal>. This resolves - to <literal>currentdirectory/subdirectory/foo.txt</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - Absolute path name like <literal>/main/foo.txt</literal>. This resolves - to <literal>/main/foo.txt</literal>. - </simpara> - </listitem> - </orderedlist> - The same principle can be applied to namespaced elements in PHP. For - example, a class name can be referred to in three ways: - <orderedlist> - <listitem> - <simpara> - Unqualified name, or an unprefixed class name like - <literal>$a = new foo();</literal> or - <literal>foo::staticmethod();</literal>. If the current namespace is - <literal>currentnamespace</literal>, this resolves to - <literal>currentnamespace\foo</literal>. If - the code is global, non-namespaced code, this resolves to <literal>foo</literal>. - </simpara> - <simpara> - One caveat: unqualified names for functions and constants will - resolve to global functions and constants if the namespaced function or constant - is not defined. See <link linkend="language.namespaces.fallback">Using namespaces: - fallback to global function/constant</link> for details. - </simpara> - </listitem> - <listitem> - <simpara> - Qualified name, or a prefixed class name like - <literal>$a = new subnamespace\foo();</literal> or - <literal>subnamespace\foo::staticmethod();</literal>. If the current namespace is - <literal>currentnamespace</literal>, this resolves to - <literal>currentnamespace\subnamespace\foo</literal>. If - the code is global, non-namespaced code, this resolves to <literal>subnamespace\foo</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - Fully qualified name, or a prefixed name with global prefix operator like - <literal>$a = new \currentnamespace\foo();</literal> or - <literal>\currentnamespace\foo::staticmethod();</literal>. This always resolves - to the literal name specified in the code, <literal>currentnamespace\foo</literal>. - </simpara> - </listitem> - </orderedlist> - </para> - <para> - Here is an example of the three kinds of syntax in actual code: - <informalexample> - <simpara>file1.php</simpara> - <programlisting role="php"> - <![CDATA[ -<?php -namespace Foo\Bar\subnamespace; - -const FOO = 1; -function foo() {} -class foo -{ - static function staticmethod() {} -} -?> - ]]> - </programlisting> - <simpara>file2.php</simpara> - <programlisting role="php"> - <![CDATA[ -<?php -namespace Foo\Bar; -include 'file1.php'; - -const FOO = 2; -function foo() {} -class foo -{ - static function staticmethod() {} -} - -/* Unqualified name */ -foo(); // resolves to function Foo\Bar\foo -foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod -echo FOO; // resolves to constant Foo\Bar\FOO - -/* Qualified name */ -subnamespace\foo(); // resolves to function Foo\Bar\subnamespace\foo -subnamespace\foo::staticmethod(); // resolves to class Foo\Bar\subnamespace\foo, - // method staticmethod -echo subnamespace\FOO; // resolves to constant Foo\Bar\subnamespace\FOO - -/* Fully qualified name */ -\Foo\Bar\foo(); // resolves to function Foo\Bar\foo -\Foo\Bar\foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod -echo \Foo\Bar\FOO; // resolves to constant Foo\Bar\FOO -?> - ]]> - </programlisting> - </informalexample> - </para> - <para> - Note that to access any global - class, function or constant, a fully qualified name can be used, such as - <function>\strlen</function> or <classname>\Exception</classname> or - <literal>\INI_ALL</literal>. - <example> - <title>Accessing global classes, functions and constants from within a namespace</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace Foo; - -function strlen() {} -const INI_ALL = 3; -class Exception {} - -$a = \strlen('hi'); // calls global function strlen -$b = \INI_ALL; // accesses global constant INI_ALL -$c = new \Exception('error'); // instantiates global class Exception -?> - ]]> - </programlisting> - </example> - </para> - </sect1> - <sect1 xml:id="language.namespaces.dynamic"> - <title>Namespaces and dynamic language features</title> - <para> - PHP's implementation of namespaces is influenced by its dynamic nature as a programming - language. Thus, to convert code like the following example into namespaced code: - <example> - <title>Dynamically accessing elements</title> - <simpara>example1.php:</simpara> - <programlisting role="php"> - <![CDATA[ -<?php -class classname -{ - function __construct() - { - echo __METHOD__,"\n"; - } -} -function funcname() -{ - echo __FUNCTION__,"\n"; -} -const constname = "global"; - -$a = 'classname'; -$obj = new $a; // prints classname::__construct -$b = 'funcname'; -$b(); // prints funcname -echo constant('constname'), "\n"; // prints global -?> - ]]> - </programlisting> - </example> - One must use the fully qualified name (class name with namespace prefix). - Note that because there is no difference between a qualified and a fully qualified Name - inside a dynamic class name, function name, or constant name, the leading backslash is - not necessary. - <example> - <title>Dynamically accessing namespaced elements</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace namespacename; -class classname -{ - function __construct() - { - echo __METHOD__,"\n"; - } -} -function funcname() -{ - echo __FUNCTION__,"\n"; -} -const constname = "namespaced"; - -include 'example1.php'; - -$a = 'classname'; -$obj = new $a; // prints classname::__construct -$b = 'funcname'; -$b(); // prints funcname -echo constant('constname'), "\n"; // prints global - -/* note that if using double quotes, "\\namespacename\\classname" must be used */ -$a = '\namespacename\classname'; -$obj = new $a; // prints namespacename\classname::__construct -$a = 'namespacename\classname'; -$obj = new $a; // also prints namespacename\classname::__construct -$b = 'namespacename\funcname'; -$b(); // prints namespacename\funcname -$b = '\namespacename\funcname'; -$b(); // also prints namespacename\funcname -echo constant('\namespacename\constname'), "\n"; // prints namespaced -echo constant('namespacename\constname'), "\n"; // also prints namespaced -?> - ]]> - </programlisting> - </example> - </para> - <para> - Be sure to read the <link linkend="language.namespaces.faq.quote">note about - escaping namespace names in strings</link>. - </para> - </sect1> - <sect1 xml:id="language.namespaces.nsconstants"> - <title>namespace keyword and __NAMESPACE__ constant</title> - <para> - PHP supports two ways of abstractly accessing elements within the current namespace, - the <constant>__NAMESPACE__</constant> magic constant, and the <literal>namespace</literal> - keyword. - </para> - <para> - The value of <constant>__NAMESPACE__</constant> is a string that contains the current - namespace name. In global, un-namespaced code, it contains an empty string. - <example> - <title>__NAMESPACE__ example, namespaced code</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject; - -echo '"', __NAMESPACE__, '"'; // outputs "MyProject" -?> -]]> - </programlisting> - </example> - <example> - <title>__NAMESPACE__ example, global code</title> - <programlisting role="php"> - <![CDATA[ -<?php - -echo '"', __NAMESPACE__, '"'; // outputs "" -?> -]]> - </programlisting> - </example> - The <constant>__NAMESPACE__</constant> constant is useful for dynamically constructing - names, for instance: - <example> - <title>using __NAMESPACE__ for dynamic name construction</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject; - -function get($classname) -{ - $a = __NAMESPACE__ . '\\' . $classname; - return new $a; -} -?> -]]> - </programlisting> - </example> - </para> - <para> - The <literal>namespace</literal> keyword can be used to explicitly request - an element from the current namespace or a sub-namespace. It is the namespace - equivalent of the <literal>self</literal> operator for classes. - <example> - <title>the namespace operator, inside a namespace</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace MyProject; - -use blah\blah as mine; // see "Using namespaces: importing/aliasing" - -blah\mine(); // calls function blah\blah\mine() -namespace\blah\mine(); // calls function MyProject\blah\mine() - -namespace\func(); // calls function MyProject\func() -namespace\sub\func(); // calls function MyProject\sub\func() -namespace\cname::method(); // calls static method "method" of class MyProject\cname -$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname -$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b -?> -]]> - </programlisting> - </example> - <example> - <title>the namespace operator, in global code</title> - <programlisting role="php"> - <![CDATA[ -<?php - -namespace\func(); // calls function func() -namespace\sub\func(); // calls function sub\func() -namespace\cname::method(); // calls static method "method" of class cname -$a = new namespace\sub\cname(); // instantiates object of class sub\cname -$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b -?> -]]> - </programlisting> - </example> - </para> - </sect1> - <sect1 xml:id="language.namespaces.importing"> - <title>Using namespaces: Aliasing/Importing</title> - <para> - The ability to refer to an external fully qualified name with an alias, or importing, - is an important feature of namespaces. This is similar to the - ability of unix-based filesystems to create symbolic links to a file or to a directory. - </para> - <para> - PHP namespaces support - two kinds of aliasing or importing: aliasing a class name, and aliasing a namespace name. - Note that importing a function or constant is not supported. - </para> - <para> - In PHP, aliasing is accomplished with the <literal>use</literal> operator. Here - is an example showing all 3 kinds of importing: - <example> - <title>importing/aliasing with the use operator</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace foo; -use My\Full\Classname as Another; - -// this is the same as use My\Full\NSname as NSname -use My\Full\NSname; - -// importing a global class -use \ArrayObject; - -$obj = new namespace\Another; // instantiates object of class foo\Another -$obj = new Another; // instantiates object of class My\Full\Classname -NSname\subns\func(); // calls function My\Full\NSname\subns\func -$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject -// without the "use \ArrayObject" we would instantiate an object of class foo\ArrayObject -?> -]]> - </programlisting> - </example> - Note that for namespaced names (fully qualified namespace names containing - namespace separator, such as <literal>Foo\Bar</literal> as opposed to global names that - do not, such as <literal>FooBar</literal>), the leading backslash is unnecessary and not - allowed, as import names - must be fully qualified, and are not processed relative to the current namespace. - </para> - <para> - PHP additionally supports a convenience shortcut to place multiple use statements - on the same line - <example> - <title>importing/aliasing with the use operator, multiple use statements combined</title> - <programlisting role="php"> - <![CDATA[ -<?php -use My\Full\Classname as Another, My\Full\NSname; - -$obj = new Another; // instantiates object of class My\Full\Classname -NSname\subns\func(); // calls function My\Full\NSname\subns\func -?> -]]> - </programlisting> - </example> - </para> - <para> - Importing is performed at compile-time, and so does not affect dynamic class, function - or constant names. - <example> - <title>Importing and dynamic names</title> - <programlisting role="php"> - <![CDATA[ -<?php -use My\Full\Classname as Another, My\Full\NSname; - -$obj = new Another; // instantiates object of class My\Full\Classname -$a = 'Another'; -$obj = new $a; // instantiates object of class Another -?> -]]> - </programlisting> - </example> - </para> - <para> - In addition, importing only affects unqualified and qualified names. Fully qualified - names are absolute, and unaffected by imports. - <example> - <title>Importing and fully qualified names</title> - <programlisting role="php"> - <![CDATA[ -<?php -use My\Full\Classname as Another, My\Full\NSname; - -$obj = new Another; // instantiates object of class My\Full\Classname -$obj = new \Another; // instantiates object of class Another -$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing -$obj = new \Another\thing; // instantiates object of class Another\thing -?> -]]> - </programlisting> - </example> - </para> - </sect1> - <sect1 xml:id="language.namespaces.global"> - <title>Global space</title> - <para> - Without any namespace definition, all class and function definitions are - placed into the global space - as it was in PHP before namespaces were - supported. Prefixing a name with <literal>\</literal> will specify that - the name is required from the global space even in the context of the - namespace. - <example> - <title>Using global space specification</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace A\B\C; - -/* This function is A\B\C\fopen */ -function fopen() { - /* ... */ - $f = \fopen(...); // call global fopen - return $f; -} -?> - ]]> - </programlisting> - </example> - </para> - </sect1> - <sect1 xml:id="language.namespaces.fallback"> - <title>Using namespaces: fallback to global function/constant</title> - <para> - Inside a namespace, when PHP encounters a unqualified Name in a class name, function or - constant context, it resolves these with different priorities. Class names always - resolve to the current namespace name. Thus to access internal or non-namespaced - user classes, One must refer to them with their fully qualified Name as in: - <example> - <title>Accessing global classes inside a namespace</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace A\B\C; -class Exception extends \Exception {} - -$a = new Exception('hi'); // $a is an object of class A\B\C\Exception -$b = new \Exception('hi'); // $b is an object of class Exception - -$c = new ArrayObject; // fatal error, class A\B\C\ArrayObject not found -?> - ]]> - </programlisting> - </example> - </para> - <para> - For functions and constants, PHP will fall back to global functions or constants - if a namespaced function or constant does not exist. - <example> - <title>global functions/constants fallback inside a namespace</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace A\B\C; - -const E_ERROR = 45; -function strlen($str) -{ - return \strlen($str) - 1; -} - -echo E_ERROR, "\n"; // prints "45" -echo INI_ALL, "\n"; // prints "7" - falls back to global INI_ALL - -echo strlen('hi'), "\n"; // prints "1" -if (is_array('hi')) { // prints "is not array" - echo "is array\n"; -} else { - echo "is not array\n"; -} -?> - ]]> - </programlisting> - </example> - </para> - </sect1> - - <sect1 xml:id="language.namespaces.rules"> - <title>Name resolution rules</title> - <para> - For the purposes of these resolution rules, here are some important definitions: - <variablelist> - <title>Namespace name definitions</title> - <varlistentry> - <term>Unqualified name</term> - <listitem> - <para> - This is an identifier without a namespace separator, such as <literal>Foo</literal> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>Qualified name</term> - <listitem> - <para> - This is an identifier with a namespace separator, such as <literal>Foo\Bar</literal> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>Fully qualified name</term> - <listitem> - <para> - This is an identifier with a namespace separator that begins with a namespace - separator, such as <literal>\Foo\Bar</literal>. <literal>namespace\Foo</literal> - is also a fully qualified name. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - <para> - Names are resolved following these resolution rules: - <orderedlist> - <listitem> - <simpara> - Calls to fully qualified functions, classes or constants are resolved at compile-time. - For instance <literal>new \A\B</literal> resolves to class <literal>A\B</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - All unquaified and qualified names (not fully qualified names) are translated during - compilation according to current - import rules. For example, if the namespace <literal>A\B\C</literal> is imported as - <literal>C</literal>, a call to - <literal>C\D\e()</literal> is translated to <literal>A\B\C\D\e()</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - Inside a namespace, all qualified names not translated according to import - rules have the current namespace prepended. For example, if a call - to <literal>C\D\e()</literal> is performed within namespace <literal>A\B</literal>, - it is translated to <literal>A\B\C\D\e()</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - Unqualified class names are translated during compilation according to current - import rules (full name substituted for short imported name). In example, if - the namespace <literal>A\B\C</literal> is imported as C, <literal>new C()</literal> is - translated to <literal>new A\B\C()</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - Inside namespace (say A\B), calls to unqualified functions are resolved at run-time. - Here is how a - call to function <literal>foo()</literal> is resolved: - </simpara> - <orderedlist> - <listitem> - <simpara> - It looks for a function from the current namespace: - <literal>A\B\foo()</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - It tries to find and call the <emphasis>global</emphasis> function - <literal>foo()</literal>. - </simpara> - </listitem> - </orderedlist> - </listitem> - <listitem> - <simpara> - Inside namespace (say <literal>A\B</literal>), calls to unqualified or qualified - class names (not fully qualified class names) - are resolved at run-time. Here is how a call to - <literal>new C()</literal> or <literal>new D\E()</literal> is resolved. - For <literal> new C()</literal>: - </simpara> - <orderedlist> - <listitem> - <simpara> - It looks for a class from the current namespace: - <literal>A\B\C</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - It attemts to autoload <literal>A\B\C</literal>. - </simpara> - </listitem> - </orderedlist> - <simpara> - For <literal> new D\E()</literal>: - </simpara> - <orderedlist> - <listitem> - <simpara> - It looks for a class by prepending the current namespace: - <literal>A\B\D\E</literal>. - </simpara> - </listitem> - <listitem> - <simpara> - It attemts to autoload <literal>A\B\D\E</literal>. - </simpara> - </listitem> - </orderedlist> - <simpara> - To reference any global class in the global namespace, - its fully qualified name <literal>new \C()</literal> must be used. - </simpara> - </listitem> - </orderedlist> - </para> - <example> - <title>Name resolutions illustrated</title> - <programlisting role="php"> -<![CDATA[ -<?php -namespace A; -use B\D, C\E as F; - -// function calls - -foo(); // first tries to call "foo" defined in namespace "A" - // then calls global function "foo" - -\foo(); // calls function "foo" defined in global scope - -my\foo(); // calls function "foo" defined in namespace "A\my" - -F(); // first tries to call "F" defined in namespace "A" - // then calls global function "F" - -// class references - -new B(); // creates object of class "B" defined in namespace "A" - // if not found, it tries to autoload class "A\B" - -new D(); // using import rules, creates object of class "D" defined in namespace "B" - // if not found, it tries to autoload class "B\D" - -new F(); // using import rules, creates object of class "E" defined in namespace "C" - // if not found, it tries to autoload class "C\E" - -new \B(); // creates object of class "B" defined in global scope - // if not found, it tries to autoload class "B" - -new \D(); // creates object of class "D" defined in global scope - // if not found, it tries to autoload class "D" - -new \F(); // creates object of class "F" defined in global scope - // if not found, it tries to autoload class "F" - -// static methods/namespace functions from another namespace - -B\foo(); // calls function "foo" from namespace "A\B" - -B::foo(); // calls method "foo" of class "B" defined in namespace "A" - // if class "A\B" not found, it tries to autoload class "A\B" - -D::foo(); // using import rules, calls method "foo" of class "D" defined in namespace "B" - // if class "B\D" not found, it tries to autoload class "B\D" - -\B\foo(); // calls function "foo" from namespace "B" - -\B::foo(); // calls method "foo" of class "B" from global scope - // if class "B" not found, it tries to autoload class "B" - -// static methods/namespace functions of current namespace - -A\B::foo(); // calls method "foo" of class "B" from namespace "A\A" - // if class "A\A\B" not found, it tries to autoload class "A\A\B" - -\A\B::foo(); // calls method "foo" of class "B" from namespace "A\B" - // if class "A\B" not found, it tries to autoload class "A\B" -?> -]]> - </programlisting> - </example> - </sect1> - <sect1 xml:id="language.namespaces.faq"> - <title>FAQ: things you need to know about namespaces</title> - <para> - This FAQ is split into two sections: common questions, and some specifics of - implementation that are helpful to understand fully. - </para> - <para> - First, the common questions. - <orderedlist> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.shouldicare">If I don't use namespaces, should - I care about any of this?</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.globalclass">How do I use internal or global - classes in a namespace?</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.innamespace">How do I use namespaces classes - functions, or constants in their own namespace?</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.full"> - How does a name like <literal>\my\name</literal> or <literal>\name</literal> - resolve? - </link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.qualified">How does a name like - <literal>my\name</literal> resolve?</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.shortname1">How does an unqualified class name - like <literal>name</literal> resolve?</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.shortname2">How does an unqualified function - name or unqualified constant name - like <literal>name</literal> resolve?</link> - </simpara> - </listitem> - </orderedlist> - </para> - <para> - There are a few implementation details of the namespace implementations - that are helpful to understand. - <orderedlist> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.conflict">Import names cannot conflict with - classes defined in the same file.</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.nested">Nested namespaces are not allowed. - </link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.nofuncconstantuse">Neither functions nor - constants can be imported via the <literal>use</literal> - statement.</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.quote">Dynamic namespace names (quoted - identifiers) should escape backslash.</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.constants">Undefined Constants referenced - using any backslash die with fatal error</link> - </simpara> - </listitem> - <listitem> - <simpara> - <link linkend="language.namespaces.faq.builtinconst">Cannot override special - constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD</link> - </simpara> - </listitem> - </orderedlist> - </para> - <sect2 xml:id="language.namespaces.faq.shouldicare"> - <title>If I don't use namespaces, should I care about any of this?</title> - <para> - No. Namespaces do not affect any existing code in any way, or any - as-yet-to-be-written code that does not contain namespaces. You can - write this code if you wish: - </para> - <para> - <example> - <title>Accessing global classes outside a namespace</title> - <programlisting role="php"> -<![CDATA[ -<?php -$a = new \stdClass; -]]> - </programlisting> - </example> - </para> - <para> - This is functionally equivalent to: - </para> - <para> - <example> - <title>Accessing global classes outside a namespace</title> - <programlisting role="php"> -<![CDATA[ -<?php -$a = new stdClass; -]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.globalclass"> - <title>How do I use internal or global classes in a namespace?</title> - <para> - <example> - <title>Accessing internal classes in namespaces</title> - <programlisting role="php"> -<![CDATA[ -<?php -namespace foo; -$a = new \stdClass; - -function test(\ArrayObject $typehintexample = null) {} - -$a = \DirectoryIterator::CURRENT_AS_FILEINFO; - -// extending an internal or global class -class MyException extends \Exception {} -?> -]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.innamespace"> - <title> - How do I use namespaces classes, functions, or constants in their own - namespace? - </title> - <para> - <example> - <title>Accessing internal classes, functions or constants in namespaces</title> - <programlisting role="php"> -<![CDATA[ -<?php -namespace foo; - -class MyClass {} - -// using a class from the current namespace as a type hint -function test(MyClass $typehintexample = null) {} -// another way to use a class from the current namespace as a type hint -function test(\foo\MyClass $typehintexample = null) {} - -// extending a class from the current namespace -class Extended extends MyClass {} - -// accessing a global function -$a = \globalfunc(); - -// accessing a global constant -$b = \INI_ALL; -?> -]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.full"> - <title> - How does a name like <literal>\my\name</literal> or <literal>\name</literal> - resolve? - </title> - <para> - Names that begin with a <literal>\</literal> always resolve to what they - look like, so <literal>\my\name</literal> is in fact <literal>my\name</literal>, - and <literal>\Exception</literal> is <literal>Exception</literal>. - <example> - <title>Fully Qualified names</title> - <programlisting role="php"> -<![CDATA[ -<?php -namespace foo; -$a = new \my\name(); // instantiates "my\name" class -echo \strlen('hi'); // calls function "strlen" -$a = \INI_ALL; // $a is set to the value of constant "INI_ALL" -?> -]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.qualified"> - <title>How does a name like <literal>my\name</literal> resolve?</title> - <para> - Names that contain a backslash but do not begin with a backslash like - <literal>my\name</literal> can be resolved in 2 different ways. - </para> - <para> - If there is - an import statement that aliases another name to <literal>my</literal>, then - the import alias is applied to the <literal>my</literal> in <literal>my\name</literal>. - </para> - <para> - Otherwise, the current namespace name is prepended to <literal>my\name</literal>. - </para> - <para> - <example> - <title>Qualified names</title> - <programlisting role="php"> -<![CDATA[ -<?php -namespace foo; -use blah\blah as foo; - -$a = new my\name(); // instantiates "foo\my\name" class -foo\bar::name(); // calls static method "name" in class "blah\blah\bar" -my\bar(); // calls function "foo\my\bar" -$a = my\BAR; // sets $a to the value of constant "foo\my\BAR" -?> -]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.shortname1"> - <title>How does an unqualified class name like <literal>name</literal> resolve?</title> - <para> - Class names that do not contain a backslash like - <literal>name</literal> can be resolved in 2 different ways. - </para> - <para> - If there is - an import statement that aliases another name to <literal>name</literal>, then - the import alias is applied. - </para> - <para> - Otherwise, the current namespace name is prepended to <literal>name</literal>. - </para> - <para> - <example> - <title>Unqualified class names</title> - <programlisting role="php"> -<![CDATA[ -<?php -namespace foo; -use blah\blah as foo; - -$a = new name(); // instantiates "foo\name" class -foo::name(); // calls static method "name" in class "blah\blah" -?> -]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.shortname2"> - <title> - How does an unqualified function name or unqualified constant name - like <literal>name</literal> resolve? - </title> - <para> - Function or constant names that do not contain a backslash like - <literal>name</literal> can be resolved in 2 different ways. - </para> - <para> - First, the current namespace name is prepended to <literal>name</literal>. - </para> - <para> - Finally, if the constant or function <literal>name</literal> does not exist - in the current namespace, a global constant or function <literal>name</literal> - is used if it exists. - </para> - <para> - <example> - <title>Unqualified function or constant names</title> - <programlisting role="php"> -<![CDATA[ -<?php -namespace foo; -use blah\blah as foo; - -const FOO = 1; - -function my() {} -function foo() {} -function sort(&$a) -{ - sort($a); - $a = array_flip($a); - return $a; -} - -my(); // calls "foo\my" -$a = strlen('hi'); // calls global function "strlen" because "foo\strlen" does not exist -$arr = array(1,3,2); -$b = sort($arr); // calls function "foo\sort" -$c = foo(); // calls function "foo\foo" - import is not applied - -$a = FOO; // sets $a to value of constant "foo\FOO" - import is not applied -$b = INI_ALL; // sets $b to value of global constant "INI_ALL" -?> -]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.conflict"> - <title>Import names cannot conflict with classes defined in the same file.</title> - <para> - The following script combinations are legal: - <informalexample> - <simpara>file1.php</simpara> - <programlisting role="php"> - <![CDATA[ -<?php -namespace my\stuff; -class MyClass {} -?> - ]]> - </programlisting> - <simpara>another.php</simpara> - <programlisting role="php"> - <![CDATA[ -<?php -namespace another; -class thing {} -?> - ]]> - </programlisting> - <simpara>file2.php</simpara> - <programlisting role="php"> - <![CDATA[ -<?php -namespace my\stuff; -include 'file1.php'; -include 'another.php'; - -use another\thing as MyClass; -$a = new MyClass; // instantiates class "thing" from namespace another -?> - ]]> - </programlisting> - </informalexample> - </para> - <para> - There is no name conflict, even though the class <literal>MyClass</literal> exists - within the <literal>my\stuff</literal> namespace, because the MyClass definition is - in a separate file. However, the next example causes a fatal error on name conflict - because MyClass is defined in the same file as the use statement. - <informalexample> - <programlisting role="php"> - <![CDATA[ -<?php -namespace my\stuff; -use another\thing as MyClass; -class MyClass {} // fatal error: MyClass conflicts with import statement -$a = new MyClass; -?> - ]]> - </programlisting> - </informalexample> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.nested"> - <title>Nested namespaces are not allowed.</title> - <para> - PHP does not allow nesting namespaces - <informalexample> - <programlisting role="php"> - <![CDATA[ -<?php -namespace my\stuff { - namespace nested { - class foo {} - } -} -?> - ]]> - </programlisting> - </informalexample> - However, it is easy to simulate nested namespaces like so: - <informalexample> - <programlisting role="php"> - <![CDATA[ -<?php -namespace my\stuff\nested { - class foo {} -} -?> - ]]> - </programlisting> - </informalexample> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.nofuncconstantuse"> - <title>Neither functions nor constants can be imported via the <literal>use</literal> - statement.</title> - <para> - The only elements that are affected by <literal>use</literal> statements are namespaces - and class names. In order to shorten a long constant or function, import its containing - namespace - <informalexample> - <programlisting role="php"> - <![CDATA[ -<?php -namespace mine; -use ultra\long\ns\name; - -$a = name\CONSTANT; -name\func(); -?> - ]]> - </programlisting> - </informalexample> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.quote"> - <title>Dynamic namespace names (quoted identifiers) should escape backslash</title> - <para> - It is very important to realize that because the backslash is used as an escape character - within strings, it should always be doubled when used inside a string. Otherwise - there is a risk of unintended consequences: - <example> - <title>Dangers of using namespaced names inside a double-quoted string</title> - <programlisting role="php"> - <![CDATA[ -<?php -$a = new "dangerous\name"; \\ \n is a newline inside double quoted strings! -$obj = new $a; - -$a = new 'not\at\all\dangerous'; \\ no problems here. -$obj = new $a; -?> - ]]> - </programlisting> - </example> - Inside a single-quoted string, the backslash escape sequence is much safer to use, but it - is still recommended practice to escape backslashes in all strings as a best practice. - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.constants"> - <title>Undefined Constants referenced using any backslash die with fatal error</title> - <para> - Any undefined constant that is unqualified like <literal>FOO</literal> will - produce a notice explaining that PHP assumed <literal>FOO</literal> was the value - of the constant. Any constant, qualified or fully qualified, that contains a - backslash will produce a fatal error if not found. - <example> - <title>Undefined constants</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace bar; -$a = FOO; // produces notice - undefined constants "FOO" assumed "FOO"; -$a = \FOO; // fatal error, undefined namespace constant FOO -$a = Bar\FOO; // fatal error, undefined namespace constant bar\Bar\FOO -$a = \Bar\FOO; // fatal error, undefined namespace constant Bar\FOO -?> - ]]> - </programlisting> - </example> - </para> - </sect2> - <sect2 xml:id="language.namespaces.faq.builtinconst"> - <title>Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD</title> - <para> - Any attempt to define a namespaced constant that is a special, built-in constant - results in a fatal error - <example> - <title>Undefined constants</title> - <programlisting role="php"> - <![CDATA[ -<?php -namespace bar; -const NULL = 0; // fatal error; -const true = 'stupid'; // also fatal error; -// etc. -?> - ]]> - </programlisting> - </example> - </para> - </sect2> - </sect1> -</chapter> - -<!-- Keep this comment at the end of the file - Local variables: - mode: sgml - sgml-omittag:t - sgml-shorttag:t - sgml-minimize-attributes:nil - sgml-always-quote-attributes:t - sgml-indent-step:1 - sgml-indent-data:t - indent-tabs-mode:nil - sgml-parent-document:nil - sgml-default-dtd-file:"../../manual.ced" - sgml-exposed-tags:nil - sgml-local-catalogs:nil - sgml-local-ecat-files:nil - End: - vim600: syn=xml fen fdm=syntax fdl=2 si - vim: et tw=78 syn=sgml - vi: ts=1 sw=1 ---> +<?xml version="1.0" encoding="UTF-8"?> +<!-- $Revision: 1.6 $ --> +<chapter xml:id="language.namespaces" xmlns="http://docbook.org/ns/docbook" + version="1.1"> + <title>Namespaces</title> + + <sect1 xml:id="language.namespaces.rationale"> + <title>Namespaces overview</title> + <simpara> + What are namespaces? In the broadest definition namespaces are a way of encapsulating + items. This can be seen as an abstract concept in many places. For example, in any + operating system directories serve to group related files, and act as a namespace for + the files within them. As a concrete example, the file <literal>foo.txt</literal> can + exist in both directory <literal>/home/greg</literal> and in <literal>/home/other</literal>, + but two copies of <literal>foo.txt</literal> cannot co-exist in the same directory. In + addition, to access the <literal>foo.txt</literal> file outside of the + <literal>/home/greg</literal> directory, we must prepend the directory name to the file + name using the directory separator to get <literal>/home/greg/foo.txt</literal>. This + same principle extends to namespaces in the programming world. + </simpara> + <simpara> + In the PHP world, namespaces are designed to solve two problems that authors + of libraries and applications encounter when creating re-usable code elements + such as classes or functions: + </simpara> + <para> + <orderedlist> + <listitem> + <simpara> + Name collisions between code you create, and + internal PHP classes/functions/constants or third-party classes/functions/constants. + </simpara> + </listitem> + <listitem> + <simpara> + Ability to alias (or shorten) Extra_Long_Names designed to alleviate the first problem, + improving readability of source code. + </simpara> + </listitem> + </orderedlist> + </para> + <simpara> + PHP Namespaces provide a way in which to group related classes, + functions and constants. Here is an example of namespace syntax in PHP: + </simpara> + <programlisting role="php"> + <![CDATA[ +<?php +namespace my\name; // see "Defining Namespaces" section + +class MyClass {} +function myfunction() {} +const MYCONST = 1; + +$a = new MyClass; +$c = new \my\name\MyClass; // see "Global Space" section + +$a = strlen('hi'); // see "Using namespaces: fallback to global + // function/constant" section + +$d = namespace\MYCONST; // see "namespace operator and __NAMESPACE__ + // constant" section +$d = __NAMESPACE__ . '\MYCONST'; +echo constant($d); // see "Namespaces and dynamic language features" section +?> + ]]> + </programlisting> + <simpara> + Namespaces are available in PHP as of PHP 5.3.0. + </simpara> + </sect1> + + <sect1 xml:id="language.namespaces.definition"> + <title>Defining namespaces</title> + <para> + Although any valid PHP code can be contained within a namespace, only three + type of code are affected by namespaces: classes, functions and constants. + </para> + <para> + Namespaces are declared using the <literal>namespace</literal> + keyword. A file containing a namespace must declare the namespace + at the top of the file before any other code. + <example> + <title>Declaring a single namespace</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject; + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } + +?> +]]> + </programlisting> + </example> + The only code construct allowed before a namespace declaration is the + <literal>declare</literal> statement, for defining encoding of a source file. In addition, + no non-PHP code may precede a namespace declaration, including extra whitespace: + <example> + <title>Declaring a single namespace</title> + <programlisting role="php"> + <![CDATA[ +<html> +<?php +namespace MyProject; // fatal error - namespace must be the first statement in the script +?> +]]> + </programlisting> + </example> + </para> + <para> + In addition, unlike any other PHP construct, the same namespace may be defined + in multiple files, allowing splitting up of a namespace's contents across the filesystem. + </para> + </sect1> + <sect1 xml:id="language.namespaces.nested"> + <title>Declaring sub-namespaces</title> + <para> + Much like directories and files, PHP namespaces also contain the ability to specify + a hierarchy of namespace names. Thus, a namespace name can be defined with + sub-levels: + <example> + <title>Declaring a single namespace with hierarchy</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject\Sub\Level; + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } + +?> +]]> + </programlisting> + </example> + The above example creates constant <literal>MyProject\Sub\Level\CONNECT_OK</literal>, + class <literal>MyProject\Sub\Level\Connection</literal> and function + <literal>MyProject\Sub\Level\Connection</literal>. + </para> + </sect1> + <sect1 xml:id="language.namespaces.definitionmultiple"> + <title>Defining multiple namespaces in the same file</title> + <para> + Multiple namespaces may also be declared in the same file. There are two allowed + syntaxes. + </para> + <para> + <example> + <title>Declaring multiple namespaces, simple combination syntax</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject; + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } + +namespace AnotherProject; + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } +?> +]]> + </programlisting> + </example> + </para> + <para> + This syntax is not recommended for combining namespaces into a single file. + Instead it is recommended to use the alternate bracketed syntax. + </para> + <para> + <example> + <title>Declaring multiple namespaces, bracketed syntax</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject { + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } +} + +namespace AnotherProject { + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } +} +?> +]]> + </programlisting> + </example> + </para> + <para> + It is strongly discouraged as a coding practice to combine multiple namespaces into + the same file. The primary use case is to combine multiple PHP scripts into the same + file. + </para> + To combine global non-namespaced code with namespaced code, only bracketed syntax is + supported. Global code should be + encased in a namespace statement with no namespace name as in: + <example> + <title>Declaring multiple namespaces and unnamespaced code</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject { + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } +} + +namespace { // global code +session_start(); +$a = MyProject\connect(); +echo MyProject\Connection::start(); +} +?> +]]> + </programlisting> + </example> + </para> + <para> + No PHP code may exist outside of the namespace brackets except for an opening + declare statement. + <example> + <title>Declaring multiple namespaces and unnamespaced code</title> + <programlisting role="php"> + <![CDATA[ +<?php +declare(encoding='UTF-8'); +namespace MyProject { + +const CONNECT_OK = 1; +class Connection { /* ... */ } +function connect() { /* ... */ } +} + +namespace { // global code +session_start(); +$a = MyProject\connect(); +echo MyProject\Connection::start(); +} +?> +]]> + </programlisting> + </example> + </para> + </sect1> + <sect1 xml:id="language.namespaces.basics"> + <title>Using namespaces: Basics</title> + <para> + Before discussing the use of namespaces, it is important to understand how PHP + knows which namespaced element your code is requesting. A simple analogy can be made + between PHP namespaces and a filesystem. There are three ways to access a file in a + file system: + <orderedlist> + <listitem> + <simpara> + Relative file name like <literal>foo.txt</literal>. This resolves to + <literal>currentdirectory/foo.txt</literal> where currentdirectory is the + directory currently occupied. So if the current directory is + <literal>/home/foo</literal>, the name resolves to <literal>/home/foo/foo.txt</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + Relative path name like <literal>subdirectory/foo.txt</literal>. This resolves + to <literal>currentdirectory/subdirectory/foo.txt</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + Absolute path name like <literal>/main/foo.txt</literal>. This resolves + to <literal>/main/foo.txt</literal>. + </simpara> + </listitem> + </orderedlist> + The same principle can be applied to namespaced elements in PHP. For + example, a class name can be referred to in three ways: + <orderedlist> + <listitem> + <simpara> + Unqualified name, or an unprefixed class name like + <literal>$a = new foo();</literal> or + <literal>foo::staticmethod();</literal>. If the current namespace is + <literal>currentnamespace</literal>, this resolves to + <literal>currentnamespace\foo</literal>. If + the code is global, non-namespaced code, this resolves to <literal>foo</literal>. + </simpara> + <simpara> + One caveat: unqualified names for functions and constants will + resolve to global functions and constants if the namespaced function or constant + is not defined. See <link linkend="language.namespaces.fallback">Using namespaces: + fallback to global function/constant</link> for details. + </simpara> + </listitem> + <listitem> + <simpara> + Qualified name, or a prefixed class name like + <literal>$a = new subnamespace\foo();</literal> or + <literal>subnamespace\foo::staticmethod();</literal>. If the current namespace is + <literal>currentnamespace</literal>, this resolves to + <literal>currentnamespace\subnamespace\foo</literal>. If + the code is global, non-namespaced code, this resolves to <literal>subnamespace\foo</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + Fully qualified name, or a prefixed name with global prefix operator like + <literal>$a = new \currentnamespace\foo();</literal> or + <literal>\currentnamespace\foo::staticmethod();</literal>. This always resolves + to the literal name specified in the code, <literal>currentnamespace\foo</literal>. + </simpara> + </listitem> + </orderedlist> + </para> + <para> + Here is an example of the three kinds of syntax in actual code: + <informalexample> + <simpara>file1.php</simpara> + <programlisting role="php"> + <![CDATA[ +<?php +namespace Foo\Bar\subnamespace; + +const FOO = 1; +function foo() {} +class foo +{ + static function staticmethod() {} +} +?> + ]]> + </programlisting> + <simpara>file2.php</simpara> + <programlisting role="php"> + <![CDATA[ +<?php +namespace Foo\Bar; +include 'file1.php'; + +const FOO = 2; +function foo() {} +class foo +{ + static function staticmethod() {} +} + +/* Unqualified name */ +foo(); // resolves to function Foo\Bar\foo +foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod +echo FOO; // resolves to constant Foo\Bar\FOO + +/* Qualified name */ +subnamespace\foo(); // resolves to function Foo\Bar\subnamespace\foo +subnamespace\foo::staticmethod(); // resolves to class Foo\Bar\subnamespace\foo, + // method staticmethod +echo subnamespace\FOO; // resolves to constant Foo\Bar\subnamespace\FOO + +/* Fully qualified name */ +\Foo\Bar\foo(); // resolves to function Foo\Bar\foo +\Foo\Bar\foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod +echo \Foo\Bar\FOO; // resolves to constant Foo\Bar\FOO +?> + ]]> + </programlisting> + </informalexample> + </para> + <para> + Note that to access any global + class, function or constant, a fully qualified name can be used, such as + <function>\strlen</function> or <classname>\Exception</classname> or + <literal>\INI_ALL</literal>. + <example> + <title>Accessing global classes, functions and constants from within a namespace</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace Foo; + +function strlen() {} +const INI_ALL = 3; +class Exception {} + +$a = \strlen('hi'); // calls global function strlen +$b = \INI_ALL; // accesses global constant INI_ALL +$c = new \Exception('error'); // instantiates global class Exception +?> + ]]> + </programlisting> + </example> + </para> + </sect1> + <sect1 xml:id="language.namespaces.dynamic"> + <title>Namespaces and dynamic language features</title> + <para> + PHP's implementation of namespaces is influenced by its dynamic nature as a programming + language. Thus, to convert code like the following example into namespaced code: + <example> + <title>Dynamically accessing elements</title> + <simpara>example1.php:</simpara> + <programlisting role="php"> + <![CDATA[ +<?php +class classname +{ + function __construct() + { + echo __METHOD__,"\n"; + } +} +function funcname() +{ + echo __FUNCTION__,"\n"; +} +const constname = "global"; + +$a = 'classname'; +$obj = new $a; // prints classname::__construct +$b = 'funcname'; +$b(); // prints funcname +echo constant('constname'), "\n"; // prints global +?> + ]]> + </programlisting> + </example> + One must use the fully qualified name (class name with namespace prefix). + Note that because there is no difference between a qualified and a fully qualified Name + inside a dynamic class name, function name, or constant name, the leading backslash is + not necessary. + <example> + <title>Dynamically accessing namespaced elements</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace namespacename; +class classname +{ + function __construct() + { + echo __METHOD__,"\n"; + } +} +function funcname() +{ + echo __FUNCTION__,"\n"; +} +const constname = "namespaced"; + +include 'example1.php'; + +$a = 'classname'; +$obj = new $a; // prints classname::__construct +$b = 'funcname'; +$b(); // prints funcname +echo constant('constname'), "\n"; // prints global + +/* note that if using double quotes, "\\namespacename\\classname" must be used */ +$a = '\namespacename\classname'; +$obj = new $a; // prints namespacename\classname::__construct +$a = 'namespacename\classname'; +$obj = new $a; // also prints namespacename\classname::__construct +$b = 'namespacename\funcname'; +$b(); // prints namespacename\funcname +$b = '\namespacename\funcname'; +$b(); // also prints namespacename\funcname +echo constant('\namespacename\constname'), "\n"; // prints namespaced +echo constant('namespacename\constname'), "\n"; // also prints namespaced +?> + ]]> + </programlisting> + </example> + </para> + <para> + Be sure to read the <link linkend="language.namespaces.faq.quote">note about + escaping namespace names in strings</link>. + </para> + </sect1> + <sect1 xml:id="language.namespaces.nsconstants"> + <title>namespace keyword and __NAMESPACE__ constant</title> + <para> + PHP supports two ways of abstractly accessing elements within the current namespace, + the <constant>__NAMESPACE__</constant> magic constant, and the <literal>namespace</literal> + keyword. + </para> + <para> + The value of <constant>__NAMESPACE__</constant> is a string that contains the current + namespace name. In global, un-namespaced code, it contains an empty string. + <example> + <title>__NAMESPACE__ example, namespaced code</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject; + +echo '"', __NAMESPACE__, '"'; // outputs "MyProject" +?> +]]> + </programlisting> + </example> + <example> + <title>__NAMESPACE__ example, global code</title> + <programlisting role="php"> + <![CDATA[ +<?php + +echo '"', __NAMESPACE__, '"'; // outputs "" +?> +]]> + </programlisting> + </example> + The <constant>__NAMESPACE__</constant> constant is useful for dynamically constructing + names, for instance: + <example> + <title>using __NAMESPACE__ for dynamic name construction</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject; + +function get($classname) +{ + $a = __NAMESPACE__ . '\\' . $classname; + return new $a; +} +?> +]]> + </programlisting> + </example> + </para> + <para> + The <literal>namespace</literal> keyword can be used to explicitly request + an element from the current namespace or a sub-namespace. It is the namespace + equivalent of the <literal>self</literal> operator for classes. + <example> + <title>the namespace operator, inside a namespace</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace MyProject; + +use blah\blah as mine; // see "Using namespaces: importing/aliasing" + +blah\mine(); // calls function blah\blah\mine() +namespace\blah\mine(); // calls function MyProject\blah\mine() + +namespace\func(); // calls function MyProject\func() +namespace\sub\func(); // calls function MyProject\sub\func() +namespace\cname::method(); // calls static method "method" of class MyProject\cname +$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname +$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b +?> +]]> + </programlisting> + </example> + <example> + <title>the namespace operator, in global code</title> + <programlisting role="php"> + <![CDATA[ +<?php + +namespace\func(); // calls function func() +namespace\sub\func(); // calls function sub\func() +namespace\cname::method(); // calls static method "method" of class cname +$a = new namespace\sub\cname(); // instantiates object of class sub\cname +$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b +?> +]]> + </programlisting> + </example> + </para> + </sect1> + <sect1 xml:id="language.namespaces.importing"> + <title>Using namespaces: Aliasing/Importing</title> + <para> + The ability to refer to an external fully qualified name with an alias, or importing, + is an important feature of namespaces. This is similar to the + ability of unix-based filesystems to create symbolic links to a file or to a directory. + </para> + <para> + PHP namespaces support + two kinds of aliasing or importing: aliasing a class name, and aliasing a namespace name. + Note that importing a function or constant is not supported. + </para> + <para> + In PHP, aliasing is accomplished with the <literal>use</literal> operator. Here + is an example showing all 3 kinds of importing: + <example> + <title>importing/aliasing with the use operator</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace foo; +use My\Full\Classname as Another; + +// this is the same as use My\Full\NSname as NSname +use My\Full\NSname; + +// importing a global class +use \ArrayObject; + +$obj = new namespace\Another; // instantiates object of class foo\Another +$obj = new Another; // instantiates object of class My\Full\Classname +NSname\subns\func(); // calls function My\Full\NSname\subns\func +$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject +// without the "use \ArrayObject" we would instantiate an object of class foo\ArrayObject +?> +]]> + </programlisting> + </example> + Note that for namespaced names (fully qualified namespace names containing + namespace separator, such as <literal>Foo\Bar</literal> as opposed to global names that + do not, such as <literal>FooBar</literal>), the leading backslash is unnecessary and not + allowed, as import names + must be fully qualified, and are not processed relative to the current namespace. + </para> + <para> + PHP additionally supports a convenience shortcut to place multiple use statements + on the same line + <example> + <title>importing/aliasing with the use operator, multiple use statements combined</title> + <programlisting role="php"> + <![CDATA[ +<?php +use My\Full\Classname as Another, My\Full\NSname; + +$obj = new Another; // instantiates object of class My\Full\Classname +NSname\subns\func(); // calls function My\Full\NSname\subns\func +?> +]]> + </programlisting> + </example> + </para> + <para> + Importing is performed at compile-time, and so does not affect dynamic class, function + or constant names. + <example> + <title>Importing and dynamic names</title> + <programlisting role="php"> + <![CDATA[ +<?php +use My\Full\Classname as Another, My\Full\NSname; + +$obj = new Another; // instantiates object of class My\Full\Classname +$a = 'Another'; +$obj = new $a; // instantiates object of class Another +?> +]]> + </programlisting> + </example> + </para> + <para> + In addition, importing only affects unqualified and qualified names. Fully qualified + names are absolute, and unaffected by imports. + <example> + <title>Importing and fully qualified names</title> + <programlisting role="php"> + <![CDATA[ +<?php +use My\Full\Classname as Another, My\Full\NSname; + +$obj = new Another; // instantiates object of class My\Full\Classname +$obj = new \Another; // instantiates object of class Another +$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing +$obj = new \Another\thing; // instantiates object of class Another\thing +?> +]]> + </programlisting> + </example> + </para> + </sect1> + <sect1 xml:id="language.namespaces.global"> + <title>Global space</title> + <para> + Without any namespace definition, all class and function definitions are + placed into the global space - as it was in PHP before namespaces were + supported. Prefixing a name with <literal>\</literal> will specify that + the name is required from the global space even in the context of the + namespace. + <example> + <title>Using global space specification</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace A\B\C; + +/* This function is A\B\C\fopen */ +function fopen() { + /* ... */ + $f = \fopen(...); // call global fopen + return $f; +} +?> + ]]> + </programlisting> + </example> + </para> + </sect1> + <sect1 xml:id="language.namespaces.fallback"> + <title>Using namespaces: fallback to global function/constant</title> + <para> + Inside a namespace, when PHP encounters a unqualified Name in a class name, function or + constant context, it resolves these with different priorities. Class names always + resolve to the current namespace name. Thus to access internal or non-namespaced + user classes, One must refer to them with their fully qualified Name as in: + <example> + <title>Accessing global classes inside a namespace</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace A\B\C; +class Exception extends \Exception {} + +$a = new Exception('hi'); // $a is an object of class A\B\C\Exception +$b = new \Exception('hi'); // $b is an object of class Exception + +$c = new ArrayObject; // fatal error, class A\B\C\ArrayObject not found +?> + ]]> + </programlisting> + </example> + </para> + <para> + For functions and constants, PHP will fall back to global functions or constants + if a namespaced function or constant does not exist. + <example> + <title>global functions/constants fallback inside a namespace</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace A\B\C; + +const E_ERROR = 45; +function strlen($str) +{ + return \strlen($str) - 1; +} + +echo E_ERROR, "\n"; // prints "45" +echo INI_ALL, "\n"; // prints "7" - falls back to global INI_ALL + +echo strlen('hi'), "\n"; // prints "1" +if (is_array('hi')) { // prints "is not array" + echo "is array\n"; +} else { + echo "is not array\n"; +} +?> + ]]> + </programlisting> + </example> + </para> + </sect1> + + <sect1 xml:id="language.namespaces.rules"> + <title>Name resolution rules</title> + <para> + For the purposes of these resolution rules, here are some important definitions: + <variablelist> + <title>Namespace name definitions</title> + <varlistentry> + <term>Unqualified name</term> + <listitem> + <para> + This is an identifier without a namespace separator, such as <literal>Foo</literal> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>Qualified name</term> + <listitem> + <para> + This is an identifier with a namespace separator, such as <literal>Foo\Bar</literal> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>Fully qualified name</term> + <listitem> + <para> + This is an identifier with a namespace separator that begins with a namespace + separator, such as <literal>\Foo\Bar</literal>. <literal>namespace\Foo</literal> + is also a fully qualified name. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + <para> + Names are resolved following these resolution rules: + <orderedlist> + <listitem> + <simpara> + Calls to fully qualified functions, classes or constants are resolved at compile-time. + For instance <literal>new \A\B</literal> resolves to class <literal>A\B</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + All unquaified and qualified names (not fully qualified names) are translated during + compilation according to current + import rules. For example, if the namespace <literal>A\B\C</literal> is imported as + <literal>C</literal>, a call to + <literal>C\D\e()</literal> is translated to <literal>A\B\C\D\e()</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + Inside a namespace, all qualified names not translated according to import + rules have the current namespace prepended. For example, if a call + to <literal>C\D\e()</literal> is performed within namespace <literal>A\B</literal>, + it is translated to <literal>A\B\C\D\e()</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + Unqualified class names are translated during compilation according to current + import rules (full name substituted for short imported name). In example, if + the namespace <literal>A\B\C</literal> is imported as C, <literal>new C()</literal> is + translated to <literal>new A\B\C()</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + Inside namespace (say A\B), calls to unqualified functions are resolved at run-time. + Here is how a + call to function <literal>foo()</literal> is resolved: + </simpara> + <orderedlist> + <listitem> + <simpara> + It looks for a function from the current namespace: + <literal>A\B\foo()</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + It tries to find and call the <emphasis>global</emphasis> function + <literal>foo()</literal>. + </simpara> + </listitem> + </orderedlist> + </listitem> + <listitem> + <simpara> + Inside namespace (say <literal>A\B</literal>), calls to unqualified or qualified + class names (not fully qualified class names) + are resolved at run-time. Here is how a call to + <literal>new C()</literal> or <literal>new D\E()</literal> is resolved. + For <literal> new C()</literal>: + </simpara> + <orderedlist> + <listitem> + <simpara> + It looks for a class from the current namespace: + <literal>A\B\C</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + It attemts to autoload <literal>A\B\C</literal>. + </simpara> + </listitem> + </orderedlist> + <simpara> + For <literal> new D\E()</literal>: + </simpara> + <orderedlist> + <listitem> + <simpara> + It looks for a class by prepending the current namespace: + <literal>A\B\D\E</literal>. + </simpara> + </listitem> + <listitem> + <simpara> + It attemts to autoload <literal>A\B\D\E</literal>. + </simpara> + </listitem> + </orderedlist> + <simpara> + To reference any global class in the global namespace, + its fully qualified name <literal>new \C()</literal> must be used. + </simpara> + </listitem> + </orderedlist> + </para> + <example> + <title>Name resolutions illustrated</title> + <programlisting role="php"> +<![CDATA[ +<?php +namespace A; +use B\D, C\E as F; + +// function calls + +foo(); // first tries to call "foo" defined in namespace "A" + // then calls global function "foo" + +\foo(); // calls function "foo" defined in global scope + +my\foo(); // calls function "foo" defined in namespace "A\my" + +F(); // first tries to call "F" defined in namespace "A" + // then calls global function "F" + +// class references + +new B(); // creates object of class "B" defined in namespace "A" + // if not found, it tries to autoload class "A\B" + +new D(); // using import rules, creates object of class "D" defined in namespace "B" + // if not found, it tries to autoload class "B\D" + +new F(); // using import rules, creates object of class "E" defined in namespace "C" + // if not found, it tries to autoload class "C\E" + +new \B(); // creates object of class "B" defined in global scope + // if not found, it tries to autoload class "B" + +new \D(); // creates object of class "D" defined in global scope + // if not found, it tries to autoload class "D" + +new \F(); // creates object of class "F" defined in global scope + // if not found, it tries to autoload class "F" + +// static methods/namespace functions from another namespace + +B\foo(); // calls function "foo" from namespace "A\B" + +B::foo(); // calls method "foo" of class "B" defined in namespace "A" + // if class "A\B" not found, it tries to autoload class "A\B" + +D::foo(); // using import rules, calls method "foo" of class "D" defined in namespace "B" + // if class "B\D" not found, it tries to autoload class "B\D" + +\B\foo(); // calls function "foo" from namespace "B" + +\B::foo(); // calls method "foo" of class "B" from global scope + // if class "B" not found, it tries to autoload class "B" + +// static methods/namespace functions of current namespace + +A\B::foo(); // calls method "foo" of class "B" from namespace "A\A" + // if class "A\A\B" not found, it tries to autoload class "A\A\B" + +\A\B::foo(); // calls method "foo" of class "B" from namespace "A\B" + // if class "A\B" not found, it tries to autoload class "A\B" +?> +]]> + </programlisting> + </example> + </sect1> + <sect1 xml:id="language.namespaces.faq"> + <title>FAQ: things you need to know about namespaces</title> + <para> + This FAQ is split into two sections: common questions, and some specifics of + implementation that are helpful to understand fully. + </para> + <para> + First, the common questions. + <orderedlist> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.shouldicare">If I don't use namespaces, should + I care about any of this?</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.globalclass">How do I use internal or global + classes in a namespace?</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.innamespace">How do I use namespaces classes + functions, or constants in their own namespace?</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.full"> + How does a name like <literal>\my\name</literal> or <literal>\name</literal> + resolve? + </link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.qualified">How does a name like + <literal>my\name</literal> resolve?</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.shortname1">How does an unqualified class name + like <literal>name</literal> resolve?</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.shortname2">How does an unqualified function + name or unqualified constant name + like <literal>name</literal> resolve?</link> + </simpara> + </listitem> + </orderedlist> + </para> + <para> + There are a few implementation details of the namespace implementations + that are helpful to understand. + <orderedlist> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.conflict">Import names cannot conflict with + classes defined in the same file.</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.nested">Nested namespaces are not allowed. + </link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.nofuncconstantuse">Neither functions nor + constants can be imported via the <literal>use</literal> + statement.</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.quote">Dynamic namespace names (quoted + identifiers) should escape backslash.</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.constants">Undefined Constants referenced + using any backslash die with fatal error</link> + </simpara> + </listitem> + <listitem> + <simpara> + <link linkend="language.namespaces.faq.builtinconst">Cannot override special + constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD</link> + </simpara> + </listitem> + </orderedlist> + </para> + <sect2 xml:id="language.namespaces.faq.shouldicare"> + <title>If I don't use namespaces, should I care about any of this?</title> + <para> + No. Namespaces do not affect any existing code in any way, or any + as-yet-to-be-written code that does not contain namespaces. You can + write this code if you wish: + </para> + <para> + <example> + <title>Accessing global classes outside a namespace</title> + <programlisting role="php"> +<![CDATA[ +<?php +$a = new \stdClass; +]]> + </programlisting> + </example> + </para> + <para> + This is functionally equivalent to: + </para> + <para> + <example> + <title>Accessing global classes outside a namespace</title> + <programlisting role="php"> +<![CDATA[ +<?php +$a = new stdClass; +]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.globalclass"> + <title>How do I use internal or global classes in a namespace?</title> + <para> + <example> + <title>Accessing internal classes in namespaces</title> + <programlisting role="php"> +<![CDATA[ +<?php +namespace foo; +$a = new \stdClass; + +function test(\ArrayObject $typehintexample = null) {} + +$a = \DirectoryIterator::CURRENT_AS_FILEINFO; + +// extending an internal or global class +class MyException extends \Exception {} +?> +]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.innamespace"> + <title> + How do I use namespaces classes, functions, or constants in their own + namespace? + </title> + <para> + <example> + <title>Accessing internal classes, functions or constants in namespaces</title> + <programlisting role="php"> +<![CDATA[ +<?php +namespace foo; + +class MyClass {} + +// using a class from the current namespace as a type hint +function test(MyClass $typehintexample = null) {} +// another way to use a class from the current namespace as a type hint +function test(\foo\MyClass $typehintexample = null) {} + +// extending a class from the current namespace +class Extended extends MyClass {} + +// accessing a global function +$a = \globalfunc(); + +// accessing a global constant +$b = \INI_ALL; +?> +]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.full"> + <title> + How does a name like <literal>\my\name</literal> or <literal>\name</literal> + resolve? + </title> + <para> + Names that begin with a <literal>\</literal> always resolve to what they + look like, so <literal>\my\name</literal> is in fact <literal>my\name</literal>, + and <literal>\Exception</literal> is <literal>Exception</literal>. + <example> + <title>Fully Qualified names</title> + <programlisting role="php"> +<![CDATA[ +<?php +namespace foo; +$a = new \my\name(); // instantiates "my\name" class +echo \strlen('hi'); // calls function "strlen" +$a = \INI_ALL; // $a is set to the value of constant "INI_ALL" +?> +]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.qualified"> + <title>How does a name like <literal>my\name</literal> resolve?</title> + <para> + Names that contain a backslash but do not begin with a backslash like + <literal>my\name</literal> can be resolved in 2 different ways. + </para> + <para> + If there is + an import statement that aliases another name to <literal>my</literal>, then + the import alias is applied to the <literal>my</literal> in <literal>my\name</literal>. + </para> + <para> + Otherwise, the current namespace name is prepended to <literal>my\name</literal>. + </para> + <para> + <example> + <title>Qualified names</title> + <programlisting role="php"> +<![CDATA[ +<?php +namespace foo; +use blah\blah as foo; + +$a = new my\name(); // instantiates "foo\my\name" class +foo\bar::name(); // calls static method "name" in class "blah\blah\bar" +my\bar(); // calls function "foo\my\bar" +$a = my\BAR; // sets $a to the value of constant "foo\my\BAR" +?> +]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.shortname1"> + <title>How does an unqualified class name like <literal>name</literal> resolve?</title> + <para> + Class names that do not contain a backslash like + <literal>name</literal> can be resolved in 2 different ways. + </para> + <para> + If there is + an import statement that aliases another name to <literal>name</literal>, then + the import alias is applied. + </para> + <para> + Otherwise, the current namespace name is prepended to <literal>name</literal>. + </para> + <para> + <example> + <title>Unqualified class names</title> + <programlisting role="php"> +<![CDATA[ +<?php +namespace foo; +use blah\blah as foo; + +$a = new name(); // instantiates "foo\name" class +foo::name(); // calls static method "name" in class "blah\blah" +?> +]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.shortname2"> + <title> + How does an unqualified function name or unqualified constant name + like <literal>name</literal> resolve? + </title> + <para> + Function or constant names that do not contain a backslash like + <literal>name</literal> can be resolved in 2 different ways. + </para> + <para> + First, the current namespace name is prepended to <literal>name</literal>. + </para> + <para> + Finally, if the constant or function <literal>name</literal> does not exist + in the current namespace, a global constant or function <literal>name</literal> + is used if it exists. + </para> + <para> + <example> + <title>Unqualified function or constant names</title> + <programlisting role="php"> +<![CDATA[ +<?php +namespace foo; +use blah\blah as foo; + +const FOO = 1; + +function my() {} +function foo() {} +function sort(&$a) +{ + sort($a); + $a = array_flip($a); + return $a; +} + +my(); // calls "foo\my" +$a = strlen('hi'); // calls global function "strlen" because "foo\strlen" does not exist +$arr = array(1,3,2); +$b = sort($arr); // calls function "foo\sort" +$c = foo(); // calls function "foo\foo" - import is not applied + +$a = FOO; // sets $a to value of constant "foo\FOO" - import is not applied +$b = INI_ALL; // sets $b to value of global constant "INI_ALL" +?> +]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.conflict"> + <title>Import names cannot conflict with classes defined in the same file.</title> + <para> + The following script combinations are legal: + <informalexample> + <simpara>file1.php</simpara> + <programlisting role="php"> + <![CDATA[ +<?php +namespace my\stuff; +class MyClass {} +?> + ]]> + </programlisting> + <simpara>another.php</simpara> + <programlisting role="php"> + <![CDATA[ +<?php +namespace another; +class thing {} +?> + ]]> + </programlisting> + <simpara>file2.php</simpara> + <programlisting role="php"> + <![CDATA[ +<?php +namespace my\stuff; +include 'file1.php'; +include 'another.php'; + +use another\thing as MyClass; +$a = new MyClass; // instantiates class "thing" from namespace another +?> + ]]> + </programlisting> + </informalexample> + </para> + <para> + There is no name conflict, even though the class <literal>MyClass</literal> exists + within the <literal>my\stuff</literal> namespace, because the MyClass definition is + in a separate file. However, the next example causes a fatal error on name conflict + because MyClass is defined in the same file as the use statement. + <informalexample> + <programlisting role="php"> + <![CDATA[ +<?php +namespace my\stuff; +use another\thing as MyClass; +class MyClass {} // fatal error: MyClass conflicts with import statement +$a = new MyClass; +?> + ]]> + </programlisting> + </informalexample> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.nested"> + <title>Nested namespaces are not allowed.</title> + <para> + PHP does not allow nesting namespaces + <informalexample> + <programlisting role="php"> + <![CDATA[ +<?php +namespace my\stuff { + namespace nested { + class foo {} + } +} +?> + ]]> + </programlisting> + </informalexample> + However, it is easy to simulate nested namespaces like so: + <informalexample> + <programlisting role="php"> + <![CDATA[ +<?php +namespace my\stuff\nested { + class foo {} +} +?> + ]]> + </programlisting> + </informalexample> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.nofuncconstantuse"> + <title>Neither functions nor constants can be imported via the <literal>use</literal> + statement.</title> + <para> + The only elements that are affected by <literal>use</literal> statements are namespaces + and class names. In order to shorten a long constant or function, import its containing + namespace + <informalexample> + <programlisting role="php"> + <![CDATA[ +<?php +namespace mine; +use ultra\long\ns\name; + +$a = name\CONSTANT; +name\func(); +?> + ]]> + </programlisting> + </informalexample> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.quote"> + <title>Dynamic namespace names (quoted identifiers) should escape backslash</title> + <para> + It is very important to realize that because the backslash is used as an escape character + within strings, it should always be doubled when used inside a string. Otherwise + there is a risk of unintended consequences: + <example> + <title>Dangers of using namespaced names inside a double-quoted string</title> + <programlisting role="php"> + <![CDATA[ +<?php +$a = new "dangerous\name"; \\ \n is a newline inside double quoted strings! +$obj = new $a; + +$a = new 'not\at\all\dangerous'; \\ no problems here. +$obj = new $a; +?> + ]]> + </programlisting> + </example> + Inside a single-quoted string, the backslash escape sequence is much safer to use, but it + is still recommended practice to escape backslashes in all strings as a best practice. + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.constants"> + <title>Undefined Constants referenced using any backslash die with fatal error</title> + <para> + Any undefined constant that is unqualified like <literal>FOO</literal> will + produce a notice explaining that PHP assumed <literal>FOO</literal> was the value + of the constant. Any constant, qualified or fully qualified, that contains a + backslash will produce a fatal error if not found. + <example> + <title>Undefined constants</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace bar; +$a = FOO; // produces notice - undefined constants "FOO" assumed "FOO"; +$a = \FOO; // fatal error, undefined namespace constant FOO +$a = Bar\FOO; // fatal error, undefined namespace constant bar\Bar\FOO +$a = \Bar\FOO; // fatal error, undefined namespace constant Bar\FOO +?> + ]]> + </programlisting> + </example> + </para> + </sect2> + <sect2 xml:id="language.namespaces.faq.builtinconst"> + <title>Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD</title> + <para> + Any attempt to define a namespaced constant that is a special, built-in constant + results in a fatal error + <example> + <title>Undefined constants</title> + <programlisting role="php"> + <![CDATA[ +<?php +namespace bar; +const NULL = 0; // fatal error; +const true = 'stupid'; // also fatal error; +// etc. +?> + ]]> + </programlisting> + </example> + </para> + </sect2> + </sect1> +</chapter> + +<!-- Keep this comment at the end of the file + Local variables: + mode: sgml + sgml-omittag:t + sgml-shorttag:t + sgml-minimize-attributes:nil + sgml-always-quote-attributes:t + sgml-indent-step:1 + sgml-indent-data:t + indent-tabs-mode:nil + sgml-parent-document:nil + sgml-default-dtd-file:"../../manual.ced" + sgml-exposed-tags:nil + sgml-local-catalogs:nil + sgml-local-ecat-files:nil + End: + vim600: syn=xml fen fdm=syntax fdl=2 si + vim: et tw=78 syn=sgml + vi: ts=1 sw=1 +-->