PHP namespace (namespace)
PHP namespace (namespace) ditambahkan di PHP 5.3, jika Anda belajar C # dan Java, namespace yang tidak apa-apa hal-hal baru. Namun dalam PHP yang masih memiliki makna yang sangat penting.
ruang nama PHP dapat memecahkan dua masalah berikut:
- kode pengguna yang ditulis dalam PHP kelas / fungsi / konstanta atau konflik pihak ketiga nama kelas / fungsi / konstanta antara.
- Sebagai nama identifier panjang (biasanya untuk meringankan kategori pertama didefinisikan) membuat alias (atau pendek) nama meningkatkan pembacaan kode sumber.
mendefinisikan ruang nama
Secara default, semua konstanta, kelas, dan nama fungsi ditempatkan di ruang global, sama seperti sebelum dukungan namespace PHP.
Namespace deklarasi oleh namespace kata kunci. Jika nama file mengandung spasi, itu harus menyatakan namespace sebelum kode lainnya. Sintaks adalah sebagai berikut;
< ?php // 定义代码在 'MyProject' 命名空间中 namespace MyProject; // ... 代码 ...
Anda juga dapat menentukan ruang nama yang berbeda dalam file yang sama dalam kode, seperti:
< ?php namespace MyProject1; // MyProject1 命名空间中的PHP代码 namespace MyProject2; // MyProject2 命名空间中的PHP代码 // 另一种语法 namespace MyProject3 { // MyProject3 命名空间中的PHP代码 } ?>
Sebelum menyatakan kode hukum yang unik namespace digunakan untuk menentukan file sumber metode encoding menyatakan pernyataan. Semua kode non-PHP termasuk spasi tidak dapat muncul sebelum deklarasi namespace.
<?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(); } ?>
Kode berikut kesalahan sintaks akan terjadi:
<html> <?php namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句 ?>
Subnamespaces
Hubungan dengan direktori dan file seperti, ruang nama PHP juga memungkinkan untuk menentukan nama namespace hirarkis. Dengan demikian, nama namespace dapat didefinisikan menggunakan secara hirarkis:
<?php namespace MyProject\Sub\Level; //声明分层次的单个命名空间 const CONNECT_OK = 1; class Connection { /* ... */ } function Connect() { /* ... */ } ?>
Contoh di atas menciptakan konstan MyProject \ Sub \ Tingkat \ CONNECT_OK, jenis MyProject \ Sub \ Tingkat \ Connection dan fungsi MyProject \ Sub \ Tingkat \ Connect.
Ruang nama
PHP nama kelas namespace dapat dirujuk dalam tiga cara:
Nama wajar tanpa pengecualian, atau nama kelas tidak mengandung awalan, seperti $ a = new foo (); atau foo :: staticmethod ();. Jika namespace saat ini currentnamespace, foo akan ditafsirkan sebagai currentnamespace \ foo. Jika foo adalah kode global, kode tidak mengandung namespace apapun, itu akan diurai sebagai foo foo. Peringatan: Jika fungsi namespace atau konstan tidak didefinisikan, maka nama fungsi atau nama konstan wajar tanpa pengecualian akan diselesaikan dengan nama fungsi global, atau nama konstan.
nama yang memenuhi, atau nama berisi awalan, seperti $ a = baru subnamespace \ foo ( ); atau subnamespace \ foo :: staticmethod ();. Jika namespace saat ini currentnamespace, maka foo akan diurai sebagai currentnamespace \ subnamespace \ foo. Jika foo adalah kode global, kode tidak mengandung namespace apapun, foo akan diselesaikan untuk subnamespace \ foo.
Sepenuhnya nama kualifikasi, atau menyertakan nama operator yang awalan global, misalnya, $ a = new \ currentnamespace \ foo (); atau \ currentnamespace \ foo :: staticmethod () ;. Dalam hal ini, foo akan selalu diselesaikan dengan nama kata-kata kode (literal nama) currentnamespace \ foo.
Berikut adalah sebuah contoh dari tiga cara:
file kode file1.php
<?php namespace Foo\Bar\subnamespace; const FOO = 1; function foo() {} class foo { static function staticmethod() {} } ?>
file kode 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 ?>
Perhatikan bahwa untuk mengakses setiap kelas global, fungsi atau konstan, Anda dapat menggunakan nama yang memenuhi syarat, seperti \ strlen () atau \ Exception atau \ INI_ALL.
Namespace Mengakses kelas global, fungsi dan konstanta:
<?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 ?>
Ruang nama dan fitur bahasa dinamis
Menerapkan PHP namespace dipengaruhi oleh fitur bahasa dinamis sendiri. Jadi, jika Anda ingin kode berikut ke ruang nama, akses dinamis elemen.
example1.php file kode:
<?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 ?>
Anda harus menggunakan nama yang memenuhi syarat (termasuk nama kelas dari awalan namespace). Perhatikan bahwa karena dalam nama yang dinamis kelas, nama fungsi, atau nama konstan, nama berkualitas dan nama yang memenuhi syarat ada perbedaan, sehingga backslash terkemuka tidak perlu.
Unsur namespace Access dinamis
<?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 kata kunci dan konstanta __NAMESPACE__
PHP mendukung dua cara untuk mengakses namespace saat elemen interior abstrak, __ konstanta NAMESPACE__ Sihir dan namespace kata kunci.
__NAMESPACE__ Nilai konstanta adalah string yang berisi nama namespace saat ini. Di global, kode tidak termasuk namespace yang berisi string kosong.
__NAMESPACE__ Contoh, di kode namespace
<?php namespace MyProject; echo '"', __NAMESPACE__, '"'; // 输出 "MyProject" ?>
__NAMESPACE__ Contoh, kode global yang
<?php echo '"', __NAMESPACE__, '"'; // 输出 "" ?>
Konstan __NAMESPACE__ dibuat secara dinamis ketika nama berguna, misalnya:
Gunakan __NAMESPACE__ nama dibuat secara dinamis
<?php namespace MyProject; function get($classname) { $a = __NAMESPACE__ . '\\' . $classname; return new $a; } ?>
Namespace kata kunci dapat digunakan secara eksplisit mengakses namespace saat atau elemen sub-namespace. Hal ini setara dengan kelas operator diri.
namespace kode Operator namespace
<?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 ?>
Operator namespace, kode global yang
<?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 ?>
Menggunakan ruang nama: Aliasing / Mengimpor
PHP ruang nama mendukung dua menggunakan alias atau mengimpor: Gunakan alias untuk nama kelas, atau alias untuk nama namespace. Perhatikan bahwa PHP tidak mendukung mengimpor fungsi atau konstan.
Dalam PHP, alias untuk digunakan operator untuk mencapai berikut ini adalah penggunaan semua cara yang mungkin untuk mengimpor tiga contoh:
1, menggunakan penggunaan Operator impor / alias
<?php namespace foo; use My\Full\Classname as Another; // 下面的例子与 use My\Full\NSname as NSname 相同 use My\Full\NSname; // 导入一个全局类 use \ArrayObject; $obj = new namespace\Another; // 实例化 foo\Another 对象 $obj = new Another; // 实例化 My\Full\Classname 对象 NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func $a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象 // 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象 ?>
2, baris yang berisi beberapa pernyataan penggunaan
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // 实例化 My\Full\Classname 对象 NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func ?>
operasi impor dilakukan pada waktu kompilasi, tapi nama kelas yang dinamis, nama fungsi, atau nama konstan tidak.
3, Impor dan nama dinamis
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // 实例化一个 My\Full\Classname 对象 $a = 'Another'; $obj = new $a; // 实际化一个 Another 对象 ?>
Selain itu, operasi impor hanya mempengaruhi nama wajar tanpa pengecualian dan berkualitas. Sepenuhnya nama kualifikasi karena diidentifikasi, tidak terpengaruh oleh impor.
4, Mengimpor dan sepenuhnya nama berkualitas
<?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 ?>
Menggunakan ruang nama: mundur ke fungsi global / konstan
Dalam namespace, ketika PHP bertemu kelas wajar tanpa pengecualian, fungsi atau nama konstan, ia menggunakan strategi prioritas yang berbeda untuk menyelesaikan nama. Nama kelas dari nama namespace saat selalu memutuskan untuk. Oleh karena itu, dalam akses internal ke sistem atau tidak termasuk dalam namespace dari nama kelas, Anda harus menggunakan nama yang memenuhi syarat, misalnya:
1, mengakses kelas global dalam namespace
<?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 类 ?>
Untuk fungsi dan konstanta, fungsi tidak ada atau jika konstanta namespace saat ini, PHP akan jatuh kembali ke fungsi global atau konstanta di ruang angkasa.
2, fungsi global namespace dicadangkan / konstanta
<?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"; } ?>
ruang global
Jika Anda tidak menentukan namespace apapun, semua definisi kelas dan fungsi berada dalam ruang global dan PHP sebagai sebelum pengenalan konsep ruang nama. Sebelum nama diawali \ menunjukkan bahwa nama adalah ruang nama global, hal ini juga berlaku dari namespace lain bahkan jika nama tersebut berada.
Keterangan Gunakan ruang global
<?php namespace A\B\C; /* 这个函数是 A\B\C\fopen */ function fopen() { /* ... */ $f = \fopen(...); // 调用全局的fopen函数 return $f; } ?>
agar namespace
Karena dengan namespace, yang adalah penggunaan rawan kesalahan sebagian besar waktu kelas, untuk menemukan jalan kelas ini adalah apa yang.
<?php namespace A; use B\D, C\E as F; // 函数调用 foo(); // 首先尝试调用定义在命名空间"A"中的函数foo() // 再尝试调用全局函数 "foo" \foo(); // 调用全局空间函数 "foo" my\foo(); // 调用定义在命名空间"A\my"中函数 "foo" F(); // 首先尝试调用定义在命名空间"A"中的函数 "F" // 再尝试调用全局函数 "F" // 类引用 new B(); // 创建命名空间 "A" 中定义的类 "B" 的一个对象 // 如果未找到,则尝试自动装载类 "A\B" new D(); // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象 // 如果未找到,则尝试自动装载类 "B\D" new F(); // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象 // 如果未找到,则尝试自动装载类 "C\E" new \B(); // 创建定义在全局空间中的类 "B" 的一个对象 // 如果未发现,则尝试自动装载类 "B" new \D(); // 创建定义在全局空间中的类 "D" 的一个对象 // 如果未发现,则尝试自动装载类 "D" new \F(); // 创建定义在全局空间中的类 "F" 的一个对象 // 如果未发现,则尝试自动装载类 "F" // 调用另一个命名空间中的静态方法或命名空间函数 B\foo(); // 调用命名空间 "A\B" 中函数 "foo" B::foo(); // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法 // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B" D::foo(); // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法 // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D" \B\foo(); // 调用命名空间 "B" 中的函数 "foo" \B::foo(); // 调用全局空间中的类 "B" 的 "foo" 方法 // 如果类 "B" 未找到,则尝试自动装载类 "B" // 当前命名空间中的静态方法或函数 A\B::foo(); // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法 // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B" \A\B::foo(); // 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法 // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B" ?>
Nama Resolusi Ikuti aturan ini:
- Fungsi nama yang memenuhi syarat dari kelas dan panggilan konstan diselesaikan pada waktu kompilasi. Misalnya baru \ A \ B memutuskan untuk kelas A \ B.
- Semua nama wajar tanpa pengecualian dan berkualitas (bukan nama yang memenuhi syarat) dikonversi pada waktu kompilasi berdasarkan aturan impor saat ini. Misalnya, jika namespace A \ B \ C diimpor sebagai C, maka panggilan ke C \ D \ e () akan dikonversi ke A \ B \ C \ D \ e ().
- Namespace dalam, semua nama yang memenuhi syarat tidak diterjemahkan sesuai dengan aturan impor akan ditambahkan ke nama namespace saat di depannya. Misalnya, dalam namespace A \ B internal panggilan C \ D \ e (), maka C \ D \ e () diterjemahkan ke A \ B \ C \ D \ e ().
- nama kelas yang tidak memenuhi syarat dari converter (dengan nama lengkap bukan nama dari pengenalan singkat) pada waktu kompilasi berdasarkan aturan impor saat ini. Misalnya, jika namespace A \ B \ C diimpor sebagai C, yang baru C () dikonversi ke baru A \ B \ C () .
- Namespace internal yang (seperti A \ B), panggilan untuk memenuhi syarat nama fungsi diselesaikan pada saat runtime. Misalnya, panggilan berfungsi foo () teratasi seperti ini:
- Cari disebut A \ B \ foo di namespace saat ini () function
- Cobalah untuk menemukan dan memanggil global (global) fungsi ruang foo ().
- Namespace (misalnya, A \ B) internal untuk nama wajar tanpa pengecualian atau memenuhi syarat dari nama-nama kelas (bukan nama yang memenuhi syarat) panggilan teratasi pada waktu berjalan. Berikut adalah panggilan untuk baru C () dan baru D \ E () dari proses penyelesaian: baru C () parsing:
- Cari A \ B \ C kelas dalam namespace saat ini.
- Ia mencoba untuk autoload A \ B \ C.
- Dalam nama kelas diawali dengan nama namespace saat menjadi: A \ B \ D \ E , kemudian mencari kelas.
- Ia mencoba untuk autoload A \ B \ D \ E.