Ruang nama PHP (ruang nama)

Ruang nama PHP (ruang nama) telah ditambahkan dalam PHP 5.3

Apakah ruang nama? Secara umum, ruang nama ialah cara untuk merangkum sesuatu. Abstraksi ini boleh didapati di banyak tempat. Contohnya, dalam sistem pengendalian, direktori

digunakan untuk mengumpulkan fail berkaitan Untuk fail dalam direktori, ia memainkan peranan ruang nama. Contohnya, fail foo.txt boleh wujud dalam direktori /home/greg dan /home/other pada masa yang sama, tetapi dua fail foo.txt tidak boleh wujud dalam direktori yang sama. Selain itu, apabila mengakses fail

foo.txt di luar direktori /home/greg, kita mesti meletakkan nama direktori dan pemisah direktori sebelum nama fail untuk mendapatkan /home/greg/foo.txt. Prinsip ini digunakan dalam bidang pengaturcaraan ialah konsep



ruang nama.

Ruang nama PHP boleh menyelesaikan dua jenis masalah berikut: 1 dan Konflik nama antara kelas/fungsi/pemalar dalaman PHP atau kelas/fungsi/pemalar pihak ketiga.

2. Cipta nama alias (atau pendek) untuk nama pengecam yang sangat panjang (biasanya ditakrifkan untuk mengurangkan jenis masalah pertama) untuk meningkatkan kebolehbacaan kod sumber.


Tentukan ruang nama Secara lalai, semua pemalar, kelas dan fungsi nama diletakkan dalam ruang global, sama seperti sebelum PHP menyokong ruang nama.

Ruang nama diisytiharkan menggunakan ruang nama kata kunci. Jika fail mengandungi ruang nama, ia mesti mengisytiharkan ruang nama sebelum semua kod lain.

Sintaksnya adalah seperti berikut:

<?php
// 定义代码在 'MyProject' 命名空间中
namespace MyProject;
// ... 代码 ...
?>
你也可以在同一个文件中定义不同的命名空间代码,如:
<?php
namespace MyProject1;
// MyProject1 命名空间中的PHP代码
namespace MyProject2;
// MyProject2 命名空间中的PHP代码
// 另一种语法
namespace MyProject3 {
// MyProject3 命名空间中的PHP代码
}
?>
Satu-satunya kod undang-undang sebelum mengisytiharkan ruang nama ialah pernyataan isytihar yang mentakrifkan bagaimana fail sumber adalah dikodkan. Selain itu, semua kod bukan PHP termasuk aksara ruang kosong tidak boleh muncul sebelum pengisytiharan ruang nama:

<?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();
 }
 ?>

dan kod berikut akan melaporkan ralat

<html>
 <?php
 namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句
 ?>


ruang nama sangat serupa dengan hubungan antara direktori dan fail ruang nama PHP juga membolehkan anda menentukan nama ruang nama hierarki. Oleh itu, nama ruang nama boleh ditakrifkan dalam cara hierarki:

<?php
 namespace MyProject\Sub\Level;  //声明分层次的单个命名空间
 const CONNECT_OK = 1;
 class Connection { /* ... */ }
 function Connect() { /* ... */  }
 
 ?>

Contoh di atas mencipta MyProjectSubLevelCONNECT_OK yang berterusan, kelas MyProjectSubLevelConnection dan fungsi MyProjectSubLevelConnect.


Penggunaan ruang nama

Sebelum membincangkan cara menggunakan ruang nama, anda mesti memahami cara PHP mengetahui elemen ruang nama yang hendak digunakan. Analogi mudah boleh dibuat antara ruang nama PHP dan sistem fail. Terdapat tiga cara untuk mengakses fail dalam sistem fail:

1. Format nama fail relatif seperti foo.txt. Ia akan dihuraikan sebagai currentdirectory/foo.txt, dengan currentdirectory mewakili direktori semasa. Jadi jika direktori semasa ialah /home/foo, nama fail diselesaikan kepada /home/foo/foo.txt.

2. Nama laluan relatif adalah dalam bentuk subdirektori/foo.txt. Ia akan dihuraikan sebagai direktori semasa/subdirektori/foo.txt. ​  

3. Nama laluan mutlak adalah dalam bentuk /main/foo.txt. Ia akan dihuraikan sebagai /main/foo.txt.

Elemen dalam ruang nama PHP menggunakan prinsip yang sama. Contohnya, nama kelas boleh dirujuk dalam tiga cara:

1 Nama tidak layak atau nama kelas tanpa awalan , contohnya $a=. new foo(); atau foo::staticmethod();. Jika ruang nama semasa ialah currentnamespace, foo akan diselesaikan kepada currentnamespacefoo. Jika kod yang menggunakan foo bersifat global dan tidak mengandungi kod dalam mana-mana ruang nama, foo akan diselesaikan sebagai foo. Amaran: Jika fungsi atau pemalar dalam ruang nama tidak ditentukan, fungsi tidak layak atau nama pemalar diselesaikan kepada fungsi global atau nama tetap.

2. Nama layak, atau nama termasuk awalan , seperti $a = new subnamespacefoo( atau subnamespacefoo::staticmethod();. Jika ruang nama semasa ialah currentnamespace, foo akan diselesaikan kepada currentnamespacesubnamespacefoo. Jika kod yang menggunakan foo adalah global, kod tidak terkandung dalam mana-mana ruang nama, foo akan diselesaikan kepada subnamespacefoo.

3.  Nama yang layak sepenuhnya, atau nama yang termasuk operator awalan global, Contohnya, $a = new currentnamespacefoo( atau currentnamespacefoo::staticmethod ( );. Dalam kes ini, foo sentiasa diselesaikan kepada nama literal currentnamespacefoo dalam kod.

Berikut ialah contoh menggunakan ketiga-tiga kaedah ini:

Contoh

<?php
 namespace Foo\Bar\subnamespace;
 
 const FOO = 1;
 function foo() {}
 class foo
 {
     static function staticmethod() {}
 }
 ?>

Contoh

<?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 bahawa untuk mengakses mana-mana kelas global, fungsi atau pemalar, anda boleh menggunakan nama yang layak sepenuhnya, seperti strlen() atau Exception atau INI_ALL.


Akses kelas global, fungsi dan pemalar di dalam ruang nama:

<?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 ciri bahasa dinamik

Pelaksanaan ruang nama PHP Dipengaruhi oleh ciri dinamik bahasanya sendiri. Jadi, jika anda ingin menukar kod di bawah kepada ruang nama, akses elemen secara dinamik.

Instance

<?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
 ?>

Hasil larian program:

nama kelas::__bina nama fungsi global

mesti menggunakan nama yang layak sepenuhnya (nama kelas termasuk awalan ruang nama). Ambil perhatian bahawa garis miring ke belakang utama tidak diperlukan kerana tiada perbezaan antara nama layak dan layak sepenuhnya dalam nama kelas dinamik, nama fungsi atau nama tetap.


Instance

Akses dinamik kepada elemen ruang nama

<?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
 ?>

Keputusan pelaksanaan program:

nama kelas::__bina nama fungsi global nama kelas::__build nama fungsi global namespacenameclassname::__build namespacenameclassname::__build namespacenamefuncname namespacenamefuncname ruang nama ruang nama


kata kunci ruang nama dan pemalar __NAMESPACE__

PHP menyokong dua kaedah abstrak untuk mengakses elemen dalam ruang nama semasa, pemalar ajaib __NAMESPACE__ dan kata kunci ruang nama.

Nilai pemalar __NAMESPACE__ ialah rentetan yang mengandungi nama ruang nama semasa. Dalam kod global, tidak termasuk dalam mana-mana ruang nama, ia mengandungi rentetan kosong.

Contoh

__NAMESPACE__ Contoh, dalam Kod dalam ruang nama

<?php
 namespace MyProject;
 header("Content-type:text/html;charset=utf-8");    //设置编码
 echo '"', __NAMESPACE__, '"'; // 输出 "MyProject"
 ?>

hasil pelaksanaan program:

"MyProject"

Instance

__NAMESPACE__ contoh, kod global

<?php
 header("Content-type:text/html;charset=utf-8");    //设置编码
 
 echo '"', __NAMESPACE__, '"'; // 输出 "MyProject"
 ?>

Hasil jalankan program:

""

Instance

Malar __NAMESPACE__ berguna apabila mencipta nama secara dinamik, contohnya:

Buat nama secara dinamik menggunakan __NAMESPACE__

<?php
 namespace MyProject;
 
 function get($classname)
 {
     $a = __NAMESPACE__ . '\' . $classname;
     return new $a;
 }
 ?>

Kata kunci ruang nama boleh digunakan untuk mengakses elemen secara eksplisit dalam ruang nama atau sub-ruang nama semasa. Ia bersamaan dengan pengendali diri dalam kelas.

Instance

operator ruang nama, kod dalam ruang nama

<?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
 ?>

Instance

pengendali ruang nama, kod global

<?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
 ?>

Gunakan ruang nama: alias/import

Sokongan ruang nama PHP mempunyai dua cara menggunakan alias atau import: menggunakan alias untuk nama kelas, atau menggunakan alias untuk nama ruang nama. Ambil perhatian bahawa PHP tidak menyokong fungsi pengimportan atau pemalar.

Dalam PHP, aliasing dilaksanakan melalui penggunaan operator Berikut ialah contoh menggunakan ketiga-tiga kaedah import yang mungkin:


1 , gunakan operator penggunaan untuk. import/gunakan 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. Satu baris mengandungi berbilang 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
 ?>

3. Import dan nama dinamik

<?php
 use My\Full\Classname as Another, My\Full\NSname;
 
 $obj = new Another; // 实例化一个 My\Full\Classname 对象
 $a = 'Another';
 $obj = new $a;      // 实际化一个 Another 对象
 ?>

4 Import dan nama yang layak sepenuhnya

rreee

<🎜. >


Gunakan ruang nama: sandaran fungsi/pemalar global

Apabila PHP menemui kelas, fungsi atau nama tetap yang tidak layak dalam ruang nama, ia menggunakan strategi keutamaan yang berbeza untuk menyelesaikan nama tersebut. Nama kelas sentiasa diselesaikan kepada nama dalam ruang nama semasa. Oleh itu apabila mengakses nama kelas yang berada di dalam sistem atau tidak termasuk dalam ruang nama, anda mesti menggunakan nama yang layak sepenuhnya

Contohnya:

1 Akses kelas global dalam ruang nama

<?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
 ?>

Untuk fungsi dan pemalar, jika fungsi atau pemalar tidak wujud dalam ruang nama semasa, PHP akan kembali menggunakan fungsi atau pemalar dalam ruang global.

2. Sandarkan fungsi/pemalar global dalam ruang nama

<?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 类
 ?>


Ruang global

Jika tiada ruang nama ditakrifkan, semua kelas dan fungsi ditakrifkan dalam ruang global, sama seperti sebelum PHP memperkenalkan konsep ruang nama. Awalan nama menunjukkan bahawa nama itu berada dalam ruang global, walaupun nama itu berada dalam ruang nama lain.

Instance

Gunakan arahan ruang global

<?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";
 }
 ?>

Pesanan ruang nama

Sejak ruang nama dicipta, perkara yang paling mudah ralat ialah apabila menggunakan kelas, apakah laluan carian untuk kelas ini.

<?php
 namespace A\B\C;
 
 /* 这个函数是 A\B\C\fopen */
 function fopen() {
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
 }
 ?>

Penyelesaian nama mengikut peraturan berikut:

1 Panggilan ke fungsi, kelas dan pemalar dengan nama yang layak sepenuhnya diselesaikan semasa penyusunan masa. Sebagai contoh, AB baharu memutuskan ke kelas AB.

2. Semua nama yang tidak layak dan nama yang layak (nama tidak layak sepenuhnya) ditukar pada masa penyusunan mengikut peraturan import semasa. Sebagai contoh, jika ruang nama ABC diimport sebagai C, maka panggilan ke CDe() akan ditukar kepada ABCDe().

3. Dalam ruang nama, semua nama yang layak yang tidak ditukar mengikut peraturan import akan mempunyai nama ruang nama semasa di hadapannya. Sebagai contoh, jika CDe() dipanggil dalam ruang nama AB, CDe() akan ditukar kepada ABCDe().

4. Nama kelas yang tidak layak ditukar pada masa penyusunan mengikut peraturan import semasa (nama penuh digunakan dan bukannya nama import pendek). Sebagai contoh, jika ruang nama ABC diimport sebagai C, maka C() baharu ditukar kepada ABC() baharu.

5. Dalam ruang nama (mis. AB), panggilan fungsi kepada nama yang tidak layak diselesaikan pada masa jalan. Contohnya, panggilan ke fungsi foo() dihuraikan seperti ini:

1 Cari fungsi bernama ABfoo() dalam ruang nama semasa

2 () di angkasa.

6. Panggilan ke nama yang tidak layak atau kelas nama yang layak (nama tidak layak sepenuhnya) dalam ruang nama (mis. AB) diselesaikan pada masa jalan. Berikut ialah proses penghuraian untuk memanggil C() baharu dan DE() baharu: Penghuraian C():

1. Cari kelas ABC dalam ruang nama semasa.

2. Cuba muatkan kelas ABC secara automatik.

Analisis DE() baharu:

3 Tambahkan nama ruang nama semasa di hadapan nama kelas untuk menjadi: ABDE, dan kemudian cari kelas.

4. Cuba muatkan kelas ABDE secara automatik.

Untuk merujuk kepada kelas global dalam ruang nama global, nama C() yang layak sepenuhnya mesti digunakan.



Meneruskan pembelajaran
||
<?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 ?>
  • Cadangan kursus
  • Muat turun perisian kursus