加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php的命名空间与自动加载实现技巧

发布时间:2022-06-30 14:20:25 所属栏目:PHP教程 来源:互联网
导读:这篇文章主要给大家介绍了关于php的命名空间与自动加载实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用php具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 类的自动加载 引子 当我们在php代码中加载类时,我们必须要include或者re
  这篇文章主要给大家介绍了关于php的命名空间与自动加载实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用php具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
 
  类的自动加载
 
  引子
 
  当我们在php代码中加载类时,我们必须要include或者require 某个类文件。
 
  但遇到类似的情况,例如:
 
  require "Class1.php";
  require "Class2.php";
  $boy = $_GET['sex'] = 0?true:false;
  if($boy)
  {
   $class1 = new Class1();
  }else{
   $class2 = new Class2();
  }
  假如我们需要判断一个人的性别,如果是男的就实例化class1这个类,如果是女的就实例化class2这个类。那么问题来了:这段代码,每次我只需要执行一个实例化对象,然而我必须加载这两个类文件。
 
  php对于这种问题提出了解决方案
 
  spl_auto_register()
 
  这个概念在 在php5.1中提出
 
  spl_auto_register($autoload_function = null, $throw = true, $prepend = false)
 
  函数包含3个参数
 
  ①autoload_function  这是一个函数【方法】名称,可以是字符串或者数组(调用类方法使用)。这个函数(方法)的功能就是,来把需要new 的类文件包含include(requeire)进来,这样new的时候就不会找不到文件了。其实就是封装整个项目的include和require功能。
 
  ② $throw 该参数指定当autoload_function无法注册时,spl_autoload_register()是否应引发异常。
 
  ③ 如果为true,那么spl_autoload_register()将在自动加载到文件前面,而不时在它后面。
 
  用法
 
  那么有了这个函数之后向这样写了
 
  function load($class)
  {
   require "./{$class}.php";
  }
  spl_autoload_register('load');
  if($boy)
  {
   $class1 = new Class1();
  }else{
   $class2 = new Class2();
  }
  程序执行过程如下:
 
  // 正常的流程
 
  new 一个对象-->找不到对象--> 报错
 
  // 引入spl_autoload_register 后
 
  new 一个对象-->找不到对象--> spl_autoload_register对说交给我试试--> 加载成功
 
  加载之后我们执行了load这个函数,通过class的拼接,我们完成了加载函数的过程
 
  __autoload()
 
  类的自动加载在前面我们讲 spl_autoload_register 的时候已经和大家讲过了。今天我们讲另一种
 
  __autoload() 在php7中已经不建议使用了
 
  php的__autoload函数是一个魔术函数,在这个函数出现之前,如果一个php文件里引用了100个对象,那么这个文件就需要使用include或require引进100个类文件,这将导致该php文件无比庞大。于是就有了这个 __autoload函数。
 
  __autoload函数在什么时候调用呢?当php文件中使用了new关键字实例化一个对象时,如果该类没有在本php文件中被定义,将会触发__autoload函数,此时,就可以引进定义该类的php文件,而后,就能实例化成功了。
 
  (注意:如果需要实例化的对象,在本文件中已经找到该类的定义的话,就不会触发 __autoload 函数)
 
  他和 spl_autoload_registe r的区别就在于当文件中同时出现__autoload和spl_autoload_register时,以spl_autoload_register为准
 
  命名空间
 
  我们先前讲过类的自动加载,然后我就在思索。
 
  我们用框架写代码的时候,每在另一个文件中调用其他类时
 
  我们并没有写spl_autoload_register这个方法啊?那我们时怎么实现的呢?
 
  原理
 
  原来啊,我们php在5.3时引入了命名空间的概念(这也是为什么大多数的框架不支持5.3之前的版本原因之一),命名空间大家多少还是了解的吧:不知道的去墙角面壁思过
 
  命名空间简而言之就是一种标识,它的主要目的是解决命名冲突的问题。就像在日常生活中,有很多姓名相同的人,如何区分这些人呢?那就需要加上一些额外的标识。把工作单位当成标识似乎不错,这样就不用担心 “撞名” 的尴尬了。
 
  命名空间分类
 
  完全限定命名空间
 
  限定命名空间
 
  new 成都徐大帅(); // 限定类名
 
  new 成都徐大帅(); // 完全限定类名
 
  在当前命名空间没有声明的情况下,限定类名和完全限定类名是等价的。因为如果不指定空间,则默认为全局()。
 
  namespace 美国;
 
  new 成都徐大帅(); // 美国成都徐大帅(实际结果)
 
  new 成都徐大帅(); // 成都徐大帅(实际结果)
 
  这个例子展示了在命名空间下,使用限定类名和完全限定类名的区别。(完全限定类名 = 当前命名空间 + 限定类名)
 
  /* 导入命名空间 */
  use 成都徐大帅;
  new 徐大帅(); // 成都徐大帅(实际结果)
   
  /* 设置别名 */
  use 成都徐大帅 AS CEO;
  new CEO(); // 成都徐大帅(实际结果)
   
  /* 任何情况 */
  new 成都徐大帅();// 成都徐大帅(实际结果)
  使用命名空间只是让类名有了前缀,不容易发生冲突,系统仍然不会进行自动导入。
 
  如果不引入文件,系统会在抛出 "Class Not Found" 错误之前触发 __autoload() 或者spl_autoload_register函数,并将限定类名传入作为参数。
 
  上面的例子都是基于你已经将相关文件手动引入的情况下实现的,否则系统会抛出 " Class '成都徐大帅' not found"。因为她不知道这个文件在哪里。所以在引入命名空间以后又引入了自动加载

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读