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 相关文章推荐
计算2000年01月01日起到指定日的天数
Oct 09 PHP
PHP中通过ADO调用Access数据库的方法测试不通过
Dec 31 PHP
php实现网站插件机制的方法
Nov 10 PHP
php下通过curl抓取yahoo boss 搜索结果的实现代码
Jun 10 PHP
APACHE的AcceptPathInfo指令使用介绍
Jan 18 PHP
用php制作简单分页(从数据库读取记录)的方法详解
May 04 PHP
解析PHP高效率写法(详解原因)
Jun 20 PHP
解析php取整的几种方式
Jun 25 PHP
php对二维数组按指定键值key排序示例代码
Nov 26 PHP
浅析PHP编程中10个最常见的错误
Aug 08 PHP
Yii2框架实现注册和登录教程
Sep 30 PHP
PHP命名空间namespace及use的简单用法分析
Aug 03 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
Banner程序
2006/10/09 PHP
php四种基础算法代码实例
2013/10/29 PHP
destoon出现验证码不显示时的紧急处理方法
2014/08/22 PHP
变量在 PHP7 内部的实现(二)
2015/12/21 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
2017/09/16 PHP
PHP PDOStatement::execute讲解
2019/01/31 PHP
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
不用构造函数(Constructor)new关键字也能实现JavaScript的面向对象
2013/01/11 Javascript
自己使用jquery写的一个无缝滚动的插件
2014/04/30 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
轻松学习jQuery插件EasyUI EasyUI创建CRUD应用
2015/11/30 Javascript
JavaScript 弹出子窗体并返回结果到父窗体的实现代码
2016/05/28 Javascript
JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
2016/08/11 Javascript
Vue.js实现一个todo-list的上移下移删除功能
2017/06/26 Javascript
Nodejs 和 Electron ubuntu下快速安装过程
2018/05/04 NodeJs
浅谈Vue static 静态资源路径 和 style问题
2020/11/07 Javascript
vue 项目@change多个参数传值多个事件的操作
2021/01/29 Vue.js
[01:38]DOTA2辉夜杯 欢乐的观众现场采访
2015/12/26 DOTA
python实现指定字符串补全空格的方法
2015/04/30 Python
Python匹配中文的正则表达式
2016/05/11 Python
windows下python之mysqldb模块安装方法
2017/09/07 Python
python模仿网页版微信发送消息功能
2018/02/24 Python
Python嵌套列表转一维的方法(压平嵌套列表)
2018/07/03 Python
Tensorflow 同时载入多个模型的实例讲解
2018/07/27 Python
python射线法判断检测点是否位于区域外接矩形内
2019/06/28 Python
windows中安装Python3.8.0的实现方法
2019/11/19 Python
Python实现仿射密码的思路详解
2020/04/23 Python
在python中list作函数形参,防止被实参修改的实现方法
2020/06/05 Python
python实现canny边缘检测
2020/09/14 Python
python软件测试Jmeter性能测试JDBC Request(结合数据库)的使用详解
2021/01/26 Python
计算机本科生自荐信
2013/10/15 职场文书
声乐专业大学生职业生涯规划书:理想的未来需要自己去打造
2014/09/20 职场文书
公司股东出资证明书
2014/11/01 职场文书
后勤个人工作总结
2015/02/28 职场文书
《家庭教育》读后感3篇
2019/12/18 职场文书
mysql自增长id用完了该怎么办
2022/02/12 MySQL