在PHP中检查PHP文件是否有语法错误的方法


Posted in PHP onDecember 23, 2009

之前在当当的时候的一个项目中用到了一个简单的模板引擎,其实也是借鉴discuz来做的模板引擎,很简单,它所作的事情就是把一些自定义的标签编译成php代码。已经说了很简单了,所以编译的时候也名优进行模板语法的检查,那么在开发过程中就会出现编译出来的php文件有语法问题,有语法问题没有关系,我修改重新编译一下就好了。首先不能在每次请求的时候都把php模板重新编译一下,会严重影响性能,折中的处理时在每个编译好的php文件末尾检查一下该模板文件是否已经修改过,根据设定的更新频率,如果又需要则重新编译模板文件,现在的问题是编译出来的php文件自己有语法错误,根本执行不到模板检查那一步,所以即使修改了模板文件中的问题也不会重新编译。 所以我想寻找一种简单的方法来检查生成的php文件是否合法。不合法就重新编译,这样开发过程中就不用出现错误就得手动删除缓存文件了。

在网上找了一下。刚开始以为 token_get_all()函数能处理语法错误的问题,结果发现,它只是做简单的词法分析。没有办法。后来到论坛上去问了一下

http://groups.google.com/group/professional-php/browse_thread/thread/b8581f6b07b10ff0/2601a63c406bb1c1?lnk=gst&q=reeze#2601a63c406bb1c1

有人告诉我有这样一个函数 php_check_syntax() http://www.php.net/manual/en/function.php-check-syntax.php 我想问题就这么坚决了。。我真应该RTF(Read The Fuck Mannual). 仔细一看。这个函数已近被弃用了:
Note: For technical reasons, this function is deprecated and removed from PHP. Instead, use php -l somefile.php from the commandline.

这个technical reason 到底是什么呢? 先不管了,以后再慢慢研究,反正不能使用这个方法就对了。
他们的建议是使用命令行$php -l filename.php 来检查语法。
Gary Every给了我一个代码片段参考:

在命令行下检查问题也不大。如果我要放在在线应用呢? 这就涉及到可移植性的问题了。首先是操作系统,然后就是环境变量。这样的话就会依赖于服务器端的配置。在http://www.php.net/manual/en/function.php-check-syntax.php 上有人贴出了自己的php_check_syntax()函数实现。
有的采用的就是上面的命令行的方法。
后面有提到使用eval的方法来验证。eval方法会执行传入的代码, 如果代码有语法错误则会抛出parser error, 可以使用'@'错误抑制符去掉错误信息,eval和echo一样并不是函数,不能使用变量函数的方法调用比如:
$func = ‘eval'
$func()这样的调用就是无效的。它会提示没有eval函数,如果你自己定义这么一个函数也是有问题的。因为eval是一个关键字。
eval调用和include差不多,如果被包含文件中没有明确return就返回null。如果直接eval我们需要检查的文件会造成被检查的文件内代码被执行,这可不是我们想要的,我们只需要检查一下这个文件的语法是否正确。 我们可以在要检查的文件之前添加return 语句,让代码提前跳出,那么后面的代码就不会执行了。好的,就这么干。代码如下:
checker.php

<?php if(!function_exists('php_check_syntax')) { 
function php_check_syntax($file_name, &$error_message = null) { 
$file_content = file_get_contents($file_name); 
$check_code = "return true; ?>"; 
$file_content = $check_code . $file_content . "<?php "; 
if(!@eval($file_content)) { 
$error_message = "file: " . realpath($file_name) . " have syntax error"; 
return false; 
} 
return true; 
} 
} 
if(!php_check_syntax("file.php", $msg)) { 
echo $msg; 
} 
else { 
echo "Woohoo, OK!"; 
}

file.php
<?php 
foreach:: a => b 
?>

因为Parse error 是没法被 set_error_handler处理函数处理的。这个异常没办法catch到。所以才使用了@来抑制错误。这带来的问题就是我们无法得到详细的错误信息。 不过目前我需要的功能也只是检查语法是否正确。不正确的话重新编译模板文件,就这么简单,至于语法错误,在显示网页的时候自然会看得到。
最好的办法就是这个被遗弃的php_check_syntax这个方法回到php中。下次再研究下他们是出于什么原因把这个函数去掉的。
////////思维很混乱,写的每一点条理性,谁让我语文那么烂涅。
PHP 相关文章推荐
用PHP和ACCESS写聊天室(九)
Oct 09 PHP
用DBSQL类加快开发MySQL数据库程序的速度
Oct 09 PHP
dedecms系统常用术语汇总
Apr 03 PHP
解析使用ThinkPHP应该掌握的调试手段
Jun 20 PHP
PHP中的多行字符串传递给JavaScript的两种方法
Jun 19 PHP
smarty模板引擎中内建函数if、elseif和else的使用方法
Jan 22 PHP
php集成套件服务器xampp安装使用教程(适合第一次玩PHP的新手)
Jun 03 PHP
php 变量引用与变量销毁机制详细介绍
Dec 05 PHP
Laravel 6.2 中添加了可调用容器对象的方法
Oct 22 PHP
Laravel 微信小程序后端搭建步骤详解
Nov 26 PHP
php 实现简单的登录功能示例【基于thinkPHP框架】
Dec 02 PHP
PHP实现页面静态化深入讲解
Mar 04 PHP
php 常用类整理
Dec 23 #PHP
PHP 源代码压缩小工具
Dec 22 #PHP
php 8小时时间差的解决方法小结
Dec 22 #PHP
PHP 分页原理分析,大家可以看看
Dec 21 #PHP
c#中的实现php中的preg_replace
Dec 21 #PHP
php 空格,换行,跳格使用说明
Dec 18 #PHP
PHP 抓取新浪读书频道的小说并生成txt电子书的代码
Dec 18 #PHP
You might like
一个MYSQL操作类
2006/11/16 PHP
探讨如何把session存入数据库
2013/06/07 PHP
解析PHP中empty is_null和isset的测试
2013/06/29 PHP
PHP中使用TCPDF生成PDF文档实例
2014/07/01 PHP
php数组索引与键值操作技巧实例分析
2015/06/24 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
2020/05/14 PHP
可选择和输入的下拉列表框示例
2013/11/05 Javascript
一个小例子解释如何来阻止Jquery事件冒泡
2014/07/17 Javascript
javascript实现右侧弹出“分享到”窗口效果
2016/02/01 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
2016/02/18 Javascript
jQuery的ajax下载blob文件
2016/07/21 Javascript
将html页面保存成图片,图片写入pdf的实现方法(推荐)
2016/09/17 Javascript
jQuery点击弹出层弹出模态框点击模态框消失代码分享
2017/01/21 Javascript
Vue实例中生命周期created和mounted的区别详解
2017/08/25 Javascript
Vue实现简易翻页效果源码分享
2018/11/08 Javascript
Vue中axios拦截器如何单独配置token
2019/12/27 Javascript
Python版的文曲星猜数字游戏代码
2013/09/02 Python
使用Python编写一个最基础的代码解释器的要点解析
2016/07/12 Python
numpy使用技巧之数组过滤实例代码
2018/02/03 Python
Python实现求一个集合所有子集的示例
2018/05/04 Python
python使用turtle库绘制时钟
2020/03/25 Python
python http基本验证方法
2018/12/26 Python
python实现对输入的密文加密
2019/03/20 Python
Python音频操作工具PyAudio上手教程详解
2019/06/26 Python
Python 按比例获取样本数据或执行任务的实现代码
2020/12/03 Python
python+selenium实现12306模拟登录的步骤
2021/01/21 Python
python利用proxybroker构建爬虫免费IP代理池的实现
2021/02/21 Python
用CSS3和table标签实现一个圆形轨迹的动画的示例代码
2019/01/17 HTML / CSS
HTML5 canvas基本绘图之绘制矩形
2016/06/27 HTML / CSS
体育教育个人自荐信范文
2013/12/01 职场文书
幼儿运动会邀请函
2014/01/17 职场文书
学生手册家长评语
2014/02/10 职场文书
死亡证明书样本说明
2014/10/18 职场文书
《夜莺的歌声》教学反思
2016/02/22 职场文书
PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
2021/04/16 PHP
JAVA 线程池(池化技术)的实现原理
2022/04/28 Java/Android