©
This document uses PHP Chinese website manual Release
(PHP 5 >= 5.3.0)
在讨论如何使用命名空间之前,必须了解 PHP 是如何知道要使用哪一个命名空间中的元素的。可以将 PHP 命名空间与文件系统作一个简单的类比。在文件系统中访问一个文件有三种方式:
下面是一个使用这三种方式的实例:
file1.php
<?php
namespace Foo \ Bar \ subnamespace ;
const FOO = 1 ;
function foo () {}
class foo
{
static function staticmethod () {}
}
?>
file2.php
<?php
namespace Foo \ Bar ;
include 'file1.php' ;
const FOO = 2 ;
function foo () {}
class foo
{
static function staticmethod () {}
}
foo (); // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
foo :: staticmethod (); // 解析为类 Foo\Bar\foo的静态方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod
echo FOO ; // resolves to constant Foo\Bar\FOO
subnamespace \ foo (); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace \ foo :: staticmethod (); // 解析为类 Foo\Bar\subnamespace\foo,
// 以及类的方法 staticmethod
echo subnamespace \ FOO ; // 解析为常量 Foo\Bar\subnamespace\FOO
\ Foo \ Bar \ foo (); // 解析为函数 Foo\Bar\foo
\ Foo \ Bar \ foo :: staticmethod (); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \ Foo \ Bar \ FOO ; // 解析为常量 Foo\Bar\FOO
?>
注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL。
Example #1 在命名空间内部访问全局类、函数和常量
<?php
namespace Foo ;
function strlen () {}
const INI_ALL = 3 ;
class Exception {}
$a = \ strlen ( 'hi' ); // 调用全局函数strlen
$b = \ INI_ALL ; // 访问全局常量 INI_ALL
$c = new \ Exception ( 'error' ); // 实例化全局类 Exception
?>
[#1] Anonymous [2014-10-27 13:08:53]
<?php
namespace Foo;
try {
// Something awful here
// That will throw a new exception from SPL
}
catch (Exception as $ex) {
// We will never get here
// This is because we are catchin Foo\Exception
}
?>
Instead use fully qualified name for the exception to catch it
<?php
namespace Foo;
try {
// something awful here
// That will throw a new exception from SPL
}
catch (\Exception as $ex) {
// Now we can get here at last
}
?>
[#2] anon [2014-01-30 21:47:59]
The namespace hierarchy will normally mirror the directory hierarchy where the class files are located, but this is not a strict requirement. You could, for example, have several class flles with different namespaces in the same directory.
[#3] tom at tomwardrop dot com [2012-02-26 10:06:35]
It seems the file system analogy only goes so far. One thing that's missing that would be very useful is relative navigation up the namespace chain, e.g.
<?php
namespace MyProject {
class Person {}
}
namespace MyProject\People {
class Adult extends ..\Person {}
}
?>
That would be really nice, especially if you had really deep namespaces. It would save you having to type out the full namespace just to reference a resource one level up.
[#4] Lukas Z [2011-12-05 15:25:26]
Well variables inside namespaces do not override others since variables are never affected by namespace but always global:
"Although any valid PHP code can be contained within a namespace, only four types of code are affected by namespaces: classes, interfaces, functions and constants. "
Source: "Defining Namespaces"
http://www.php.net/manual/en/language.namespaces.definition.php
[#5] philip dot preisser at arcor dot de [2011-06-14 02:34:39]
Working with variables can overwrite equal variables in other namespaces
<?php // php5 - package-version : 5.3.5-1ubuntu7.2
namespace
main
{}
namespace
main\sub1
{
$data = 1;
}
namespace
main\sub2
{
echo $data;// 1
$data = 2;
}
namespace
main\sub1
{
echo $data;// 2
$data = 1;
}
namespace
{
echo $data;// 1
}
?>
[#6] Franois Vespa [2010-12-21 17:42:12]
It seems you cannot nest a constant declaration within a if statement
<?php
namespace FOO;
if(eval)
const BAR=true;
// will throw the following error:
// PHP Parse error: syntax error, unexpected T_CONST
// instead use:
if(eval)
define('FOO\BAR',true);
?>
[#7] kukoman at pobox dot sk [2008-10-17 11:20:26]
PHP 5.3.0alpha2 (cli)
<?php
// namespace MyProject\DB;
require 'db.php';
use MyProject\DB; // fine; same as DB\
use MyProject\DB\Connection as DBC; // fine
use MyProject\DB as HM; // fine
use HM\Connection as DBC2; // class call ends with FATAL!!!
$x = new DBC(); // fine
$y = new HM\Connection(); // fine
$z = new DBC2(); // Fatal error: Class 'HM\Connection' not found
?>
[#8] richard at richard-sumilang dot com [2008-03-27 01:36:28]
Syntax for extending classes in namespaces is still the same.
Lets call this Object.php:
<?php
namespace com\rsumilang\common;
class Object{
// ... code ...
}
?>
And now lets create a class called String that extends object in String.php:
<?php
class String extends com\rsumilang\common\Object{
// ... code ...
}
?>
Now if you class String was defined in the same namespace as Object then you don't have to specify a full namespace path:
<?php
namespace com\rsumilang\common;
class String extends Object
{
// ... code ...
}
?>
Lastly, you can also alias a namespace name to use a shorter name for the class you are extending incase your class is in seperate namespace:
<?php
namespace com\rsumilang\util;
use com\rsumlang\common as Common;
class String extends Common\Object
{
// ... code ...
}
?>
- Richard Sumilang