PHP equivelent include guards
在 C/C++ 裡,可以用 #ifdef/#define/#endif 來做 include guard 避免重複引入,而在 PHP 裡則需要用 include_once() 及 require_once() 等 _once 系列的函式,來避免重複引入。比較麻煩的是,對於 PHP 而言,相對路徑的起點是程式碼執行起點所在的那個檔案的目錄,而不是呼叫 include_once()、require_once() 的程式檔案所在的目錄。
舉個例子來說:被執行的 a.php 裡引入了 lib/b.php,然後 lib/b.php 又引入了 c.php,此時,PHP 會到 a.php 所在的目錄尋找 c.php,而非 b.php 所在的目錄尋找。
這個問題,對於 library writer 會產生相當大的困擾,除非使用者將 library 安裝至 PHP 的 library 目錄 (例如在 FreeBSD 下用 ports 安裝 PHP,其 library 目錄即為 /usr/local/lib/php),直接以該目錄為相對路徑起點,才不會有此困擾。
因此,我寫了下面這些 functions 來解決這樣的問題:
////////////////////////////////////////////////////////////////////////
// Hacks for include guards.
//
/**
* 具備 include guard 功能的 include() 版本。
*
* @param caller 請固定傳入 __FILE__。
* @param path 請傳入欲引入的檔案之相對(於呼叫此函示之檔案的)路徑。
*/
function include_file($caller, $path)
{
include(realpath(dirname($caller) . '/' . $path));
}
/**
* 具備 include guard 功能的 include_once() 版本。
*
* @param caller 請固定傳入 __FILE__。
* @param path 請傳入欲引入的檔案之相對(於呼叫此函示之檔案的)路徑。
*/
function include_file_once($caller, $path)
{
include_once(realpath(dirname($caller) . '/' . $path));
}
/**
* 具備 include guard 功能的 require() 版本。
*
* @param caller 請固定傳入 __FILE__。
* @param path 請傳入欲引入的檔案之相對(於呼叫此函示之檔案的)路徑。
*/
function require_file($caller, $path)
{
require(realpath(dirname($caller) . '/' . $path));
}
/**
* 具備 include guard 功能的 require_once() 版本。
*
* @param caller 請固定傳入 __FILE__。
* @param path 請傳入欲引入的檔案之相對(於呼叫此函示之檔案的)路徑。
*/
function require_file_once($caller, $path)
{
require_once(realpath(dirname($caller) . '/' . $path));
}



Post a Comment