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 if 想到的些问题
Mar 22 PHP
用来给图片加水印的PHP类
Apr 09 PHP
PHP 面向对象实现代码
Nov 11 PHP
PHP开发者常犯的10个MySQL错误更正剖析
Jan 30 PHP
html静态页面调用php文件的方法
Nov 13 PHP
php防止网站被刷新的方法汇总
Dec 01 PHP
php模仿asp Application对象在线人数统计实现方法
Jan 04 PHP
PHP JSON格式的中文显示问题解决方法
Apr 09 PHP
php猴子选大王问题解决方法
May 12 PHP
PHP定时执行任务实现方法详解(Timer)
Jul 30 PHP
php-beanstalkd消息队列类实例分享
Jul 19 PHP
PHP文件管理之实现网盘及压缩包的功能操作
Sep 20 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 中执行系统外部命令
2006/10/09 PHP
php数组函数序列之array_values() 获取数组元素值的函数与方法
2011/10/30 PHP
使用 PHPMAILER 发送邮件实例应用
2012/11/07 PHP
谈谈你对Zend SAPIs(Zend SAPI Internals)的理解
2015/11/10 PHP
php获得客户端浏览器名称及版本的方法(基于ECShop函数)
2015/12/23 PHP
PHP+redis实现的购物车单例类示例
2019/02/02 PHP
Json对象替换字符串占位符实现代码
2010/11/17 Javascript
鼠标事件延时切换插件
2011/03/12 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
JS 屏蔽按键效果与改变按键效果的示例代码
2013/12/24 Javascript
JavaScript中的方法重载实例
2015/03/16 Javascript
浅谈javascript语法和定时函数
2015/05/03 Javascript
jQuery模仿单选按钮选中效果
2016/06/24 Javascript
Listloading.js移动端上拉下拉刷新组件
2016/08/04 Javascript
AngularJS实现数据列表的增加、删除和上移下移等功能实例
2016/09/05 Javascript
AngularJS框架的ng-app指令与自动加载实现方法分析
2017/01/04 Javascript
jQuery事件与动画基础详解
2017/02/23 Javascript
angularjs $http实现form表单提交示例
2017/06/09 Javascript
vue select选择框数据变化监听方法
2018/08/24 Javascript
[02:56]DOTA2英雄基础教程 巨魔战将
2013/12/10 DOTA
Python使用xlrd模块操作Excel数据导入的方法
2015/05/26 Python
详谈python在windows中的文件路径问题
2018/04/28 Python
python如何给字典的键对应的值为字典项的字典赋值
2019/07/05 Python
解决django同步数据库的时候app models表没有成功创建的问题
2019/08/09 Python
python实现逆滤波与维纳滤波示例
2020/02/26 Python
Python捕获异常堆栈信息的几种方法(小结)
2020/05/18 Python
使用jupyter notebook运行python和R的步骤
2020/08/13 Python
全球知名旅游社区法国站点:TripAdvisor法国
2016/08/03 全球购物
北京银河万佳Java面试题
2012/03/21 面试题
应用电子专业学生的自我评价
2013/10/16 职场文书
电子工程专业毕业生求职信
2014/03/14 职场文书
基层党支部公开承诺书
2014/05/29 职场文书
品德与社会教学反思
2016/02/24 职场文书
基于Redis位图实现用户签到功能
2021/05/08 Redis
pandas求平均数和中位数的方法实例
2021/08/04 Python
动漫APP软件排行榜前十名,半次元上榜,第一款由腾讯公司推出
2022/03/18 杂记