博客列表 >PHP - 命名空间与自动加载

PHP - 命名空间与自动加载

晴天
晴天原创
2020年05月15日 17:41:43564浏览

在不同的命名空间下面可以创建名称相同的函数 接口 变量

  1. <?php
  2. namespace ns1;
  3. function demo(){
  4. echo 'hello,ns1';
  5. }
  6. namespace ns2;
  7. function demo(){
  8. echo 'hello,ns2';
  9. }
  10. //若要访问当前空间下的demo
  11. //直接访问 这叫非限定名称
  12. demo(); //输出 hello,ns2
  13. //若要访问ns1的demo 这叫完全限定名称
  14. \ns1\demo(); //输出hello,ns1
  15. //若要访问子空间的demo 这叫限定名称
  16. z1\demo(); //输出 hello,ns2,z1
  17. //ns2 创建子空间
  18. namespace ns2\z1;
  19. function demo(){
  20. echo 'hello,ns2,z1';
  21. }
  • 但是这种语法不能创建匿名空间 ,匿名空间就是默认空间 也叫根空间/全局空间

使用{} 可以创建匿名空间

  1. <?php
  2. namespace ns1 {
  3. function demo()
  4. {
  5. echo 'hello,ns1';
  6. }
  7. }
  8. namespace ns2 {
  9. function demo()
  10. {
  11. echo 'hello,ns2';
  12. }
  13. }
  14. namespace ns2\z1 {
  15. function demo()
  16. {
  17. echo 'hello,ns2,z1';
  18. }
  19. }
  20. //创建 全局空间
  21. namespace {
  22. function demo()
  23. {
  24. echo '我是全局空间';
  25. }
  26. // 调用全局空间demo
  27. demo(); //输出 我是全局空间
  28. echo '<hr>';
  29. // 调用ns1 demo
  30. \ns1\demo(); //hello,ns1
  31. // 调用ns2 demo
  32. \ns2\demo(); // hello,ns2
  33. // 调用ns2下面的子空间 demo
  34. \ns2\z1\demo(); //hello,ns2,z1
  35. }

给命名空间起别名

  1. <?php
  2. namespace ns1 {
  3. function demo()
  4. {
  5. echo 'hello,ns1';
  6. }
  7. }
  8. namespace ns2 {
  9. function demo()
  10. {
  11. echo 'hello,ns2';
  12. }
  13. }
  14. namespace ns2\z1 {
  15. function demo()
  16. {
  17. echo 'hello,ns2,z1';
  18. }
  19. // 创建类
  20. class Demo{
  21. // 创建方法
  22. public static function index(){
  23. echo '我是ns2\z1里的index类';
  24. }
  25. }
  26. }
  27. //创建 全局空间
  28. namespace {
  29. function demo()
  30. {
  31. echo '我是全局空间';
  32. }
  33. //如果我要调用ns2\z1\demo()
  34. // 原始方法
  35. \ns2\z1\demo(); // hello,ns2,z1
  36. // 给他起别名
  37. use ns2\z1 as z;
  38. z\demo(); //输出 hello,ns2,z1 将命名空间简化
  39. // 调用类
  40. // 原始方法
  41. \ns2\z1\Demo::index(); //我是ns2\z1里的index类s
  42. // 给他起别名
  43. use ns2\z1\Demo as k;
  44. k::index(); //我是ns2\z1里的index类
  45. // 如果类名与别名相同 可以省略类别名
  46. // 比如
  47. // use ns2\z1\Demo as Demo;
  48. // 可以直接 省略
  49. use ns2\z1\Demo;
  50. Demo::index(); // 输出相同 我是ns2\z1里的index类
  51. }

自动加载

在一个脚本中 可能会加载几十上百个文件,那么挨个require 就不现实了 所以考虑封装一个自动加载器

  • 如果想要实现自动加载,需要满足两个条件
    1. 命名空间必须与类文件所在的绝对路径一一对应

      比如 你的文件放到 inc/lib 文件夹中 那么命名空间必须是 namespace inc\lib;

    1. 当前类名称必须与当前类文件的名称完全一致

      比如 类名称为 class Demo1 那么该文件的名字 也要是 demo1.php

1. 创建类文件

  • demo1.php demo2.php demo3.php 保存到 inc文件夹下面的lib文件夹中

  • 对应的文件中 类名必须与文件名一致

2. 封装自动加载器

autoload.php

  1. <?php
  2. //自动加载预备知识
  3. //str_replace() 替换字符串中指定内容
  4. //DIRECTORY_SEPARATOR 目录分隔符 跟随系统自动改变 windows / liunx \
  5. //__DIR__ 当前所在路径
  6. //spl_autoload_register() 注册一个自动加载器
  7. try {
  8. spl_autoload_register(function ($className) {
  9. // 1.命名空间中的分隔符转为目录分隔符
  10. $path = str_replace('\\', DIRECTORY_SEPARATOR, $className);
  11. // 2.生成真正要加载的类文件
  12. $file = __DIR__ . DIRECTORY_SEPARATOR . $path . '.php';
  13. // 加载这个文件
  14. require $file;
  15. });
  16. } catch (Exception $e) {
  17. die($e->getMessage());
  18. }

3. 调用

  1. <?php
  2. //调用自动加载器
  3. require 'autoload.php';
  4. //调用 类
  5. use inc\lib\Demo1;
  6. use inc\lib\Demo2;
  7. use inc\lib\Demo3;
  8. //输出类的名字
  9. echo Demo1::class , '<hr>'; // 输出 inc\lib\Demo1
  10. echo Demo2::class , '<hr>';// 输出 inc\lib\Demo2
  11. echo Demo3::class , '<hr>';// 输出 inc\lib\Demo3

总结

学命名空间那几天有些私事给耽搁了,一直记得老师说命名空间学不会影响后面的框架,正好今天有时间,本来以为这个重要的东西应该比类难,还是有些抵触情绪不想学,可是不学又不行,只能硬着头皮上了,随着课程的深入 其实一点都不难,重在理解,就是将n个文件 写到一个脚本中,并且不会因为重名报错。

关于类的自动加载 感觉好神奇! 几行代码解决了写n个require的烦恼,只要加载这个文件就可以了,就像是类中的属性拦截器,当你加载这个命名空间中的方法时,不用require,自动加载器会自动调用并完成require功能!

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议