在PHP中檢查PHP文件是否有語(yǔ)法錯(cuò)誤的方法
更新時(shí)間:2009年12月23日 22:35:31 作者:
在網(wǎng)上找了一下。剛開(kāi)始以為 token_get_all()函數(shù)能處理語(yǔ)法錯(cuò)誤的問(wèn)題,結(jié)果發(fā)現(xiàn),它只是做簡(jiǎn)單的詞法分析。沒(méi)有辦法。后來(lái)到論壇上去問(wèn)了一下
之前在當(dāng)當(dāng)?shù)臅r(shí)候的一個(gè)項(xiàng)目中用到了一個(gè)簡(jiǎn)單的模板引擎,其實(shí)也是借鑒discuz來(lái)做的模板引擎,很簡(jiǎn)單,它所作的事情就是把一些自定義的標(biāo)簽編譯成php代碼。已經(jīng)說(shuō)了很簡(jiǎn)單了,所以編譯的時(shí)候也名優(yōu)進(jìn)行模板語(yǔ)法的檢查,那么在開(kāi)發(fā)過(guò)程中就會(huì)出現(xiàn)編譯出來(lái)的php文件有語(yǔ)法問(wèn)題,有語(yǔ)法問(wèn)題沒(méi)有關(guān)系,我修改重新編譯一下就好了。首先不能在每次請(qǐng)求的時(shí)候都把php模板重新編譯一下,會(huì)嚴(yán)重影響性能,折中的處理時(shí)在每個(gè)編譯好的php文件末尾檢查一下該模板文件是否已經(jīng)修改過(guò),根據(jù)設(shè)定的更新頻率,如果又需要?jiǎng)t重新編譯模板文件,現(xiàn)在的問(wèn)題是編譯出來(lái)的php文件自己有語(yǔ)法錯(cuò)誤,根本執(zhí)行不到模板檢查那一步,所以即使修改了模板文件中的問(wèn)題也不會(huì)重新編譯。 所以我想尋找一種簡(jiǎn)單的方法來(lái)檢查生成的php文件是否合法。不合法就重新編譯,這樣開(kāi)發(fā)過(guò)程中就不用出現(xiàn)錯(cuò)誤就得手動(dòng)刪除緩存文件了。
在網(wǎng)上找了一下。剛開(kāi)始以為 token_get_all()函數(shù)能處理語(yǔ)法錯(cuò)誤的問(wèn)題,結(jié)果發(fā)現(xiàn),它只是做簡(jiǎn)單的詞法分析。沒(méi)有辦法。后來(lái)到論壇上去問(wèn)了一下
http://groups.google.com/group/professional-php/browse_thread/thread/b8581f6b07b10ff0/2601a63c406bb1c1?lnk=gst&q=reeze#2601a63c406bb1c1
有人告訴我有這樣一個(gè)函數(shù) php_check_syntax() http://www.php.net/manual/en/function.php-check-syntax.php 我想問(wèn)題就這么堅(jiān)決了。。我真應(yīng)該RTF(Read The Fuck Mannual). 仔細(xì)一看。這個(gè)函數(shù)已近被棄用了:
Note: For technical reasons, this function is deprecated and removed from PHP. Instead, use php -l somefile.php from the commandline.
這個(gè)technical reason 到底是什么呢? 先不管了,以后再慢慢研究,反正不能使用這個(gè)方法就對(duì)了。
他們的建議是使用命令行$php -l filename.php 來(lái)檢查語(yǔ)法。
Gary Every給了我一個(gè)代碼片段參考:
在命令行下檢查問(wèn)題也不大。如果我要放在在線應(yīng)用呢? 這就涉及到可移植性的問(wèn)題了。首先是操作系統(tǒng),然后就是環(huán)境變量。這樣的話就會(huì)依賴(lài)于服務(wù)器端的配置。在http://www.php.net/manual/en/function.php-check-syntax.php 上有人貼出了自己的php_check_syntax()函數(shù)實(shí)現(xiàn)。
有的采用的就是上面的命令行的方法。
后面有提到使用eval的方法來(lái)驗(yàn)證。eval方法會(huì)執(zhí)行傳入的代碼, 如果代碼有語(yǔ)法錯(cuò)誤則會(huì)拋出parser error, 可以使用'@'錯(cuò)誤抑制符去掉錯(cuò)誤信息,eval和echo一樣并不是函數(shù),不能使用變量函數(shù)的方法調(diào)用比如:
$func = ‘eval'
$func()這樣的調(diào)用就是無(wú)效的。它會(huì)提示沒(méi)有eval函數(shù),如果你自己定義這么一個(gè)函數(shù)也是有問(wèn)題的。因?yàn)閑val是一個(gè)關(guān)鍵字。
eval調(diào)用和include差不多,如果被包含文件中沒(méi)有明確return就返回null。如果直接eval我們需要檢查的文件會(huì)造成被檢查的文件內(nèi)代碼被執(zhí)行,這可不是我們想要的,我們只需要檢查一下這個(gè)文件的語(yǔ)法是否正確。 我們可以在要檢查的文件之前添加return 語(yǔ)句,讓代碼提前跳出,那么后面的代碼就不會(huì)執(zhí)行了。好的,就這么干。代碼如下:
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
?>
因?yàn)镻arse error 是沒(méi)法被 set_error_handler處理函數(shù)處理的。這個(gè)異常沒(méi)辦法catch到。所以才使用了@來(lái)抑制錯(cuò)誤。這帶來(lái)的問(wèn)題就是我們無(wú)法得到詳細(xì)的錯(cuò)誤信息。 不過(guò)目前我需要的功能也只是檢查語(yǔ)法是否正確。不正確的話重新編譯模板文件,就這么簡(jiǎn)單,至于語(yǔ)法錯(cuò)誤,在顯示網(wǎng)頁(yè)的時(shí)候自然會(huì)看得到。
最好的辦法就是這個(gè)被遺棄的php_check_syntax這個(gè)方法回到php中。下次再研究下他們是出于什么原因把這個(gè)函數(shù)去掉的。
////////思維很混亂,寫(xiě)的每一點(diǎn)條理性,誰(shuí)讓我語(yǔ)文那么爛涅。
在網(wǎng)上找了一下。剛開(kāi)始以為 token_get_all()函數(shù)能處理語(yǔ)法錯(cuò)誤的問(wèn)題,結(jié)果發(fā)現(xiàn),它只是做簡(jiǎn)單的詞法分析。沒(méi)有辦法。后來(lái)到論壇上去問(wèn)了一下
http://groups.google.com/group/professional-php/browse_thread/thread/b8581f6b07b10ff0/2601a63c406bb1c1?lnk=gst&q=reeze#2601a63c406bb1c1
有人告訴我有這樣一個(gè)函數(shù) php_check_syntax() http://www.php.net/manual/en/function.php-check-syntax.php 我想問(wèn)題就這么堅(jiān)決了。。我真應(yīng)該RTF(Read The Fuck Mannual). 仔細(xì)一看。這個(gè)函數(shù)已近被棄用了:
Note: For technical reasons, this function is deprecated and removed from PHP. Instead, use php -l somefile.php from the commandline.
這個(gè)technical reason 到底是什么呢? 先不管了,以后再慢慢研究,反正不能使用這個(gè)方法就對(duì)了。
他們的建議是使用命令行$php -l filename.php 來(lái)檢查語(yǔ)法。
Gary Every給了我一個(gè)代碼片段參考:
在命令行下檢查問(wèn)題也不大。如果我要放在在線應(yīng)用呢? 這就涉及到可移植性的問(wèn)題了。首先是操作系統(tǒng),然后就是環(huán)境變量。這樣的話就會(huì)依賴(lài)于服務(wù)器端的配置。在http://www.php.net/manual/en/function.php-check-syntax.php 上有人貼出了自己的php_check_syntax()函數(shù)實(shí)現(xiàn)。
有的采用的就是上面的命令行的方法。
后面有提到使用eval的方法來(lái)驗(yàn)證。eval方法會(huì)執(zhí)行傳入的代碼, 如果代碼有語(yǔ)法錯(cuò)誤則會(huì)拋出parser error, 可以使用'@'錯(cuò)誤抑制符去掉錯(cuò)誤信息,eval和echo一樣并不是函數(shù),不能使用變量函數(shù)的方法調(diào)用比如:
$func = ‘eval'
$func()這樣的調(diào)用就是無(wú)效的。它會(huì)提示沒(méi)有eval函數(shù),如果你自己定義這么一個(gè)函數(shù)也是有問(wèn)題的。因?yàn)閑val是一個(gè)關(guān)鍵字。
eval調(diào)用和include差不多,如果被包含文件中沒(méi)有明確return就返回null。如果直接eval我們需要檢查的文件會(huì)造成被檢查的文件內(nèi)代碼被執(zhí)行,這可不是我們想要的,我們只需要檢查一下這個(gè)文件的語(yǔ)法是否正確。 我們可以在要檢查的文件之前添加return 語(yǔ)句,讓代碼提前跳出,那么后面的代碼就不會(huì)執(zhí)行了。好的,就這么干。代碼如下:
checker.php
復(fù)制代碼 代碼如下:
<?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
復(fù)制代碼 代碼如下:
<?php
foreach:: a => b
?>
因?yàn)镻arse error 是沒(méi)法被 set_error_handler處理函數(shù)處理的。這個(gè)異常沒(méi)辦法catch到。所以才使用了@來(lái)抑制錯(cuò)誤。這帶來(lái)的問(wèn)題就是我們無(wú)法得到詳細(xì)的錯(cuò)誤信息。 不過(guò)目前我需要的功能也只是檢查語(yǔ)法是否正確。不正確的話重新編譯模板文件,就這么簡(jiǎn)單,至于語(yǔ)法錯(cuò)誤,在顯示網(wǎng)頁(yè)的時(shí)候自然會(huì)看得到。
最好的辦法就是這個(gè)被遺棄的php_check_syntax這個(gè)方法回到php中。下次再研究下他們是出于什么原因把這個(gè)函數(shù)去掉的。
////////思維很混亂,寫(xiě)的每一點(diǎn)條理性,誰(shuí)讓我語(yǔ)文那么爛涅。
相關(guān)文章
php將12小時(shí)制轉(zhuǎn)換成24小時(shí)制的方法
這篇文章主要介紹了php將12小時(shí)制轉(zhuǎn)換成24小時(shí)制的方法,涉及php時(shí)間操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03
PHP實(shí)現(xiàn)的激活用戶(hù)注冊(cè)驗(yàn)證郵箱功能示例
這篇文章主要介紹了PHP實(shí)現(xiàn)的激活用戶(hù)注冊(cè)驗(yàn)證郵箱功能,詳細(xì)分析了php郵件激活用戶(hù)所涉及的數(shù)據(jù)庫(kù)、郵件相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
PHP stream_context_create()作用和用法分析
創(chuàng)建并返回一個(gè)文本數(shù)據(jù)流并應(yīng)用各種選項(xiàng),可用于fopen(),file_get_contents()等過(guò)程的超時(shí)設(shè)置、代理服務(wù)器、請(qǐng)求方式、頭信息設(shè)置的特殊過(guò)程。2011-03-03
php批量添加數(shù)據(jù)與批量更新數(shù)據(jù)的實(shí)現(xiàn)方法
這篇文章主要介紹了php批量添加數(shù)據(jù)與批量更新數(shù)據(jù)的實(shí)現(xiàn)方法,涉及針對(duì)表單的處理與sql語(yǔ)句的靈活使用,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-12-12
php實(shí)現(xiàn)獲取及設(shè)置用戶(hù)訪問(wèn)頁(yè)面語(yǔ)言類(lèi)
這篇文章主要介紹了php實(shí)現(xiàn)獲取及設(shè)置用戶(hù)訪問(wèn)頁(yè)面語(yǔ)言類(lèi),可實(shí)現(xiàn)獲取/設(shè)置用戶(hù)訪問(wèn)的頁(yè)面語(yǔ)言,如果用戶(hù)沒(méi)有設(shè)置訪問(wèn)語(yǔ)言,則讀取Accept-Language,需要的朋友可以參考下2014-09-09
工廠模式在Zend Framework中應(yīng)用介紹
在Zend Framework中,使用了多種設(shè)計(jì)模式。其中對(duì)數(shù)據(jù)庫(kù)的封裝,用到了工廠模式2012-07-07
使用PHP實(shí)現(xiàn)Mysql讀寫(xiě)分離
本篇文章是對(duì)使用PHP實(shí)現(xiàn)Mysql讀寫(xiě)分離的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
WampServer搭建php環(huán)境時(shí)遇到的問(wèn)題匯總
這篇文章主要介紹了WampServer搭建php環(huán)境時(shí)遇到的常見(jiàn)問(wèn)題的解決辦法匯總,以上所述就是本文的全部?jī)?nèi)容了。2015-07-07

