為何大多數的 Joomla! PHP 檔案都以 defined(' JEXEC') 作為開頭?

From Joomla! Documentation

This page is a translated version of the page Why do most of the Joomla! PHP files start with defined(' JEXEC')? and the translation is 100% complete.

Other languages:
العربية • ‎Deutsch • ‎English • ‎español • ‎français • ‎Nederlands • ‎中文(台灣)‎

此份文件說明了 _JEXEC 如何用來保護許多 PHP 檔案,並說明為何要使用它,何時使用它,以及什麼情況下不該使用它。 另見: 為何大多數的 Joomla! PHP 檔案都以 defined(' JEXEC') 作為開頭?

這是什麼?

以下是 Joomla! PHP 檔案中,常見的開頭內容:

defined('_JEXEC') or die('Restricted access');

為何要用它?

_JEXEC 是定義於index.php 檔案中,屬於 Joomla! 頂層的實例(instance) 的常數 (constant),是用來確保進入 Joomla! 的安全。 defined or die 會檢查並確保使用路徑取得檔案時,_JEXEC 有被定義。這會用來保障當功能、變數或 class 沒有在檔案中定義時,不會因為PHP的偵錯回報,暴露檔案的路徑資訊。
這也可以避免一些變數注入攻擊,它們會透過註冊全域,來欺騙 PHP 檔案,讓它認為它有在程式中,雖然這並非是真的。

設定錯誤回報為關閉會有類似的效果,然而有些時候,並不一定會與允許設定php.ini檔案。無論能不能修改php的設定檔,JEXEC 檢查都會啟動,而且沒有什麼副作用。 (例如,如果您正在作偵錯,要讓每一個檔案的錯誤訊息少一些,程序會很煩人,因為您會需要設定除錯標籤來停止報錯,或是把檔案加到停用錯誤回報,這不有趣!)

何時要用它?

加到檔案中的這個檢查,會在路徑暴露,而被直接執行的情形下有用。 例如,如果在外掛 Backlink System Plugin (/plugins/system/backlink.php 檔案) 中停用這個檢查,_JEXEC,會出現下面的錯誤:

Fatal error: Call to undefined function jimport() in /Users/pasamio/Sites/workspace/joomla_15/plugins/system/backlink.php on line 18

事實證明,當檔案直接被呼叫時,'jimport' function 並不會存在,所以 PHP 會發出錯誤訊息,並暴露檔案的路徑。在檔案中加入defined or die 檢查,在檔案被訪問的時候,會導致 "Restricted access"訊息。

JEXEC 的概念是要檢查 PHP 檔案相依於其他檔案才能適當運作。一般而言,如果您在沒有 JEXEC 檢查的情形下,直接訪問檔案的話,會有 PHP 錯誤訊息 (假設您的 PHP 錯誤回報設定為「是」) 說明缺少的變數、功能、物件或類似的資訊,所以檔案需要被保護。

有些檔案可能不需要這個檢驗來保護,它們是不會有外部相依性的檔案 (例如,一個簡單的 class ,或是稍微複雜一點的程式) ,或是有外部檔案,但可以在 Joomla! 以外被執行的,例子包含了 TinyMCE 的 GZip'd Javascript 產生碼,完全是自我包含的。