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 相关文章推荐
人大复印资料处理程序_补充篇
Oct 09 PHP
php的memcached客户端memcached
Jun 14 PHP
yii框架源码分析之创建controller代码
Jun 28 PHP
三个类概括PHP的五种设计模式
Sep 05 PHP
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
Dec 10 PHP
php自动加载autoload机制示例分享
Feb 20 PHP
php计算当前程序执行时间示例
Apr 24 PHP
33道php常见面试题及答案
Jul 06 PHP
PHP 前加at符合@的作用解析
Jul 31 PHP
php文件缓存方法总结
Mar 16 PHP
php parse_str() 函数的定义和用法
May 23 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
Sep 11 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中通过语义URL防止网站被攻击的方法分享
2011/09/08 PHP
php 获取本地IP代码
2013/06/23 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
thinkphp多表查询两表有重复相同字段的完美解决方法
2016/09/22 PHP
tp5(thinkPHP5)操作mongoDB数据库的方法
2018/01/20 PHP
javascript编程起步(第一课)
2007/01/10 Javascript
User Scripts: Video Download by User Scripts
2007/05/14 Javascript
jQuery 获取对象 基本选择与层级
2010/05/31 Javascript
自己动手开发jQuery插件教程
2011/08/25 Javascript
JavaScript数据结构与算法之栈详解
2015/03/12 Javascript
JavaScript实现图片DIV竖向滑动的方法
2015/04/25 Javascript
javascript结合canvas实现图片旋转效果
2015/05/03 Javascript
JavaScript识别网页关键字并进行描红的方法
2015/11/09 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
2016/01/27 Javascript
JS实现回到页面顶部动画效果的简单实例
2016/05/24 Javascript
canvas滤镜效果实现代码
2017/02/06 Javascript
提升页面加载速度的插件InstantClick
2017/09/12 Javascript
基于vue展开收起动画的示例代码
2018/07/05 Javascript
Vue数据绑定简析小结
2019/05/07 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
如何构建 vue-ssr 项目的方法步骤
2020/08/04 Javascript
用Python生成器实现微线程编程的教程
2015/04/13 Python
Python连接mysql数据库的正确姿势
2016/02/03 Python
python开发之list操作实例分析
2016/02/22 Python
零基础使用Python读写处理Excel表格的方法
2019/05/02 Python
在pandas中遍历DataFrame行的实现方法
2019/10/23 Python
django模型类中,null=True,blank=True用法说明
2020/07/09 Python
使用CSS3编写灰阶滤镜来制作黑白照片效果的方法
2016/05/09 HTML / CSS
HTML5+CSS3实现拖放(Drag and Drop)示例
2014/07/07 HTML / CSS
Bose法国官网:购买耳机、扬声器、家庭影院、专业音响
2017/12/21 全球购物
汽车专业毕业生推荐信
2013/11/12 职场文书
2014年教育教学工作总结
2014/11/13 职场文书
2015年英语教学工作总结
2015/05/25 职场文书
卫生主题班会
2015/08/14 职场文书
2016幼儿园新学期寄语
2015/12/03 职场文书
俄罗斯十大城市人口排名,第三首都仅排第六,第二是北方首都
2022/03/20 杂记