©
本文檔使用 php中文網手册 發布
(PHP 5 >= 5.3.0)
什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。
在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:
PHP 命名空间提供了一种将相关的类、函数和常量组合到一起的途径。下面是一个说明 PHP 命名空间语法的示例:
Example #1 命名空间语法示例
<?php
namespace my \ name ; // 参考 "定义命名空间" 小节
class MyClass {}
function myfunction () {}
const MYCONST = 1 ;
$a = new MyClass ;
$c = new \ my \ name \ MyClass ; // 参考 "全局空间" 小节
$a = strlen ( 'hi' ); // 参考 "使用命名空间:后备全局函数/常量" 小节
$d = namespace\ MYCONST ; // 参考 "namespace操作符和__NAMESPACE__常量” 小节
$d = __NAMESPACE__ . '\MYCONST' ;
echo constant ( $d ); // 参考 "命名空间和动态语言特征" 小节
?>
Note:
名为PHP或php的命名空间,以及以这些名字开头的命名空间(例如PHP\Classes)被保留用作语言内核使用,而不应该在用户空间的代码中使用。
[#1] sonkengmaldini at gmail dot com [2015-08-19 20:43:55]
Be aware that using character set UTF-8 with namespace will output a fatal error telling you that 'Namespace declaration statement has to be the very first statement in the script ' instead of that character use the UTF-8 (sans BOM) !
this will display the previous message
<?php
namespace myNameSpace;//fatal error! with UTF-8 character set
?>
[#2] pierstoval at gmail dot com [2014-12-05 10:00:21]
To people coming here by searching about namespaces, know that a consortium has studied about best practices in PHP, in order to allow developers to have common coding standards.
These best practices are called "PHP Standard Recommendations" , also known as PSR.
They are visible on this link : http://www.php-fig.org/psr
Actually there are 5 coding standards categories :
PSR-0 : Autoloading Standard , which goal is to make the use of Namespaces easier, in order to convert a namespace into a file path.
PSR-1 : Basic Coding Standard , basically, standards :)
PSR-2 : Coding Style Guide, where to put braces, how to write a class, etc.
PSR-3 : Logger Interface , how to write a standard logger
PSR-4 : Improved Autoloading , to resolve more Namespaces into paths.
The ones I want to point are PSR-0 and PSR-4 : they use namespaces to resolve a FQCN (Fully qualified class name = full namespace + class name) into a file path.
Basic example, you have this directory structure :
./src/Pierstoval/Tools/MyTool.php
The namespacing PSR-0 or PSR-4 standard tells that you can transform this path into a FQCN.
Read the principles of autoload if you need to know what it means, because it's almost mandatory ;) .
Structure :
{path}/autoloader.php
{path}/index.php
{path}/src/Pierstoval/Tools/MyTool.php
Files :
<?php
// {path}/index.php
include 'autoloader.php';
$tool = new Pierstoval/Tools/MyTool();
?>
<?php
// {path}/src/Pierstoval/Tools/MyTool.php
namespace Pierstoval\Tools;
class MyTool {}
?>
<?php
// {path}/autoloader.php
function loadClass($className) {
$fileName = '';
$namespace = '';
// Sets the include path as the "src" directory
$includePath = dirname(__FILE__).DIRECTORY_SEPARATOR.'src';
if (false !== ($lastNsPos = strripos($className, '\\'))) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$fullFileName = $includePath . DIRECTORY_SEPARATOR . $fileName;
if (file_exists($fullFileName)) {
require $fullFileName;
} else {
echo 'Class "'.$className.'" does not exist.';
}
}
spl_autoload_register('loadClass'); // Registers the autoloader
?>
A standardized autoloader will get the class you want to instanciate (MyTool) and get the FQCN, transform it into a file path, and check if the file exists. If it does, it will
<?php include(); ?>
it, and if you wrote your class correctly, the class will be available within its correct namespace.
Then, if you have the following code :
<?php $tool = new Pierstoval/Tools/MyTool(); ?>
The autoloader will transform the FQCN into this path :
{path}/src/Pierstoval/Tools/MyTool.php
This might be the best practices ever in PHP framework developments, such as Symfony or others.
[#3] php dot net at e-z dot name [2013-11-03 05:32:24]
php namespaces are case-insensitive:
file1.php:
<?php
namespace foo;
function bar()
{
echo 'from bar';
}
?>
file2.php:
<?php
fOo\bar() // output: from bar
?>
[#4] Dmitry Snytkine [2011-05-31 06:54:58]
Just a note: namespace (even nested or sub-namespace) cannot be just a number, it must start with a letter.
For example, lets say you want to use namespace for versioning of your packages or versioning of your API:
namespace Mynamespace\1; // Illegal
Instead use this:
namespace Mynamespace\v1; // OK
[#5] SteveWa [2011-02-27 08:45:41]
Thought this might help other newbies like me...
Name collisions means:
you create a function named db_connect, and somebody elses code that you use in your file (i.e. an include) has the same function with the same name.
To get around that problem, you rename your function SteveWa_db_connect which makes your code longer and harder to read.
Now you can use namespaces to keep your function name separate from anyone else's function name, and you won't have to make extra_long_named functions to get around the name collision problem.
So a namespace is like a pointer to a file path where you can find the source of the function you are working with