PHP中的use关键字及文件的加载详解


Posted in PHP onNovember 28, 2016

前言

可能在大家经常使用框架,写一个Controller或者Model的时候,写了好多use,但是并没有写文件加载的代码,就以为use可以进行文件的自动加载了。

详细介绍

其实,现在流行的php框架,都是基于MVC模式的,大量的使用了命名空间,以提高程序的灵活性。那么框架是怎么实现将use关键字所声明的类库对应的脚本文件进行加载的那?

(1):在通过use关键字进行声明类库的声明的时候,并不会进行脚本的加载,而是在脚本文件真正使用到所对应的类库的时候才会进行加载(这就是所谓延迟加载)。

(2):框架一般在初始化阶段,就声明了__autoload()函数或者是spl_autoload_register()函数(一般会在入口文件中进行声明)。在调用通过use声明的类库的时候,会自动的调用上述的函数,将调用的类库名称传递到函数中(这里的类库名称是包括命名空间的全名称)

<?php
namespace Home\Controller;
function __autoload($class_name) { 
 //echo $class_name."<br/>"; 
 require_once ("./".$class_name . ".php");  
}
use Admin\Controller\Index;
new Index; //new Index会触发__autoload()函数,返回Admin\Controller\Index到函数中
?>

(3):框架中定义的__autoload()函数或者是spl_autoload_register()函数在接收到传递过来的类库名称以后,框架会对名称进行处理,分析出类库名称所对应的文件路径,然后进行文件的加载。这里需要注意的是,不同的框架在解析类库名称,分析文件路径的方式是各不一致的,毕竟各自的目录结构是不一样的。

比如说,thinkphp:

/**
  * 类库自动加载
  * @param string $class 对象类名
  * @return void
  */
 public static function autoload($class) {
  // 检查是否存在映射
  if(isset(self::$_map[$class])) {
   include self::$_map[$class];
  }elseif(false !== strpos($class,'\\')){
   $name   = strstr($class, '\\', true);
   if(in_array($name,array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$name)){ 
    // Library目录下面的命名空间自动定位
    $path  = LIB_PATH;
   }else{
    // 检测自定义命名空间 否则就以模块为命名空间
    $namespace = C('AUTOLOAD_NAMESPACE');
    $path  = isset($namespace[$name])? dirname($namespace[$name]).'/' : APP_PATH;
   }
   $filename  = $path . str_replace('\\', '/', $class) . EXT;
   if(is_file($filename)) {
    // Win环境下面严格区分大小写
    if (IS_WIN && false === strpos(str_replace('/', '\\', realpath($filename)), $class . EXT)){
     return ;
    }
    include $filename;
   }
  }elseif (!C('APP_USE_NAMESPACE')) {
   // 自动加载的类库层
   foreach(explode(',',C('APP_AUTOLOAD_LAYER')) as $layer){
    if(substr($class,-strlen($layer))==$layer){
     if(require_cache(MODULE_PATH.$layer.'/'.$class.EXT)) {
      return ;
     }
    }   
   }
   // 根据自动加载路径设置进行尝试搜索
   foreach (explode(',',C('APP_AUTOLOAD_PATH')) as $path){
    if(import($path.'.'.$class))
     // 如果加载类成功则返回
     return ;
   }
  }
 }

这里只是举例说明use与文件的自动加载没有关系,不强调各个框架是具体怎么完成自动加载,具体的可以自己看框架代码进行研究。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

PHP 相关文章推荐
MySQL GBK→UTF-8编码转换
May 24 PHP
JS中encodeURIComponent函数用php解码的代码
Mar 01 PHP
php安全之直接用$获取值而不$_GET 字符转义
Jun 03 PHP
php自定义函数截取汉字长度
May 15 PHP
PHP_SELF,SCRIPT_NAME,REQUEST_URI区别
Dec 24 PHP
php模拟登陆的实现方法分析
Jan 09 PHP
用php来限制每个ip每天浏览页面数量的实现思路
Feb 24 PHP
PHP模板解析类实例
Jul 09 PHP
PHP count()函数讲解
Feb 03 PHP
小程序微信退款功能实现方法详解【基于thinkPHP】
May 05 PHP
php命名空间设计思想、用法与缺点分析
Jul 17 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
Feb 21 PHP
php连接微软MSSQL(sql server)完全攻略
Nov 27 #PHP
php源码之将图片转化为data/base64数据流实例详解
Nov 27 #PHP
PHP使用curl函数发送Post请求的注意事项
Nov 26 #PHP
laravel创建类似ThinPHP中functions.php的全局函数
Nov 26 #PHP
PHP数组相加操作及与array_merge的区别浅析
Nov 26 #PHP
PHP中call_user_func_array回调函数的用法示例
Nov 26 #PHP
PHP 匿名函数与注意事项详细介绍
Nov 26 #PHP
You might like
php将时间差转换为字符串提示
2011/09/07 PHP
利用yahoo汇率接口实现实时汇率转换示例 汇率转换器
2014/01/14 PHP
php实现encode64编码类实例
2015/03/24 PHP
php表单处理操作
2017/11/16 PHP
PHP实现基于状态的责任链审批模式详解
2019/05/31 PHP
基于laravel Request的所有方法详解
2019/09/29 PHP
PHP 实现重载
2021/03/09 PHP
js操作时间(年-月-日 时-分-秒 星期几)
2010/06/20 Javascript
Jquery插件之多图片异步上传
2010/10/20 Javascript
在Javascript中 声明时用&quot;var&quot;与不用&quot;var&quot;的区别
2013/04/15 Javascript
js 控制图片大小核心讲解
2013/10/09 Javascript
javascript获取所有同类checkbox选项(实例代码)
2013/11/07 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
解决ueditor jquery javascript 取值问题
2014/12/30 Javascript
Node.js开发之访问Redis数据库教程
2015/01/14 Javascript
js与jquery实时监听输入框值的oninput与onpropertychange方法
2015/02/05 Javascript
nodejs实现获取当前url地址及url各种参数值
2015/06/25 NodeJs
Webpack 实现 Node.js 代码热替换
2015/10/22 Javascript
jQuery中trigger()与bind()用法分析
2015/12/18 Javascript
JavaScript动态设置div的样式的方法
2015/12/26 Javascript
vue.js实现仿原生ios时间选择组件实例代码
2016/12/21 Javascript
详解在Vue中有条件地使用CSS类
2017/09/30 Javascript
jQuery Datatables 动态列+跨列合并实现代码
2020/01/30 jQuery
[10:18]2018DOTA2国际邀请赛寻真——Fnatic能否笑到最后?
2018/08/14 DOTA
ERLANG和PYTHON互通实现过程详解
2019/07/05 Python
pytorch中torch.max和Tensor.view函数用法详解
2020/01/03 Python
tensorflow实现测试时读取任意指定的check point的网络参数
2020/01/21 Python
keras模型保存为tensorflow的二进制模型方式
2020/05/25 Python
如何使用scrapy中的ItemLoader提取数据
2020/09/30 Python
Prometheus开发中间件Exporter过程详解
2020/11/30 Python
科颜氏印度官网:Kiehl’s印度
2021/02/20 全球购物
招聘与培训专员岗位职责
2014/01/30 职场文书
资源工程专业毕业生求职信
2014/02/27 职场文书
《穷人》教学反思
2014/04/08 职场文书
行政经理岗位职责
2015/04/15 职场文书
2015年仓库管理员工作总结
2015/04/21 职场文书