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 连接mysql连接被重置的解决方法
Feb 15 PHP
php空间不支持socket但支持curl时recaptcha的用法
Nov 07 PHP
ThinkPHP3.0略缩图不能保存到子目录的解决方法
Sep 30 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
Jun 13 PHP
解析Win7 XAMPP apache无法启动的问题
Jun 26 PHP
curl不使用文件存取cookie php使用curl获取cookie示例
Jan 26 PHP
PHP 抽象方法与抽象类abstract关键字介绍及应用
Oct 16 PHP
使用PHP Socket 编程模拟Http post和get请求
Nov 25 PHP
PHP实现的线索二叉树及二叉树遍历方法详解
Apr 25 PHP
php下载文件超时时间的设置方法
Oct 06 PHP
php获取ip及网址的简单方法(必看)
Apr 01 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
重新封装zend_soap实现http连接安全认证的php代码
2011/01/12 PHP
PHP将HTML转换成文本的实现代码
2015/01/21 PHP
jquery的冒泡事件的阻止与允许(三种实现方法)
2013/02/01 Javascript
js验证整数加保留小数点的简单实例
2013/12/02 Javascript
jquery图片滚动放大代码分享(2)
2015/08/28 Javascript
JS实现的左侧竖向滑动菜单效果代码
2015/10/19 Javascript
JavaScript与jQuery实现的闪烁输入效果
2016/02/18 Javascript
页面get请求 中文参数方法乱码问题的快速解决方法
2016/05/31 Javascript
Node.js实现兼容IE789的文件上传进度条
2016/09/02 Javascript
JS 根据子网掩码,网关计算出所有IP地址范围示例
2020/04/23 Javascript
关于验证码在IE中不刷新的快速解决方法
2016/09/23 Javascript
require、backbone等重构手机图片查看器
2016/11/17 Javascript
ES6中Math对象的部分扩展
2017/02/20 Javascript
JS对象序列化成json数据和json数据转化为JS对象的代码
2017/08/23 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
2018/09/04 Javascript
Vux+Axios拦截器增加loading的问题及实现方法
2018/11/08 Javascript
js定义类的方法示例【ES5与ES6】
2019/07/30 Javascript
微信小程序官方动态自定义底部tabBar的例子
2019/09/04 Javascript
Python三元运算实现方法
2015/01/12 Python
python检测某个变量是否有定义的方法
2015/05/20 Python
Python-嵌套列表list的全面解析
2016/06/08 Python
Windows系统Python直接调用C++ DLL的方法
2019/08/01 Python
对Django url的几种使用方式详解
2019/08/06 Python
python numpy库linspace相同间隔采样的实现
2020/02/25 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
Python requests HTTP验证登录实现流程
2020/11/05 Python
python二维图制作的实例代码
2020/12/03 Python
Python爬虫+Tkinter制作一个翻译软件的示例
2021/02/20 Python
购买限量版收藏品、珠宝和礼品:Bradford Exchange
2016/09/23 全球购物
会计电算化个人求职信范文
2014/01/24 职场文书
建议书的格式
2014/05/12 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
专题民主生活会对照检查材料思想汇报
2014/09/29 职场文书
坎儿井导游词
2015/02/09 职场文书
演讲比赛通讯稿
2015/07/18 职场文书
HttpClient实现表单提交上传文件
2022/08/14 Java/Android