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 相关文章推荐
PHP实现网上点歌(二)
Oct 09 PHP
利用PHP制作简单的内容采集器的代码
Nov 28 PHP
PHP EOT定界符的使用详解
Sep 30 PHP
PHP实现邮件群发的源码
Jun 18 PHP
PHP中__FILE__、dirname与basename用法实例分析
Dec 01 PHP
深入浅析PHP7.0新特征(五大新特征)
Oct 29 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
Nov 07 PHP
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
Dec 14 PHP
[原创]PHP实现生成vcf vcard文件功能类定义与使用方法详解【附demo源码下载】
Sep 02 PHP
php 可变函数使用小结
Jun 12 PHP
PHP实现的XXTEA加密解密算法示例
Aug 28 PHP
深入分析PHP设计模式
Jun 15 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
基于qmail的完整WEBMAIL解决方案安装详解
2006/10/09 PHP
php iconv() : Detected an illegal character in input string
2010/12/05 PHP
js 匿名调用实现代码
2009/06/19 Javascript
javascript动态添加表格数据行(ASP后台数据库保存例子)
2010/05/08 Javascript
JavaScript在多浏览器下for循环的使用方法
2012/11/07 Javascript
jquery对dom的操作常用方法整理
2013/06/25 Javascript
IE6已终止操作问题的2种情况及解决
2014/04/23 Javascript
实现图片预加载的三大方法及优缺点分析
2014/11/19 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入
2016/01/19 Javascript
JavaScript中const、var和let区别浅析
2016/10/11 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
vue2.x select2 指令封装详解
2017/10/12 Javascript
vue单页应用加百度统计代码(亲测有效)
2018/01/31 Javascript
webstorm中配置nodejs环境及npm的实例
2018/05/15 NodeJs
node错误处理与日志记录的实现
2018/12/24 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
react 原生实现头像滚动播放的示例
2020/04/21 Javascript
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
零基础学Python(一)Python环境安装
2014/08/20 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
Python爬虫之正则表达式基本用法实例分析
2018/08/08 Python
python tornado微信开发入门代码
2018/08/24 Python
Python拆分大型CSV文件代码实例
2019/10/07 Python
浅谈pytorch 模型 .pt, .pth, .pkl的区别及模型保存方式
2020/05/25 Python
HTML5实现自带进度条和滑块滑杆效果
2018/04/17 HTML / CSS
美国家具网站:Cymax
2016/09/17 全球购物
HelloFresh澳大利亚:订购你的美味食品盒、健康餐食
2018/03/28 全球购物
Wolford法国官网:奥地利奢侈内衣品牌
2020/08/11 全球购物
汽车专业毕业生推荐信
2013/11/12 职场文书
《寓言两则》教学反思
2014/02/27 职场文书
2015中学教师个人工作总结
2015/07/22 职场文书
保险公司增员口号
2015/12/25 职场文书
党风廉政建设心得体会
2019/05/21 职场文书
python3.9之你应该知道的新特性详解
2021/04/29 Python
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL