Yii框架中使用PHPExcel的方法分析


Posted in PHP onJuly 25, 2019

本文实例分析了Yii框架中使用PHPExcel的方法。分享给大家供大家参考,具体如下:

PHPExcel是一个比较好用的php读取excel文件的类库,今天遇到了在yii中如何加载PHPExcel类文件的问题,因为Yii的autoload机制是安装类名去找文件,即文件名就是相应的类名,而PHPExcel的类文件命名方式则是:dir_dir_classname.php,即文件名把文件的目录名都记录了,这种命名方式yii肯定识别不了。怎么办?

其实PHPExcel也有自己的autoload方法(PHPExcel_Autoloader::load() ),通过查看源码发现它也是通过spl_autoload_register函数注册的(在PHPExcel_Autoloader::register() 中),而我们知道PHP的autoload机制是,所有用spl_autoload_register函数注册的方法,都会在autoload时被spl_autoload_call函数执行一遍,因此我们只需要让PHPExcel的autoload方法顺利注册上就行了。

如果了解Yii的autoload机制,不清楚的可以看 附录 Yii的autoload机制 ,可以知道,只要设置Yii::$enableIncludePathfalse,第三方类库就有了执行自己的autoload方法的机会,然后使用下面两行代码就能加载PHPExcel的类了:

Yii::$enableIncludePath = false;
Yii::import('application.vendors.phpexcel.PHPExcel', 1);

import时采用了force include的方式,这是因为PHPExcel.php在被require时才会注册autoloader,如果等到new PHPExcel时才注册,其他的类例如PHPExcel_IOFactory如果在这之前使用了,就会出现找不到类的错误。

个人认为我的这种办法是比较方便且优雅的,对比网上的其他办法好很多,下面列举的办法都或多或少有点问题,例如:

1、https://3water.com/article/166128.htm,这种办法先将Yii自己的autoloader unregister了,会造成yii自己的类加载不上

2、https://3water.com/article/166132.htm,这种办法还修改了PHPExcel的autoloader,代价很大。

附录: Yii的autoload机制

Yii框架宣称自己的类加载方式很高效,是真正的“用时加载”,那究竟特别在哪里?今天研究了一下源码,发现其实是在代码级加了一层“路径缓存”。

我们知道,要实现自己的autoload方法,需要采用spl_autoload_register()函数注册一个autoload方法,Yii注册的这个方法是YiiBase::autoload(),稍后再讲解这个方法的逻辑。另外,Yii一般都用Yii::import($pathAlias, $forceInclude=false)来加载相应的类(这个方法直接调用了YiiBase::import() ),这个方法配合YiiBase::autoload()就能实现“用时加载”了。

先说import的大致逻辑:

1、检查self::$_imports数组是否存在相应的$pathAlias,如果有说明已经加载过了,直接返回类名或者目录名;否则继续第2步;

2、根据路径别名获得实际的路径名,并根据路径别名最后一部分是否是“*”可以知道要加载的路径别名是否是一个文件,如果是文件,去第3步;否则去第4步;

3、如果是$forceInclude是true,则立即require这个文件,并在$_imports数组中增加一项$alias => $className;否则在数组$classMap中缓存一项$className => $realPath

4、对于路径,会在数组$_includePaths中缓存这个路径,并且在$_imports数组中增加一项$alias => $realPath

5、结束。

因为$forceInclude默认都为false,所以import不会立即加载相应的类,等到使用时才真正加载,这是YiiBase::autoload的工作。

autoload的大致逻辑:

1、检查类名是否已缓存在$classMap或$_coreClasses数组中,如果是则直接require相应的文件路径,$_coreClasses是框架自有类的映射表;否则去第2步;

2、检测YiiBase::$enableIncludePath是否为false,如果是则去第3步,否则直接include($className . '.php')

3、遍历$includePaths数组,将目录名拼接上类名,检查是否为合法的php文件,如果是则include,然后跳出循环

4、结束。

需要注意的是,文档指出:如果要与其他类库一起使用,必须将$enableIncludePath置为false,以便在Yii::autoload()失败时,其他类库的autoload方法有机会执行。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

PHP 相关文章推荐
基于MySQL分区性能的详细介绍
May 02 PHP
PHP5中GD库生成图形验证码(有汉字)
Jul 28 PHP
php-fpm配置详解
Feb 12 PHP
PHP上传文件时自动分配路径的方法
Jan 09 PHP
SESSION存放在数据库用法实例
Aug 08 PHP
php自动载入类用法实例分析
Jun 24 PHP
php+jQuery+Ajax简单实现页面异步刷新
Aug 08 PHP
Thinkphp框架开发移动端接口(1)
Aug 18 PHP
适合PHP初学者阅读的4本经典书籍
Sep 23 PHP
php 与 nginx 的处理方式及nginx与php-fpm通信的两种方式
Sep 28 PHP
PHP观察者模式实例分析【对比JS观察者模式】
May 22 PHP
解决Laravel 不能创建 migration 的问题
Oct 09 PHP
PHP保留两位小数的几种方法
Jul 24 #PHP
Yii框架使用PHPExcel导出Excel文件的方法分析【改进版】
Jul 24 #PHP
Yii Framework框架使用PHPExcel组件的方法示例
Jul 24 #PHP
PHP+Apache实现二级域名之间共享cookie的方法
Jul 24 #PHP
PHP容器类的两种实现方式示例
Jul 24 #PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
Jul 24 #PHP
thinkphp5.1框架容器与依赖注入实例分析
Jul 23 #PHP
You might like
双料怀旧--SHARP GF515的维护、修理和简单调试
2021/03/02 无线电
PHP在线生成二维码(google api)的实现代码详解
2013/06/04 PHP
php 获取本地IP代码
2013/06/23 PHP
php.ini save_handler 修改不生效的解决办法
2014/07/22 PHP
PHP实现数组递归转义的方法
2014/08/28 PHP
PHP 实现字符串翻转(包含中文汉字)的实现代码
2017/04/01 PHP
javascript 读取xml,写入xml 实现代码
2009/07/10 Javascript
点击文章内容处弹出页面代码
2009/10/01 Javascript
JQuery Tab选项卡效果代码改进版
2010/04/01 Javascript
js Event对象的5种坐标
2011/09/12 Javascript
七个很有意思的PHP函数
2014/05/12 Javascript
深入分析JQuery和JavaScript的异同
2014/10/23 Javascript
moment.js轻松实现获取当前日期是当年的第几周
2015/02/05 Javascript
浅谈javascript中的闭包
2015/05/13 Javascript
jQuery实现ctrl+enter(回车)提交表单
2015/10/19 Javascript
js实现表单提交后不重新刷新当前页面
2016/11/30 Javascript
vue2.0中vue-cli实现全选、单选计算总价格的实例代码
2017/07/18 Javascript
基于JS实现移动端左滑删除功能
2017/07/28 Javascript
JavaScript 通过Ajax 动态加载CheckBox复选框
2017/08/31 Javascript
ES6中javascript实现函数绑定及类的事件绑定功能详解
2017/11/08 Javascript
nodejs require js文件入口,在package.json中指定默认入口main方法
2018/10/10 NodeJs
小程序实现抽奖动画
2020/04/16 Javascript
layui table动态表头 改变表格头部 重新加载表格的方法
2019/09/21 Javascript
js实现适配移动端的拖动效果
2020/01/13 Javascript
JavaScript实现表单验证功能
2020/12/09 Javascript
10种检测Python程序运行时间、CPU和内存占用的方法
2015/04/01 Python
Python tkinter模块弹出窗口及传值回到主窗口操作详解
2017/07/28 Python
Python-openCV读RGB通道图实例
2020/01/17 Python
Python中BeautifulSoup通过查找Id获取元素信息
2020/12/07 Python
Fanatics英国官网:美国体育电商
2018/11/06 全球购物
新驾驶员个人自我评价
2014/01/03 职场文书
数控技术专业毕业自荐书范文
2014/02/05 职场文书
学生评语大全
2014/04/18 职场文书
房屋授权无偿使用证明
2014/11/29 职场文书
网络管理员岗位职责
2015/02/12 职场文书
linux下导入、导出mysql数据库命令的实现方法
2021/05/26 MySQL