博客列表 >细说命名空间

细说命名空间

溪边小树
溪边小树原创
2020年05月16日 20:29:07727浏览

声明命名空间

  1. <?php
  2. // 命名空间
  3. // 1. 安徽省合肥市小树小站
  4. // 2. 湖南省长沙市小树小站
  5. // 3. 浙江省宁波市小树小站
  6. // php5.3-: 全局成员默认定义在全局空间中
  7. // 全局成员: 类, 接口, 函数, 常量(访问不受作用域限制)
  8. // anhui_hefei_changjianglu, jiangshu_nanjin_changjianglu
  9. // app_controller_User.php
  10. // 引入组件类:app_controller_User.php
  11. // 声明命名空间: namespace
  12. namespace 安徽省\合肥市;
  13. echo __NAMESPACE__ . '<br>';
  14. class Demo
  15. {
  16. const ROAD_NAME = '小树小站(HF)';
  17. }
  18. // ::class: 获取类的完整名称(带上空间)
  19. echo Demo::class, '<br>';
  20. // 1. 从根空间/全局空间开始: 绝对路径, C:\\a\b\c\d.txt
  21. // 根空间/全局空间:用反斜线表示:\
  22. echo \安徽省\合肥市\Demo::ROAD_NAME . '<br>';
  23. // 2. 从当前空间开始, 可以省略当前空间名称: 非限定名称
  24. echo Demo::ROAD_NAME . '<br>';
  25. echo '<hr>';
  26. namespace 湖南省\长沙市;
  27. echo __NAMESPACE__ . '<br>';
  28. class Demo
  29. {
  30. const ROAD_NAME = '小树小站';
  31. }
  32. // ::class: 获取类的完整名称(带上空间)
  33. echo Demo::class, '<br>';
  34. echo __NAMESPACE__ . Demo::ROAD_NAME , '<br>';
  35. // 访问另一个空间中的成员,必须使用"完全限定名称":类似于绝对路径
  36. echo \安徽省\合肥市\Demo::ROAD_NAME . '<br>';
  37. echo '<hr>';
  38. namespace 浙江省\宁波市;
  39. echo __NAMESPACE__ . '<br>';
  40. class Demo
  41. {
  42. const ROAD_NAME = '小树小站';
  43. }
  44. // ::class: 获取类的完整名称(带上空间)
  45. echo Demo::class, '<hr>';
  46. namespace 江苏省;
  47. // namespace 江苏省\南京市 中的类常量
  48. // 1. 完全限定名称
  49. echo \江苏省\南京市\Demo::ROAD_NAME . '<br>';
  50. // 2. 如果在当前空间下访问, 那么当前的空间名称可以省略
  51. // 在类名前出现了空间,但不是从根空开始,这叫:"限定名称"
  52. echo 南京市\Demo::ROAD_NAME . '<br>';
  53. namespace 江苏省\南京市;
  54. class Demo
  55. {
  56. const ROAD_NAME = '小树小站';
  57. }
  58. // 1. 非限定名称
  59. // 成员前面不能有任何的命名空间,不能有"\", 理解成文件当前路径
  60. // echo Demo::ROAD_NAME;
  61. // 2. 限定名称
  62. // 成员名称前面至少要一个命名空间, 至少要有一个反斜线\, 且不能在首位, 理解成:相对路径
  63. // echo 南京市\Demo::ROAD_NAME;
  64. // 3. 完全限定名称
  65. // 总是从根空间开始,第一个字符一定是反斜线,根空间, 理解成绝对路径
  66. // echo \江苏省\南京市\Demo::ROAD_NAME

创建命名空间及别名

  1. <?php
  2. // 全局成员有哪些?
  3. // 全局成员四大家族: 类, 接口, 函数, 常量
  4. // 1. 接口
  5. interface iTest
  6. {
  7. }
  8. // 2. 类
  9. class Demo
  10. {
  11. }
  12. // 3. 函数
  13. function my_func()
  14. {
  15. }
  16. // 4. 常量
  17. const APP_NAME = '进销存';
  18. -------------------------------
  19. // 创建命名空间
  20. // 在同一个脚本中, 创建多个命名空间
  21. namespace one;
  22. // 1. 接口
  23. interface iTest
  24. {
  25. }
  26. // 2. 类
  27. class Demo
  28. {
  29. }
  30. // 3. 函数
  31. function my_func()
  32. {
  33. }
  34. // 4. 常量
  35. const APP_NAME = '多用户进销存';
  36. // 第二个空间
  37. namespace two;
  38. // 1. 接口
  39. interface iTest
  40. {
  41. }
  42. // 2. 类
  43. class Demo
  44. {
  45. }
  46. // 3. 函数
  47. function my_func()
  48. {
  49. }
  50. // 4. 常量
  51. const APP_NAME = '进销存';
  52. echo __NAMESPACE__;
  53. echo APP_NAME , '<br>';
  54. // 完全限定名称
  55. echo \one\APP_NAME, '<br>';
  56. // 这种语法, 只能创建命名空间, 不能创建匿名空间
  57. // 匿名空间就是默认空间就是根空间/全局空间
  58. // namespace \;
  59. -------------------------
  60. // 创建命名空间
  61. // 在同一个脚本中, 创建多个命名空间, 包括全局空间
  62. namespace one
  63. {
  64. // 1. 接口
  65. interface iTest
  66. {
  67. }
  68. // 2. 类
  69. class Demo
  70. {
  71. }
  72. // 3. 函数
  73. function my_func()
  74. {
  75. }
  76. // 4. 常量
  77. const APP_NAME = '多用户进销存';
  78. }
  79. // 第二个空间
  80. namespace two
  81. {
  82. // 1. 接口
  83. interface iTest
  84. {
  85. }
  86. // 2. 类
  87. class Demo
  88. {
  89. }
  90. // 3. 函数
  91. function my_func()
  92. {
  93. }
  94. // 4. 常量
  95. const APP_NAME = '进销存';
  96. }
  97. // 声明一个全局,匿名的
  98. namespace
  99. {
  100. // 完全限定名称
  101. echo one\APP_NAME;
  102. }
  103. -----------------------------------------------------
  104. // namespace 写在第一行
  105. namespace ns1
  106. {
  107. // Test:非限定名称,此时会自动将当前空间名称加上去
  108. // echo Test::App;
  109. // echo \ns1\Test::App;
  110. // 类
  111. echo \Test::APP, '<br>';
  112. echo \implode('---', [1,2,3,4]), '<br>';
  113. // 当前空间下面没有, 到全局找
  114. function implode ($str, $arr)
  115. {
  116. return sprintf('<pre>%s%s</pre>',$str,print_r($arr, true));
  117. }
  118. const E_ALL = 'Hello';
  119. echo \E_ALL;
  120. }
  121. // 全局空间
  122. namespace
  123. {
  124. class Test
  125. {
  126. const APP = '在线商城';
  127. }
  128. }
  129. -------------------------------------------------
  130. // 命名空间的别名
  131. namespace ns1;
  132. class T1
  133. {
  134. // ...
  135. }
  136. echo \ns2\T2::index(), '<br>';
  137. echo \ns2\T3::cate(), '<hr>';
  138. namespace ns2;
  139. class T2
  140. {
  141. public static function index()
  142. {
  143. return '首页';
  144. }
  145. }
  146. class T3
  147. {
  148. public static function cate()
  149. {
  150. return '频道页1111';
  151. }
  152. }
  153. namespace ns3;
  154. // use 用来声明空间别名,use 默认就是从根空开始
  155. // 1. 空间级的别名
  156. // 给外部的空间起了一个别名, ns2 ===> s
  157. use ns2 as s;
  158. echo s\T2::index(), '<br>';
  159. echo s\T3::cate(), '<hr>';
  160. // 2. 类级的别名
  161. // 给外部空间中的类,起一个别名
  162. // use ns2\T2 as T2;
  163. // use ns2\T3 as T3;
  164. // echo T2::index(), '<br>';
  165. // echo T3::cate(), '<hr>';
  166. // 类别名与原始类名相同, 此时可以省略类别名
  167. // use ns2\T2;
  168. // 因为当前类中与有一个与之冲突的类名T2
  169. use ns2\T2 as T;
  170. use ns2\T3;
  171. // use function ....;
  172. // use constant .... ;
  173. echo T2::index(), '<br>';
  174. echo T::index(), '<br>';
  175. echo T3::cate(), '<hr>';
  176. class T2
  177. {
  178. public static function index()
  179. {
  180. return '首页NS3-T2';
  181. }
  182. }

自动加载

  1. <?php
  2. require 'inc/lib/Demo1.php';
  3. require 'inc/lib/Demo2.php';
  4. require 'inc/lib/Demo3.php';
  5. use inc\lib\Demo1;
  6. use inc\lib\Demo2;
  7. use inc\lib\Demo3;
  8. echo Demo1::class, '<br>';
  9. echo Demo2::class, '<br>';
  10. echo Demo3::class, '<br>';
  11. -------------------------------------------------
  12. // 自动加载的预备知识
  13. // str_replace($search, $subject, $str);
  14. // DIRECTORY_SEPARATOR : 目录分隔符, 随系统自动变化, linux,windows中有所区别
  15. echo __DIR__; // 返回当前脚本所在的路径
  16. echo '<hr>';
  17. $className = 'inc\lib\Demo1';
  18. //1. 应该将类名中的命名空间的分隔符转为目录分隔符
  19. $path = str_replace('\\', DIRECTORY_SEPARATOR, $className);
  20. echo $path, '<hr>';
  21. // 2. 生成真正要加载的类文件名称
  22. $file = __DIR__ . DIRECTORY_SEPARATOR . $path . '.php';
  23. echo $file, '<br>';
  24. // 3. 加载这个文件
  25. require $file;
  26. use inc\lib\Demo1;
  27. echo Demo1::say();
  28. -----------------------------------------
  29. **// 如果想实现自动加载,需要满足二个条件
  30. **// 1. 命名空间必须和类文件所在的绝对路径一一对应
  31. **// 2. 当前类名称与当前的类文件的名称完全一致******
  32. namespace inc\lib;
  33. class Demo1
  34. {
  35. public static function say()
  36. {
  37. return 'Hello PHP中文网';
  38. }
  39. }
  40. ------------------------------------
  41. namespace inc\lib;
  42. class Demo2
  43. {
  44. }
  45. ------------------------------------
  46. namespace inc\lib;
  47. class Demo3
  48. {
  49. }
  50. -------------------------------------
  51. try {
  52. spl_autoload_register(function($className){
  53. //1. 应该将类名中的命名空间的分隔符转为目录分隔符
  54. $path = str_replace('\\', DIRECTORY_SEPARATOR, $className);
  55. // 2. 生成真正要加载的类文件名称
  56. $file = __DIR__ . DIRECTORY_SEPARATOR . $path . '.php';
  57. // 3. 加载这个文件
  58. require $file;
  59. });
  60. } catch (Exception $e) {
  61. die($e->getMessage());
  62. }
  63. --------------------------------------------
  64. // 封装自动加载器
  65. require 'autoload.php';
  66. use inc\lib\Demo1;
  67. use inc\lib\Demo2;
  68. use inc\lib\Demo3;
  69. echo Demo1::say();
  70. echo Demo2::class, '<br>';
  71. echo Demo3::class;

课程学习小结

本次课程老师着重讲解了命名空间的声明、创建、别名及具体的应用场景,尤其是通过实际案例解释说明了自动加载器的封装方法及步骤,让我们从底层原理上去理解命名空间相关内容的重要性,也有助于对后续相关知识的深入学习,收获很大。

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