當您設定一個文字網域時,它(顯然地)會清除前一個。
當您使用巢狀 include 時,這可能會產生問題,因為其中可能會有使用不同文字網域的 textdomain() 呼叫。從 include 返回後,您的文字網域會被更改,而父程式碼的其餘部分會無法翻譯剩餘的句子。
我寫了這兩個小函式來避免這種情況。您應該將整個程式碼放入一個檔案中,並在每個需要 gettext 功能的程式碼中 require_once 它。然後,在每個設定文字網域的程式碼/函式的開頭和結尾只使用 set_textdomain() 和 restore_textdomain()。
對 set_textdomain() 的呼叫必須對應到對 restore_textdomain() 的呼叫,並且巢狀呼叫的數量沒有限制。
這裡做了一個優化:當新的文字網域與目前的文字網域相同時,不會進行任何更改,restore_textdomain() 會知道這一點,因此您可以安全地呼叫它。
<?php
$_td_stack = array(); // 文字網域堆疊
/**
* 在記錄目前的文字網域後設定新的文字網域,
* 以便稍後可以使用 restore_textdomain() 還原。
*
* 可以巢狀呼叫這兩個函式。
* @param string 要設定的新文字網域
*/
function set_textdomain($td)
{
global $_td_stack;
$old_td = textdomain(NULL);
if ($old_td)
{
if (!strcmp($old_td, $td))
{
array_push($_td_stack, false);
}
else
{
array_push($_td_stack, $old_td);
}
}
textdomain($td);
}
/**
* 還原上次呼叫 set_textdomain() 之前作用中的文字網域。
*/
function restore_textdomain()
{
global $_td_stack;
$old_td = array_pop($_td_stack);
if ($old_td)
{
textdomain($old_td);
}
}
?>