批改状态:合格
老师批语:能完全 把命名空间理解 , 也不简单
非限定名称
完全限定名称
非完全限定名称
全局成员的四大家族: 类, 接口, 函数和常量.
namespace ns1 {require('../../out.php');class Demo1{public static $prop1 = 'hello';public static function func1(){return __METHOD__;}}// 在当前命名空间中使用本命名空间的成员, 可以省略当前空间名称, 即使用非限定名称即可./* Demo1::$prop1 等效于 \ns1\Demo1::$prop1 */echobr(Demo1::$prop1);/* Demo1::func1() 等效于 \ns1\Demo1::func1() */echobr(Demo1::func1());/* result:hellons1\Demo1::func1*/}namespace ns2\ns2_1 {const PI = 3.14;class Demo1{public static $prop = 'hi';public static function func1(){return __METHOD__;}}}namespace ns2 {// 访问其他命名空间中的成员, 需要使用完全限定名称echobr(\ns1\Demo1::$prop1);echobr(\ns1\Demo1::func1());/* result:hellons1\Demo1::func1*/// 访问具有层级关系的下级命名空间中的成员时, 可以使用非完全限定名称echobr(ns2_1\Demo1::$prop);echobr(ns2_1\Demo1::func1());echobr(ns2_1\PI);/* result:hins2\ns2_1\Demo1::func13.14*/}
__NAMESPACE__.namespace关键字创建命名空间创建命名空间的语法
创建语法 1:
namespace 命名空间名称;// do something...
这种方式只能创建命名空间, 不能创建匿名空间. 匿名空间就是默认空间, 根空间, 全局空间.
/* 创建命名空间 */namespace ns1;// do something.../* 这样创建匿名空间会报错 */namespace ;// can not do something...
创建语法 2:
namespace 命名空间名称 {// do something...}
这种方式可以创建命名空间和匿名空间
/* 创建命名空间 */namespace ns1 {// do something...}/* 创建全局空间 */namespace {// 这里是全局空间}
/* 全局空间 */namespace {$username = '张三';function sayHello($username){echobr('hello ' . $username);}class Demo{public static $prop = 'hello';}}/* 非全局命名空间 */namespace np1 {// 当前命名空间中并没有$username变量, PHP会到全局空间中去找该变量echobr($username);/* result: 张三 */// 跟变量类似sayHello('James');/* result: hello James */// 当前控件没有Demo类, 但PHP也不会到全局空间中查找, 直接报错echobr(Demo::$props);/* result: Fatal error: Uncaught Error: Class 'np1\Demo' not found in D:\phpstudy_pro\WWW\php11\PHP\0505\homework\homework.php:112 Stack trace: #0 {main} thrown in D:\phpstudy_pro\WWW\php11\PHP\0505\homework\homework.php on line 112 */}/* 命名空间中有跟根空间同名的成员 */namespace np2 {CONST NAME = 'lisi';function sayHello($username) {echobr('hi ' . $username);}class Demo {public static $prop = 'hi';}// 当前命名空间中已有相关成员的情况/* 使用当前命名空间中的常量 */echobr(NAME);/* 使用根空间中的同名常量 */echobr(\NAME);/* result:lisi全局*//* 使用当前命名空间的函数 */sayHello('Marry');/* 使用根空间中的同名函数 */\sayHello('Lily');/* result:hi Marryhello Lily*//* 使用当前命名空间中的类 */echobr(Demo::$prop);/* 使用根空间中的同名类 */echobr(\Demo::$prop);/* result:hihello*/}
use关键字来声明空间别名. use默认从根空间开始. 使用as关键字来指定空间/成员别名。声明语法:
/* 为名称空间起别名 */use 命名空间名称 as 别名名称;/* 为名称空间的成员其别名 *//* 1. 类 */use 省略第一个\的完全限定名称类名/非完全限定名称类名 as 别名名称;/* 或者 */use 省略第一个\的完全限定名称类名/非完全限定名称类名;/* 2. 函数 */use function ... as ...;/* 或者 */use function ...;/* 3. 常量 */use constant ... as ...;/* 或者 */use constant ...;
示例:
namespace ns1\test1 {class Demo {public static $username = '张三';}class Demo1 {public staitc $username = '李四';}}namespace ns2 {// 给命名空间起别名use ns1\test1 as nt1;// 给命名空间中的类起别名use ns1\test1\Demo1 as Demo1;// 当别名跟类名相同时, 可以省略别名use ns1\test1\Demo;// 使用别名简化调用echobr('姓名: ' . nt1\Demo1::$username);/* result:李四*/// 给类起别名echobr('姓名: ' . Demo1::$username);echobr('姓名: ' . Demo::$username);/* result:姓名: 李四姓名: 张三*/}
实现类自动加载的条件
命名空间必须跟类文件的绝对路径一一对应。
当前类的名称必须跟当前文件的名称完全一致。
类自动加载的目的是要省略使用
require引入各种文件。
一般把实现类自动加载的函数用系统函数 spl_autoload_register()函数进行注册。当代码中使用到未被加载的类时,PHP 会自动调用由 spl_autoload_register()函数注册的函数去尝试加载这个类。
类自动加载示例:
// autoload.php// 封装自动加载器try {// 系统函数: spl_autoload_register(): 注册执行加载类的函数spl_autoload_register(function ($className) {// 1. 将类名中的反斜线改为当前系统中的目录分隔符$path = str_replace('\\', DIRECTORY_SEPARATOR, $className);// echobr($path);// 2. 生成真正要加载的类文件名称$file = __DIR__ . DIRECTORY_SEPARATOR . $path . '.php';// echobr($file);// 3. 加载这个文件require $file;});} catch (Exception $e) {die($e->getMessage());}
// Demo1.phpnamespace tool;class Demo1 {public static function func1() {return __METHOD__;}public static function echobr($str = '') {echo $str . '<br>';}}
namespace work;// 1. 加载自动加载器文件require('autoload.php');// 2. 使用use为待加载的类起别名use tool\Demo1;// 3. 使用待加载的类Demo1::echobr(Demo1::func1());/* 成功执行需加载类的方法,即自动加载生效。result: tool\Demo1::func1 */
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号