Blogger Information
Blog 57
fans 3
comment 0
visits 60377
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP基础-名称空间/三种限定名称/空间和类的别名/类自动加载
岂几岂几
Original
731 people have browsed it

命名空间

1. 非限定名称, 限定名称和完全限定名称

非限定名称

  • 从当前空间中访问当前空间中的成员, 可以省略当前空间名称. 即, 非限定名称: 成员之前的命名空间可省略
  • 不能有”\”, 可以理解成文件当前路径.

完全限定名称

  • 当需要访问其他命名空间下的成员时, 需要使用完全限定名称, 类似全局路径.
  • 必须以”\”开始.

非完全限定名称

  • 在成员前面出现了空间名称, 但是并不是从根空间开始, 就是非完全限定名称
  • 在命名空间之间有层级关系时, 如上级空间访问下级空间的成员时使用非完全限定名称.
  • 至少要有一个”\“, 且不能在首位, 可以理解成相对路径

全局成员的四大家族: 类, 接口, 函数和常量.

  1. namespace ns1 {
  2. require('../../out.php');
  3. class Demo1
  4. {
  5. public static $prop1 = 'hello';
  6. public static function func1()
  7. {
  8. return __METHOD__;
  9. }
  10. }
  11. // 在当前命名空间中使用本命名空间的成员, 可以省略当前空间名称, 即使用非限定名称即可.
  12. /* Demo1::$prop1 等效于 \ns1\Demo1::$prop1 */
  13. echobr(Demo1::$prop1);
  14. /* Demo1::func1() 等效于 \ns1\Demo1::func1() */
  15. echobr(Demo1::func1());
  16. /* result:
  17. hello
  18. ns1\Demo1::func1
  19. */
  20. }
  21. namespace ns2\ns2_1 {
  22. const PI = 3.14;
  23. class Demo1
  24. {
  25. public static $prop = 'hi';
  26. public static function func1()
  27. {
  28. return __METHOD__;
  29. }
  30. }
  31. }
  32. namespace ns2 {
  33. // 访问其他命名空间中的成员, 需要使用完全限定名称
  34. echobr(\ns1\Demo1::$prop1);
  35. echobr(\ns1\Demo1::func1());
  36. /* result:
  37. hello
  38. ns1\Demo1::func1
  39. */
  40. // 访问具有层级关系的下级命名空间中的成员时, 可以使用非完全限定名称
  41. echobr(ns2_1\Demo1::$prop);
  42. echobr(ns2_1\Demo1::func1());
  43. echobr(ns2_1\PI);
  44. /* result:
  45. hi
  46. ns2\ns2_1\Demo1::func1
  47. 3.14
  48. */
  49. }

2. 创建和使用命名空间

2.1 创建命名空间

  • 在同一个脚本中可以创建多个命名空间
  • 获取当前命名空间, 可以使用__NAMESPACE__.
  • 使用namespace关键字创建命名空间
  • 创建命名空间的语法

    • 创建语法 1:

      1. namespace 命名空间名称;
      2. // do something...

      这种方式只能创建命名空间, 不能创建匿名空间. 匿名空间就是默认空间, 根空间, 全局空间.

      1. /* 创建命名空间 */
      2. namespace ns1;
      3. // do something...
      4. /* 这样创建匿名空间会报错 */
      5. namespace ;
      6. // can not do something...
    • 创建语法 2:

      1. namespace 命名空间名称 {
      2. // do something...
      3. }

      这种方式可以创建命名空间和匿名空间

      1. /* 创建命名空间 */
      2. namespace ns1 {
      3. // do something...
      4. }
      5. /* 创建全局空间 */
      6. namespace {
      7. // 这里是全局空间
      8. }

2.2 使用命名空间

  • 对于函数和常量来说, 如果当前命名空间中不存在该函数或常量, PHP 会退而使用全局空间中的函数或常量.
  • 类名称总是解析到当前命名空间中的名称. 因此在访问系统内部或不包含在命名空间中的类名称时, 必须使用完全限定名称.
  1. /* 全局空间 */
  2. namespace {
  3. $username = '张三';
  4. function sayHello($username)
  5. {
  6. echobr('hello ' . $username);
  7. }
  8. class Demo
  9. {
  10. public static $prop = 'hello';
  11. }
  12. }
  13. /* 非全局命名空间 */
  14. namespace np1 {
  15. // 当前命名空间中并没有$username变量, PHP会到全局空间中去找该变量
  16. echobr($username);
  17. /* result: 张三 */
  18. // 跟变量类似
  19. sayHello('James');
  20. /* result: hello James */
  21. // 当前控件没有Demo类, 但PHP也不会到全局空间中查找, 直接报错
  22. echobr(Demo::$props);
  23. /* 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 */
  24. }
  25. /* 命名空间中有跟根空间同名的成员 */
  26. namespace np2 {
  27. CONST NAME = 'lisi';
  28. function sayHello($username) {
  29. echobr('hi ' . $username);
  30. }
  31. class Demo {
  32. public static $prop = 'hi';
  33. }
  34. // 当前命名空间中已有相关成员的情况
  35. /* 使用当前命名空间中的常量 */
  36. echobr(NAME);
  37. /* 使用根空间中的同名常量 */
  38. echobr(\NAME);
  39. /* result:
  40. lisi
  41. 全局
  42. */
  43. /* 使用当前命名空间的函数 */
  44. sayHello('Marry');
  45. /* 使用根空间中的同名函数 */
  46. \sayHello('Lily');
  47. /* result:
  48. hi Marry
  49. hello Lily
  50. */
  51. /* 使用当前命名空间中的类 */
  52. echobr(Demo::$prop);
  53. /* 使用根空间中的同名类 */
  54. echobr(\Demo::$prop);
  55. /* result:
  56. hi
  57. hello
  58. */
  59. }

2.3 命名空间的别名

  • 在使用其他命名空间的成员时, 为简化完全限定名称的书写, 可以为使用的其他命名空间起别名.
  • 也可以为其他命名空间中的成员起别名。当别名跟成员名称相同时,可以省略别名。
  • 使用use关键字来声明空间别名. use默认从根空间开始. 使用as关键字来指定空间/成员别名。
  • 声明语法:

    1. /* 为名称空间起别名 */
    2. use 命名空间名称 as 别名名称;
    3. /* 为名称空间的成员其别名 */
    4. /* 1. 类 */
    5. use 省略第一个\的完全限定名称类名/非完全限定名称类名 as 别名名称;
    6. /* 或者 */
    7. use 省略第一个\的完全限定名称类名/非完全限定名称类名;
    8. /* 2. 函数 */
    9. use function ... as ...;
    10. /* 或者 */
    11. use function ...;
    12. /* 3. 常量 */
    13. use constant ... as ...;
    14. /* 或者 */
    15. use constant ...;

    示例:

    1. namespace ns1\test1 {
    2. class Demo {
    3. public static $username = '张三';
    4. }
    5. class Demo1 {
    6. public staitc $username = '李四';
    7. }
    8. }
    9. namespace ns2 {
    10. // 给命名空间起别名
    11. use ns1\test1 as nt1;
    12. // 给命名空间中的类起别名
    13. use ns1\test1\Demo1 as Demo1;
    14. // 当别名跟类名相同时, 可以省略别名
    15. use ns1\test1\Demo;
    16. // 使用别名简化调用
    17. echobr('姓名: ' . nt1\Demo1::$username);
    18. /* result:
    19. 李四
    20. */
    21. // 给类起别名
    22. echobr('姓名: ' . Demo1::$username);
    23. echobr('姓名: ' . Demo::$username);
    24. /* result:
    25. 姓名: 李四
    26. 姓名: 张三
    27. */
    28. }

3. 类的自动加载

实现类自动加载的条件

  1. 命名空间必须跟类文件的绝对路径一一对应。

  2. 当前类的名称必须跟当前文件的名称完全一致。

类自动加载的目的是要省略使用 require 引入各种文件。

一般把实现类自动加载的函数用系统函数 spl_autoload_register()函数进行注册。当代码中使用到未被加载的类时,PHP 会自动调用由 spl_autoload_register()函数注册的函数去尝试加载这个类。

类自动加载示例:

  1. autoload.php: 根据实现类自动加载的条件实现的自动加载函数,并使用 spl_autoload_register()函数进行注册。
  1. // autoload.php
  2. // 封装自动加载器
  3. try {
  4. // 系统函数: spl_autoload_register(): 注册执行加载类的函数
  5. spl_autoload_register(function ($className) {
  6. // 1. 将类名中的反斜线改为当前系统中的目录分隔符
  7. $path = str_replace('\\', DIRECTORY_SEPARATOR, $className);
  8. // echobr($path);
  9. // 2. 生成真正要加载的类文件名称
  10. $file = __DIR__ . DIRECTORY_SEPARATOR . $path . '.php';
  11. // echobr($file);
  12. // 3. 加载这个文件
  13. require $file;
  14. });
  15. } catch (Exception $e) {
  16. die($e->getMessage());
  17. }
  1. Demo1.php: 待加载的类文件
  1. // Demo1.php
  2. namespace tool;
  3. class Demo1 {
  4. public static function func1() {
  5. return __METHOD__;
  6. }
  7. public static function echobr($str = '') {
  8. echo $str . '<br>';
  9. }
  10. }
  1. work.php: 需要加载类实现业务逻辑的类
  1. namespace work;
  2. // 1. 加载自动加载器文件
  3. require('autoload.php');
  4. // 2. 使用use为待加载的类起别名
  5. use tool\Demo1;
  6. // 3. 使用待加载的类
  7. Demo1::echobr(Demo1::func1());
  8. /* 成功执行需加载类的方法,即自动加载生效。
  9. result: tool\Demo1::func1 */

4. 学习心得

  • 命名空间和三种限定名称,还是很容易理解的,可以认为是程序员把各种成员按照功能进行“归档”,当要用到这些成员时,顺着归档路径去加载即可。限定名称,是指在归档路径中的某个文件,要找到另外一个成员时,相对于该文件,或相对于归档根目录增加的路径。
  • 为命名空间或成员起别名,是为了简化使用其他命名空间的成员时的调用,或防止使用不同命名空间中的相同名字的成员时引起的冲突。
  • 类自动加载,在实际编写业务逻辑时较少用到,一般应用于框架的底层实现,是为了简化一些繁琐的文件或成员引用过程(如老师上课举的例子是为了简化加载类文件的引用过程)。
Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:能完全 把命名空间理解 , 也不简单
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post