PHP ??????
PHP ??????(namespace)
PHP ??????(namespace)? PHP 5.3?? ???????. C#? Java? ????? ??????? ??? ?? ????. ??? ?? PHP?? ??? ?? ??? ??? ????.
PHP ??????? ?? ? ?? ??? ??? ??? ? ????.
1. ???? ??? ??? PHP ?? ???/??/?? ?? ?? ???/??/?? ?? ?? ??.
2. ?? ??? ???? ??? ?? ?? ? ??? ??(????? ? ?? ??? ??? ???? ?? ???)? ?? ??(?? ??) ??? ????.
?????? ??
????? ?? ??, ??? ? ?? ??? PHP? ?? ??? ???? ??? ?? ??? ?????. ??? ?????.
??????? ??? ??????? ???? ?????. ??? ??????? ???? ??? ?? ?? ???? ?? ??????? ???? ???. ?? ??? ??? ????.
< ?php // 定義代碼在 'MyProject' 命名空間中 namespace MyProject; // ... 代碼 ...
??? ???? ??? ?? ??? ?????? ??? ??? ?? ????.
< ?php namespace MyProject1; // MyProject1 命名空間中的PHP代碼 namespace MyProject2; // MyProject2 命名空間中的PHP代碼 // 另一種語法 namespace MyProject3 { // MyProject3 命名空間中的PHP代碼 } ?>
??????? ???? ?? ??? ??? ???? ? ???? ?????. ?? ?? ??? ???. ??? ???? PHP? ?? ?? ??? ?????? ?? ?? ????? ? ???.
<?php declare(encoding='UTF-8'); //定義多個命名空間和不包含在命名空間中的代碼 namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // 全局代碼 session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
?? ??? ?? ??? ??????:
<html> <?php namespace MyProject; // 命名空間前出現(xiàn)了“<html>” 會致命錯誤 - 命名空間必須是程序腳本的第一條語句 ?>
Subnamespace
???? ?? ??? ????? PHP ??????? ???? ??? ?????? ??? ??? ?? ????. ??? ?????? ??? ??? ???? ??? ? ????.
<?php namespace MyProject\Sub\Level; //聲明分層次的單個命名空間 const CONNECT_OK = 1; class Connection { /* ... */ } function Connect() { /* ... */ } ?>
?? ???? ?? MyProjectSubLevelCONNECT_OK, MyProjectSubLevelConnection ??? ? MyProjectSubLevelConnect ??? ????.
?????? ???
PHP ??????? ??? ??? ? ?? ???? ??? ? ????:
1. ????? ?? ?? ?? $a=new foo() ?? foo: :staticmethod(); ;. ?? ??????? currentnamespace?? foo? currentnamespacefoo? ?????. foo? ???? ??? ?? ???? ?? ???????? ??? ???? ?? ?? foo? foo? ?????. ??: ??????? ?? ?? ??? ???? ?? ?? ????? ?? ?? ?? ?? ??? ?? ?? ?? ?? ???? ?????.
2. $a = new subnamespacefoo() ?? subnamespacefoo::staticmethod();? ?? ???? ?? ?? ???? ??? ?????. ?? ??????? currentnamespace?? foo? currentnamespacesubnamespacefoo? ?????. foo? ???? ??? ?? ??? ??, ?? ???????? ???? ?? ??? foo? subnamespacefoo? ?????.
3. ???? ?? ?? ?? ??? ???? ??? ??(?: $a = new currentnamespacefoo() ?? currentnamespacefoo::staticmethod();) ? ?? foo? ?? ???? ??? ?? currentnamespacefoo? ?????.
??? ? ? ?? ??? ??? ????.
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的靜態(tài)方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod echo FOO; // resolves to constant Foo\Bar\FOO /* 限定名稱 */ subnamespace\foo(); // 解析為函數(shù) Foo\Bar\subnamespace\foo subnamespace\foo::staticmethod(); // 解析為類 Foo\Bar\subnamespace\foo, // 以及類的方法 staticmethod echo subnamespace\FOO; // 解析為常量 Foo\Bar\subnamespace\FOO /* 完全限定名稱 */ \Foo\Bar\foo(); // 解析為函數(shù) Foo\Bar\foo \Foo\Bar\foo::staticmethod(); // 解析為類 Foo\Bar\foo, 以及類的方法 staticmethod echo \Foo\Bar\FOO; // 解析為常量 Foo\Bar\FOO ?>
?? ???, ?? ?? ??? ?????? strlen(), Exception ?? INI_ALL? ?? ???? ??? ??? ? ????.
?????? ?? ?? ???, ?? ? ??? ???:
<?php namespace Foo; function strlen() {} const INI_ALL = 3; class Exception {} $a = \strlen('hi'); // 調(diào)用全局函數(shù)strlen $b = \INI_ALL; // 訪問全局常量 INI_ALL $c = new \Exception('error'); // 實例化全局類 Exception ?>
?????? ? ?? ?? ??
PHP ??????? ??? ?? ??? ?? ??? ??? ????. ??? ?? ??? ??????? ????? ?? ??? ???? ??????.
example1.php ?? ??:
<?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 ?>
???? ??(?????? ???? ??? ??? ??)? ???? ???. ?? ??? ??, ?? ?? ?? ?? ????? ???? ??? ???? ?? ??? ??? ???? ?? ????? ???? ????.
?????? ??? ?? ?? ???
<?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 ?>
?????? ??? ? __NAMESPACE__ ??
PHP? ?? ?????? ?? ??? ????? ? ?? ?? ??? __NAMESPACE__ ?? ??? ?????? ???? ?????.
?? __NAMESPACE__? ?? ?? ??????? ??? ???? ??????. ??????? ???? ?? ?? ???? ? ???? ?????.
__NAMESPACE__ ?, ??????? ??
<?php namespace MyProject; echo '"', __NAMESPACE__, '"'; // 輸出 "MyProject" ?>
__NAMESPACE__ ?, ?? ??
<?php echo '"', __NAMESPACE__, '"'; // 輸出 "" ?>
?? __NAMESPACE__? ??? ???? ??? ? ?????. ?? ?? ??? ????.
__NAMESPACE__? ???? ??? ???? ?????
<?php namespace MyProject; function get($classname) { $a = __NAMESPACE__ . '\' . $classname; return new $a; } ?>
??? ??????? ???? ?? ?????? ?? ?? ??????? ??? ????? ???? ? ????. ???? self ???? ?????.
?????? ???, ??????? ??
<?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 ?>
?????? ???, ?? ??
<?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 ?>
? ?????? ??:Alias/Import
PHP ?????? ???? ?? ?? ????? ???? ? ?? ??? ????. ??? ??? ??? ????? ?????? ??? ??? ???? ????. PHP? ??? ??? ??? ???? ????.
PHP?? ??? ??? ??? ?? ?????. ??? ??? ? ?? ???? ??? ?? ???? ????.
1 ??? ????? ????? ?? ???? ?????.
<?php namespace foo; use My\Full\Classname as Another; // 下面的例子與 use My\Full\NSname as NSname 相同 use My\Full\NSname; // 導(dǎo)入一個全局類 use \ArrayObject; $obj = new namespace\Another; // 實例化 foo\Another 對象 $obj = new Another; // 實例化 My\Full\Classname 對象 NSname\subns\func(); // 調(diào)用函數(shù) My\Full\NSname\subns\func $a = new ArrayObject(array(1)); // 實例化 ArrayObject 對象 // 如果不使用 "use \ArrayObject" ,則實例化一個 foo\ArrayObject 對象 ?>2. ? ?? ?? ?? use ?? ???? ????.
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // 實例化 My\Full\Classname 對象 NSname\subns\func(); // 調(diào)用函數(shù) My\Full\NSname\subns\func ?>??? ?? ???? ??? ????? ?? ??? ??, ?? ?? ?? ?? ??? ???? ????. 3. ???? ? ?? ??
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // 實例化一個 My\Full\Classname 對象 $a = 'Another'; $obj = new $a; // 實際化一個 Another 對象 ?>?? ???? ??? ????? ?? ??? ???? ???? ??? ????. ???? ??? ?????? ????? ??? ?? ????. 4. ???? ?? ????
<?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 ?>
?????? ??: ?? ?? ??/??
???????? PHP? ????? ?? ???, ?? ?? ?? ??? ???? ?? ???? ??? ???? ??? ?????. ??. ??? ??? ?? ?? ??????? ???? ?????. ??? ??? ?? ?? ??????? ???? ?? ??? ??? ????? ?? ??? ?? ???? ??? ???? ???.
1. ??????
<?php namespace A\B\C; class Exception extends \Exception {} $a = new Exception('hi'); // $a 是類 A\B\C\Exception 的一個對象 $b = new \Exception('hi'); // $b 是類 Exception 的一個對象 $c = new ArrayObject; // 致命錯誤, 找不到 A\B\C\ArrayObject 類 ?>
? ?? ???? ??????. ??? ?? ??? ??? ?? ??????? ???? ??? PHP? ?? ??? ??? ??? ???? ???.
2. ??????
<?php namespace A\B\C; const E_ERROR = 45; function strlen($str) { return \strlen($str) - 1; } echo E_ERROR, "\n"; // 輸出 "45" echo INI_ALL, "\n"; // 輸出 "7" - 使用全局常量 INI_ALL echo strlen('hi'), "\n"; // 輸出 "1" if (is_array('hi')) { // 輸出 "is not array" echo "is array\n"; } else { echo "is not array\n"; } ?>
??? ??
? ??? ?? ??/?? ??????? ???? ??? PHP? ?????? ??? ???? ?? ????? ?? ???? ??? ?? ??? ?????. ?? ???? ??? ?? ??????? ???? ??? ?? ??? ??? ?????.
?? ?? ??? ??
<?php namespace A\B\C; /* 這個函數(shù)是 A\B\C\fopen */ function fopen() { /* ... */ $f = \fopen(...); // 調(diào)用全局的fopen函數(shù) return $f; } ?>
?????? ??
??? ??????? ???? ?, ?? ??? ???? ?? ?? ???? ??? ? ? ???? ?? ?? ??? ???????.
<?php namespace A; use B\D, C\E as F; // 函數(shù)調(diào)用 foo(); // 首先嘗試調(diào)用定義在命名空間"A"中的函數(shù)foo() // 再嘗試調(diào)用全局函數(shù) "foo" \foo(); // 調(diào)用全局空間函數(shù) "foo" my\foo(); // 調(diào)用定義在命名空間"A\my"中函數(shù) "foo" F(); // 首先嘗試調(diào)用定義在命名空間"A"中的函數(shù) "F" // 再嘗試調(diào)用全局函數(shù) "F" // 類引用 new B(); // 創(chuàng)建命名空間 "A" 中定義的類 "B" 的一個對象 // 如果未找到,則嘗試自動裝載類 "A\B" new D(); // 使用導(dǎo)入規(guī)則,創(chuàng)建命名空間 "B" 中定義的類 "D" 的一個對象 // 如果未找到,則嘗試自動裝載類 "B\D" new F(); // 使用導(dǎo)入規(guī)則,創(chuàng)建命名空間 "C" 中定義的類 "E" 的一個對象 // 如果未找到,則嘗試自動裝載類 "C\E" new \B(); // 創(chuàng)建定義在全局空間中的類 "B" 的一個對象 // 如果未發(fā)現(xiàn),則嘗試自動裝載類 "B" new \D(); // 創(chuàng)建定義在全局空間中的類 "D" 的一個對象 // 如果未發(fā)現(xiàn),則嘗試自動裝載類 "D" new \F(); // 創(chuàng)建定義在全局空間中的類 "F" 的一個對象 // 如果未發(fā)現(xiàn),則嘗試自動裝載類 "F" // 調(diào)用另一個命名空間中的靜態(tài)方法或命名空間函數(shù) B\foo(); // 調(diào)用命名空間 "A\B" 中函數(shù) "foo" B::foo(); // 調(diào)用命名空間 "A" 中定義的類 "B" 的 "foo" 方法 // 如果未找到類 "A\B" ,則嘗試自動裝載類 "A\B" D::foo(); // 使用導(dǎo)入規(guī)則,調(diào)用命名空間 "B" 中定義的類 "D" 的 "foo" 方法 // 如果類 "B\D" 未找到,則嘗試自動裝載類 "B\D" \B\foo(); // 調(diào)用命名空間 "B" 中的函數(shù) "foo" \B::foo(); // 調(diào)用全局空間中的類 "B" 的 "foo" 方法 // 如果類 "B" 未找到,則嘗試自動裝載類 "B" // 當(dāng)前命名空間中的靜態(tài)方法或函數(shù) A\B::foo(); // 調(diào)用命名空間 "A\A" 中定義的類 "B" 的 "foo" 方法 // 如果類 "A\A\B" 未找到,則嘗試自動裝載類 "A\A\B" \A\B::foo(); // 調(diào)用命名空間 "A\B" 中定義的類 "B" 的 "foo" 方法 // 如果類 "A\B" 未找到,則嘗試自動裝載類 "A\B" ?>
?? ??? ?? ??? ????.
1. ???? ??? ?? ??, ??? ? ??? ?? ??? ??? ??? ?????. ?? ?? ? AB? ??? AB? ?????.
2. ?? ????? ?? ??? ???? ??(????? ?? ??)? ?? ???? ??? ?? ??? ??? ?????. ?? ?? ?????? ABC? C? ??? ?? CDe()? ?? ??? ABCDe()? ?????.
3. ?????? ??? ???? ??? ?? ???? ?? ?? ???? ?? ??? ?? ?????? ??? ?????. ?? ??, CDe()? ?????? AB ??? ???? CDe()? ABCDe()? ?????.
4. ????? ?? ??? ??? ?? ???? ??? ?? ??? ??? ?????(?? ???? ?? ?? ?? ??? ???). ?? ?? ?????? ABC? C? ??? ?? new C()? new ABC()? ?????.
5. ??????(?: AB) ??? ????? ?? ??? ?? ?? ??? ???? ?????. ?? ?? foo() ??? ?? ??? ??? ?? ?? ?????.
1. ?? ???????? ABfoo()?? ??? ????.
2 ?? ?? foo? ?? ??? ???. () ????.
6. ??????(?: AB) ??? ????? ?? ?? ?? ???? ?? ???(??? ????? ?? ??)? ?? ??? ???? ?????. new C()? new DE()? ???? ?? ?? ??? ??? ????. new C() ?? ??:
1. ?? ???????? ABC ???? ????.
2. ABC ???? ???? ??? ???.
? DE() ??:
3. ??? ?? ?? ?? ?????? ??? ???? ABDE? ??? ? ?? ???? ?????.
4. ABDE ???? ???? ??? ???.
??? ???????? ??? ???? ????? ???? ??? new C()? ???? ???.