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 相关文章推荐
php&java(一)
Oct 09 PHP
php 读取文件乱码问题
Feb 20 PHP
PHP获取文件绝对路径的代码(上一级目录)
May 29 PHP
PHP中使用数组实现堆栈数据结构的代码
Feb 05 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
Jul 16 PHP
php项目中百度 UEditor 简单安装调试和调用
Jul 15 PHP
PHP Yaf框架的简单安装使用教程(推荐)
Jun 08 PHP
PHP实现网站访问量计数器
Oct 27 PHP
thinkPHP中钩子的使用方法实例分析
Nov 16 PHP
PHP设计模式之工厂方法设计模式实例分析
Apr 25 PHP
PHP中number_format()函数的用法讲解
Apr 08 PHP
thinkphp3.2同时连接两个数据库的简单方法
Aug 13 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
全局记录程序片段的运行时间 正确找到程序逻辑耗时多的断点
2011/01/06 PHP
php 不使用js实现页面跳转
2014/02/11 PHP
javascript js cookie的存储,获取和删除
2007/12/29 Javascript
关于Aptana Studio生成自动备份文件的解决办法
2009/12/23 Javascript
JavaScript类和继承 this属性使用说明
2010/09/03 Javascript
javascript event 事件解析
2011/01/31 Javascript
Asp.Net alert弹出提示信息的几种方法总结
2014/01/29 Javascript
js计算任意值之间随机数的方法
2015/01/16 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
2015/09/01 Javascript
jquery特效 点击展示与隐藏全文
2015/12/09 Javascript
深入浅析JavaScript系列(13):This? Yes,this!
2016/01/05 Javascript
微信jssdk在iframe页面失效问题的解决措施
2016/03/03 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
2017/07/22 jQuery
Angular5.1新功能分享
2017/12/21 Javascript
webpack搭建vue 项目的步骤
2017/12/27 Javascript
vscode下的vue文件格式化问题
2018/11/28 Javascript
关于Vue Router中路由守卫的应用及在全局导航守卫中检查元字段的方法
2018/12/09 Javascript
vue滚动tab跟随切换效果
2020/06/29 Javascript
JavaScript生成随机验证码代码实例
2019/09/28 Javascript
vuex(vue状态管理)的特殊应用案例分享
2020/03/03 Javascript
Postman动态获取返回值过程详解
2020/06/30 Javascript
vue页面引入three.js实现3d动画场景操作
2020/08/10 Javascript
python中pandas.DataFrame排除特定行方法示例
2017/03/12 Python
Python中序列的修改、散列与切片详解
2017/08/27 Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
2019/07/08 Python
flask/django 动态查询表结构相同表名不同数据的Model实现方法
2019/08/29 Python
Python截图并保存的具体实例
2021/01/14 Python
美国网上购买眼镜:Eyeconic
2017/07/29 全球购物
Python面试题集
2012/03/08 面试题
学校督导评估方案
2014/06/10 职场文书
工作保证书
2015/01/17 职场文书
客户答谢会致辞
2015/01/20 职场文书
邀请函模板
2015/02/02 职场文书
MongoDB使用profile分析慢查询的步骤
2021/04/30 MongoDB
Pycharm连接远程服务器并远程调试的全过程
2021/06/24 Python
Java字符串逆序方法详情
2022/03/21 Java/Android