PHP namespace (namespace)
PHP namespace (namespace) จะถูกเพิ่มใน PHP 5.3 ถ้าคุณได้เรียนรู้ C # และ Java, namespace ที่ไม่ได้เป็นอะไรสิ่งใหม่ ๆ แต่ใน PHP ซึ่งยังคงมีความสำคัญเป็นสิ่งที่สำคัญมาก
namespaces PHP สามารถแก้ปัญหาทั้งสองต่อไปนี้:
- รหัสผู้ใช้เขียน PHP ภายในชั้นเรียน / ฟังก์ชั่น / ค่าคงที่หรือความขัดแย้งของบุคคลที่สามเรียน / ฟังก์ชั่น / ชื่อค่าคงที่ระหว่าง
- ในฐานะที่เป็นชื่อตัวระบุยาว (ปกติเพื่อบรรเทาประเภทแรกกำหนด) สร้างชื่อแทน (หรือสั้น) ชื่อของการปรับปรุงการอ่านของรหัสแหล่งที่มา
กำหนด namespaces
โดยค่าเริ่มต้นทั้งหมดคงเรียนและชื่อฟังก์ชั่นที่มีอยู่ในพื้นที่ของโลกเพียงเช่นเดียวกับก่อนที่จะมีการสนับสนุน namespace PHP
ประกาศ namespace โดย namespace คำหลัก ถ้าชื่อไฟล์ที่มีช่องว่างก็จะต้องประกาศ namespace ก่อนรหัสอื่น ๆ ไวยากรณ์เป็นดังนี้;
< ?php // 定义代码在 'MyProject' 命名空间中 namespace MyProject; // th. 代码 th.
นอกจากนี้คุณยังสามารถกำหนด namespaces แตกต่างกันในไฟล์เดียวกันในรหัสเช่น:
< ?php namespace MyProject1; // MyProject1 命名空间中的PHP代码 namespace MyProject2; // MyProject2 命名空间中的PHP代码 // 另一种语法 namespace MyProject3 { // MyProject3 命名空间中的PHP代码 } ?>
ก่อนที่จะประกาศใน namespace รหัสทางกฎหมายที่ไม่ซ้ำกันถูกนำมาใช้ในการกำหนดแฟ้มแหล่งที่มาวิธีการเข้ารหัสประกาศคำสั่ง รหัสไม่ใช่ทั้งหมด PHP รวมถึงช่องว่างไม่สามารถปรากฏก่อนการประกาศการ namespace
<?php declare(encoding='UTF-8'); //定义多个命名空间和不包含在命名空间中的代码 namespace MyProject { const CONNECT_OK = 1; class Connection { /* th. */ } function connect() { /* th. */ } } namespace { // 全局代码 session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
ข้อผิดพลาดไวยากรณ์รหัสต่อไปนี้จะเกิดขึ้น:
<html> <?php namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句 ?>
Subnamespaces
ความสัมพันธ์กับไดเรกทอรีและไฟล์มากเหมือน namespaces PHP นอกจากนี้ยังช่วยในการระบุชื่อของ namespace ลำดับชั้น ดังนั้นชื่อของ namespace ที่สามารถกำหนดโดยใช้ลักษณะลำดับชั้น:
<?php namespace MyProject\Sub\Level; //声明分层次的单个命名空间 const CONNECT_OK = 1; class Connection { /* th. */ } function Connect() { /* th. */ } ?>
ตัวอย่างข้างต้นคงสร้าง MyProject \ ต \ ระดับ \ CONNECT_OK ชนิด MyProject \ ต \ ระดับ \ การเชื่อมต่อและการทำงาน MyProject \ ต \ ระดับ \ Connect
namespaces
PHP ชื่อชั้น namespace สามารถอ้างอิงในสามวิธี:
ชื่อไม่มีเงื่อนไขหรือชื่อของชั้นไม่ได้มีคำนำหน้าเช่น $ A = foo ใหม่ (); หรือ Foo :: StaticMethod (); ถ้า namespace ปัจจุบันคือ currentnamespace, foo จะถูกตีความว่าเป็น currentnamespace \ Foo หาก Foo เป็นรหัสทั่วโลกรหัสไม่ได้มี namespace ใด ๆ ก็จะถูกแยกเป็น Foo Foo คำเตือน: หากฟังก์ชั่น namespace หรือคงที่ไม่ได้กำหนดไว้แล้วชื่อฟังก์ชันหรือชื่อคงไม่มีเงื่อนไขจะได้รับการแก้ไขไปที่ชื่อฟังก์ชั่นระดับโลกหรือชื่ออย่างต่อเนื่อง
ชื่อที่ผ่านการรับรองหรือชื่อมีคำนำหน้าเช่น $ A = ใหม่ subnamespace \ Foo ( ); หรือ subnamespace \ Foo :: StaticMethod (); ถ้า namespace ปัจจุบันคือ currentnamespace แล้ว foo จะถูกแยกเป็น currentnamespace \ subnamespace \ Foo หาก Foo เป็นรหัสทั่วโลกรหัสไม่ได้มี namespace ใด ๆ Foo จะได้รับการแก้ไขเพื่อ subnamespace \ Foo
ครบชื่อผู้ทรงคุณวุฒิหรือรวมคำนำหน้าชื่อผู้ประกอบการทั่วโลกเช่น $ a = ใหม่ \ currentnamespace \ Foo (); หรือ \ currentnamespace \ Foo :: StaticMethod () ; ในกรณีนี้ Foo มักจะได้รับการแก้ไขให้เป็นชื่อของคำรหัส (ชื่อตัวอักษร) currentnamespace \ Foo
นี่คือตัวอย่างของทั้งสามวิธี:
รหัสไฟล์ 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 () หรือ \ ข้อยกเว้นหรือ \ INI_ALL
namespace เข้าถึงชั้นเรียนทั่วโลกฟังก์ชั่นและค่าคงที่:
<?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 ?>
Namespaces และคุณลักษณะภาษาแบบไดนามิก
IMPLEMENT PHP namespace รับผลกระทบจากคุณลักษณะของภาษาแบบไดนามิกของตัวเอง ดังนั้นถ้าคุณต้องการรหัสต่อไปนี้ลง namespaces องค์ประกอบการเข้าถึงแบบไดนามิก
รหัสไฟล์ 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 ?>
คุณต้องใช้ชื่อที่มีคุณสมบัติครบถ้วน (รวมถึงชื่อชั้นของคำนำหน้า namespace) ที่ โปรดทราบว่าเนื่องจากในชื่อแบบไดนามิกชั้นชื่อฟังก์ชันหรือชื่อคงชื่อที่มีคุณภาพและชื่อครบถ้วนไม่แตกต่างกันดังนั้นทับขวาเป็นผู้นำที่ไม่จำเป็น
องค์ประกอบ namespace การเข้าถึงแบบไดนามิก
<?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 และค่าคงที่ __NAMESPACE__
PHP สนับสนุนทั้งสองวิธีในการเข้าถึงปัจจุบัน namespace องค์ประกอบภายในนามธรรม __ คง NAMESPACE__ เมจิกและ namespace คำหลัก
__NAMESPACE__ ค่าคงที่เป็นสตริงที่มีชื่อของ namespace ปัจจุบัน ในทั่วโลก, รหัสไม่รวม 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; } ?>
คำหลัก namespace สามารถนำมาใช้ในการเข้าถึง namespace ปัจจุบันหรือองค์ประกอบย่อย namespace อย่างชัดเจน มันจะเทียบเท่ากับระดับของผู้ประกอบการเอง
namespace รหัสผู้ประกอบการ 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 ?>
ผู้ประกอบการ namespace รหัสทั่วโลก
<?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 ?>
ใช้ namespaces: นามแฝง / นำเข้า
namespaces สนับสนุน PHP สองโดยใช้นามแฝงหรือนำเข้า: ใช้นามแฝงสำหรับชื่อชั้นหรือนามแฝงสำหรับชื่อใน namespace โปรดทราบว่า PHP ไม่สนับสนุนการนำเข้าฟังก์ชั่นหรือคงที่
ใน PHP นามแฝงสำหรับใช้ประกอบการเพื่อให้บรรลุต่อไปนี้คือการใช้วิธีที่เป็นไปได้ทั้งหมดจะนำเข้าสามตัวอย่าง:
1 โดยใช้การใช้งานที่ผู้ประกอบการนำเข้า / นามแฝง
<?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 บรรทัดที่ประกอบด้วยงบการใช้งานหลาย ๆ
<?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, นำเข้าและชื่อแบบไดนามิก
<?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 ?>
ใช้ namespaces: fallback ฟังก์ชั่นระดับโลก / คงที่
ใน namespace เมื่อ PHP พบชั้นไม่มีเงื่อนไขและฟังก์ชั่นหรือชื่อคงที่จะใช้กลยุทธ์การจัดลำดับความสำคัญที่แตกต่างกันในการแก้ไขชื่อ ชื่อคลาสชื่อ namespace ปัจจุบันมักจะหายไป ดังนั้นในการเข้าถึงภายในของระบบหรือไม่รวมอยู่ใน namespace ของชื่อชั้นที่คุณจะต้องใช้ชื่อที่มีคุณสมบัติครบถ้วนตัวอย่างเช่น:
1, การเข้าถึงการเรียนระดับโลกในการใน 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 类 ?>
สำหรับฟังก์ชั่นและค่าคงที่ฟังก์ชันไม่มีอยู่หรือถ้าค่าคงที่ namespace ปัจจุบัน, PHP จะถอยกลับไปฟังก์ชั่นระดับโลกหรือค่าคงที่ในพื้นที่
2 ฟังก์ชั่นระดับโลก namespace ลิขสิทธิ์ / คงที่
<?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"; } ?>
พื้นที่ทั่วโลก
หากคุณไม่ได้กำหนด namespace ใด ๆ ทุกคำจำกัดความของการเรียนและการทำงานอยู่ในพื้นที่ทั่วโลกและ PHP เป็นก่อนที่จะนำแนวคิดของ namespaces ที่ ก่อนที่จะนำหน้าชื่อ \ บ่งชี้ว่าชื่อเป็นพื้นที่ชื่อระดับโลกก็ยังเป็นจริงของ namespace อื่น ๆ แม้ว่าชื่อตั้งอยู่
อธิบายการใช้งานพื้นที่ทั่วโลก
<?php namespace A\B\C; /* 这个函数是 A\B\C\fopen */ function fopen() { /* th. */ $f = \fopen(th.); // 调用全局的fopen函数 return $f; } ?>
namespace สั่งซื้อ
ตั้งแต่ที่มี namespace ซึ่งคือการใช้ผิดพลาดได้ง่ายที่สุดของเวลาเรียนเพื่อหาเส้นทางของชั้นนี้คือสิ่งที่
<?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" ?>
การแก้ไขชื่อตามกฎเหล่านี้:
- ฟังก์ชั่นชื่อครบถ้วนของชั้นและสายคงได้รับการแก้ไขที่รวบรวมเวลา ตัวอย่างใหม่ \ A \ B หายไประดับ A \ บี
- ชื่อไม่มีเงื่อนไขและมีคุณสมบัติ (ไม่ใช่ชื่อที่มีคุณสมบัติครบถ้วน) แปลงที่รวบรวมเวลาขึ้นอยู่กับกฎระเบียบการนำเข้าในปัจจุบัน ตัวอย่างเช่นถ้า namespace A \ B \ C จะถูกนำเข้าเป็น C แล้วโทรไปที่ C \ D \ E (ก) จะถูกแปลงเป็น A \ B \ C \ D \ E ()
- namespace ภายในชื่อทั้งหมดที่มีคุณภาพไม่ได้แปลตามกฎนำเข้าจะถูกเพิ่มชื่อ namespace ปัจจุบันในด้านหน้าของมัน ยกตัวอย่างเช่นในการ namespace A \ B ภายในโทร C \ D \ E () แล้ว C \ D \ E () จะแปลให้ A \ B \ C \ D \ E ()
- ชื่อชั้นไม่ผ่านการรับรองของแปลง (ที่มีชื่อเต็มแทนชื่อของการแนะนำสั้น) ที่รวบรวมเวลาขึ้นอยู่กับกฎระเบียบการนำเข้าในปัจจุบัน ตัวอย่างเช่นถ้า namespace A \ B \ C จะถูกนำเข้าเป็น C ใหม่ C () จะถูกแปลงใหม่ A \ B \ C ()
- namespace ภายใน (เช่น A \ B) โทรไปยังชื่อฟังก์ชันไม่มีเงื่อนไขได้รับการแก้ไขที่รันไทม์ ยกตัวอย่างเช่นการเรียกใช้ฟังก์ชัน foo () จะมีมติเช่นนี้
- ค้นหาที่เรียกว่า A \ B \ Foo ใน namespace ปัจจุบัน () ฟังก์ชั่น
- พยายามที่จะหาและเรียกระดับโลก (Global) ฟังก์ชั่นพื้นที่ foo ()
- namespace (ตัวอย่างเช่น A \ B) ภายในเพื่อชื่อไม่เหมาะสมหรือมีคุณสมบัติของชื่อชั้น (ไม่ใช่ชื่อที่มีคุณสมบัติครบถ้วน) โทรได้รับการแก้ไขในเวลาทำงาน นี่คือการเรียกร้องให้ใหม่ C () และใหม่ d \ E () ของกระบวนการความละเอียด: ใหม่ C () แยก:
- หา \ คลาส B \ C ใน namespace ปัจจุบัน
- ก็พยายามที่จะ AUTOLOAD A \ B \ ซี
- ในชื่อชั้นนำหน้าด้วยชื่อ namespace ปัจจุบันกลายเป็น: A \ B \ D \ E , แล้วมองหาชั้นเรียน
- ก็พยายามที่จะ AUTOLOAD A \ B \ D \ อี