2010-10-05 64 views
4

在一個項目中,我目前工作,我們正在考慮把system()爲php.ini中的disable_functions聲明。現在,我們的一個元模塊最終也會成爲這種限制的犧牲品,它是用system("php -l");調用語法檢查文件 - 促使我尋找替代品。替代系統('php -l')?

原來曾經有一個php_check_syntax(),但不是唯一這樣做不會限制自己只檢查語法,並進而包括該文件,如果是語法有效,但它是作爲PHP 5.0.5被移除。本手冊建議使用php -l代替,但考慮到我確定在PHP中禁用系統調用函數是一種相當普遍的做法,我想知道是否有可接受的,更好的語法檢查方式來檢查PHP文件中的PHP文件。

(順便說一下,我對此並不感冒,一個'不'完全就夠了(我期待它,真的)我們可以超出這個限制模塊 - 但我問這個問題既出於好奇以及更優美的解決方案的希望。)

+0

包括文件和捕獲異常:P – 2010-10-05 08:23:18

+1

@Ignacio:萬一未舌狀(儘管我認爲是這樣):用錯誤處理程序將致命錯誤轉換爲異常不起作用,更不用說包含該文件將執行它,而這個模塊不應該這樣做。 – pinkgothic 2010-10-05 08:37:20

+0

絕對是舌尖。正確的方法是告訴編譯器編譯它,然後捕獲異常。 – 2010-10-05 08:39:38

回答

3

我發現使用PECL runkit_lint_file()替代。

它做相同的檢查爲php_check_syntax()。

我覺得值得一看。

+0

哦!絕對。這看起來和我一直在尋找的一樣。我想知道我們是否有PECL runkit - 關閉調查!出於好奇,你知道關於這個函數的任何安全公告嗎(雖然他們對我來說是軼事,被檢查的文件是可信的)? – pinkgothic 2010-10-05 08:40:28

+0

據我可以從手冊中讀它應該是安全的,因爲它只是試圖解析php文件,然後返回,如果解析是成功的。它不應該執行任何執行,所以我認爲它是安全的;-) – ITroubs 2010-10-05 08:43:27

+0

好吧,歷史上一直有像'highlight_file()'這樣的函數的安全建議,因爲你可以避開'假設'處理正確的有效載荷 - 因此是一個問題。但是,正如我所說,傳聞 - 我並不擔心在我的情況下,只是一個奇怪的餅乾。 – pinkgothic 2010-10-05 08:46:51

0

查看我們的PHP Formatter。這個命令行工具使用格式良好的PHP文件並很好地格式化它。

它不僅格式,它也語法檢查,並返回命令行狀態,告訴您該文件是否是「良好形成」;它包含一個完整的PHP 5解析器。因爲它是一個命令行工具,所以如果這是您需要做的事情,那麼從PHP腳本啓動將很容易,並且通過檢查返回的狀態,您可以知道該文件是否合法。

+0

「這個命令行工具」 - 我試圖遠離命令行,但 - 這個想法是禁止在PHP中調用它的任何東西,畢竟('system' /'passthru' /等)。儘管如此,謝謝。 :) – pinkgothic 2010-10-07 07:12:27

2

這可能也是一種選擇: When (if ever) is eval NOT evil?

,似乎來得更快:

$nTestTiempo0 = microtime(true); 
exec('php -l yourfile.php',$arrMsgError,$nCodeError); 
$nTestTiempo1 = microtime(true); 
echo "\n", '<p>Time in verify file with exec : '.($nTestTiempo1-$nTestTiempo0).' secs.</p>'; 
//Time in verify file with exec : 0.033198118209839 secs. 

$nTestTiempo0 = microtime(true); 
ob_start(); 
var_dump(eval('return true; if(0){?>'.file_get_contents('yourfile.php').'<?php };')); 
$arrMsgError = explode("\n",trim(ob_get_contents())); 
ob_end_clean(); 
$nTestTiempo1 = microtime(true); 
echo "\n", '<p>Time in verify file with eval : '.($nTestTiempo1-$nTestTiempo0).' secs.</p>'; 
//Time in verify file with eval : 0.00030803680419922 secs. 

$nTestTiempo0 = microtime(true); 
@system('php -l yourfile.php',$nCodeError); 
$nTestTiempo1 = microtime(true); 
echo "\n", '<p>Time in verify file with system : '.($nTestTiempo1-$nTestTiempo0).' secs.</p>'; 
//Time in verify file with system : 0.032964944839478 secs. 
+0

+1爲一種新穎的方法! (順便說一句,'microtime'有一個你可能想看的參數:)它會讓你的示例代碼更加緊湊並且更容易閱讀。)儘管如此,爲了完成:儘管我們也不允許使用'eval'通過不同的渠道。 – pinkgothic 2011-05-10 21:01:35

+0

OKas!我改變了代碼。 – Galled 2011-05-12 15:28:22