問題描述
更新:我的原始問題已經解決了,但這正在成為一個有效的討論,為什麼不使用全局變量,所以我正在更新這個問題來反映。該解決方案是<?php global $category_link_prop; echo esc_url( $category_link_prop ); ?>,如 @TomJNowell 所建議的。更新 2:我現在正在做正是我想要的。但是我仍然在使用全球範圍,很樂意找到一個更好的方法。
我正在設計一大堆全球變量,將固定鏈接分類用於我主題的各個地方。其主要原因是用於主導航,以及根據當前帖子所屬類別選擇的一系列子導航。這不是我將被其他人使用的主題,但是建立在一個非常具體的目的。
這是我目前正在創建的 (我只粘貼了一些變量) 。
function set_global_nav_var()
{
//proposal
global $prop;
// Get the ID of a given category
$category_id_prop = get_cat_ID( 'proposal' );
// Get the URL of this category
$category_link_prop = get_category_link( $category_id_prop );
$prop = '<a href="'%20.esc_url(%20$category_link_prop%20).%20'" title="Proposal">Proposal</a>';
//Calvinball
global $cb;
// Get the ID of a given category
$category_id_cb = get_cat_ID( 'calvinball' );
// Get the URL of this category
$category_link_cb = get_category_link( $category_id_cb );
$cb = '<a href="'%20.esc_url(%20$category_link_cb).%20'" title="Calvinball">Calvinball</a>';
}
add_action( 'init', 'set_global_nav_var' );
我現在可以做<?php global $prop; echo $prop; ?>,他可以通過 4 個地方來獲取代碼的整個鏈接。當這種變化時,我只需要在一個地方改變它。我對不涉及全球範圍的替代品開放。
最佳解決方案
雖然我強烈建議反對這一點,但它不會加快速度,您的使用不正確。
當您嘗試使用全局時,您必須首先指定全局關鍵字。在定義其值時,您已經在此處指定了它,但在該範圍之外,它需要作為全局作用域變量重新聲明。
例如在 functions.php 中:
function test() {
global $hello;
$hello = 'hello world';
}
add_action( 'after_theme_setup', 'test' );
在 single.php 中,這將不起作用:
echo $hello;
因為 $ hello 是未定義的。但是這樣做會:
global $hello;
echo $hello;
當然你也不應該這樣做。 WordPress 已經嘗試將這些東西緩存在對象緩存中。您將看到沒有加快速度 (您可能會看到一個微小的速度降低),所有你會得到的是額外的複雜性,需要輸出很多沒有必要的全局聲明。
您最好使用結構化數據,如對象或依賴注入,或在您的情況下,一組功能。
例如,這裏是一種通過靜態變量進行類似操作的方式 (由於相同的原因,它們仍然是不好的,但是稍微少一些,並且更易於鍵入) 。
function awful_function( $new_hello='' ) {
static $hello;
if ( !empty( $new_hello ) ) {
$hello = $new_hello;
}
return $hello;
}
awful_function( 'telephone' );
echo awful_function(); // prints telephone
awful_function( 'banana');
echo awful_function(); // prints banana
如果您真的想通過將數據存儲到 re-use 的某個地方來節省時間,請考慮使用 WP_Cache 系統
次佳解決方案
不要使用全局變量,就這麼簡單。
為什麼不使用全局變量
由於使用全局變量使得長期維護軟件變得更加困難。
-
一個全局可以在代碼中的任何地方被聲明,或者根本就沒有地方,因此沒有任何地方可以直觀地查看關於全局所用的一些註釋
-
在閲讀代碼時,通常會認為變量是函數本地的,不明白在函數中改變它們的值可能會有系統的變化。
-
如果它們不處理輸入,函數在使用相同參數調用時應返回相同的值/輸出。在函數中使用全局變量引入了在函數聲明中不是文檔的附加參數。
-
全局變量沒有任何特定的初始化結構,因此您無法確定何時可以訪問全局值,並且在初始化之前嘗試訪問全局時不會收到任何錯誤。
-
有人 (一個插件可能) 可能會使用同名的全局變量,破壞你的代碼,或者你根據初始化順序毀了它。
WordPress 核心的方式方式很多地使用全局變量。在嘗試瞭解 the_content 的基本功能如何工作時,您突然意識到 $more 變量不是本地的,而是全局的,需要搜索整個核心文件以瞭解何時設置為 true 。
那麼當試圖停止複製和粘貼幾行代碼而不是將第一個運行結果存儲在全局中時,可以做些什麼呢?有幾種方法,功能和 OOP 。
甜味劑功能。它只是一個保存複製/粘貼的包裝/宏
// input: $id - the category id
// returns: the foo2 value of the category
function notaglobal($id) {
$a = foo1($id);
$b = foo2($a);
return $b;
}
好處是,現在有一個關於前一個全局功能的文檔,當您返回的值不是您期望的值時,您有一個明顯的要點。
一旦你有一個甜味劑,很容易緩存結果,如果需要 (只有當你發現這個功能需要很長時間才能執行)
function notaglobal($id) {
static $cache;
if (!isset($cache)) {
$a = foo1($id);
$b = foo2($a);
$cache = $b;
}
return $cache;
}
這給你一個全球性的行為,但是每次訪問它時都有一個有保證的初始化的優點。
您可以使用類似的 OOP 模式。我發現 OOP 通常不會在插件和主題中添加任何值,但這是一個不同的討論
class notaglobal {
var latestfoo2;
__constructor($id) {
$a = foo1($id);
$this->latestfoo2 = foo2($a)
}
}
$v = new notaglobal($cat_id);
echo $v->latestfoo2;
這是一個笨拙的代碼,但如果您有幾個值要預先計算,因為它們始終被使用,這可以是一種方式。基本上這是一個以有組織的方式包含所有全局變量的對象。為了避免使這個對象的實例成為一個全局 (你想要一個實例,否則重新計算值),你可能想使用一個 singleton pattern(有些人認為這是一個壞主意,YMMV)
我不喜歡直接訪問對象屬性,所以在我的代碼中,它會變得更多
class notaglobal {
var latestfoo2;
__constructor() {}
foo2($id) {
if (!isset($this->latestfoo2)) {
$a = foo1($id);
$b = foo2($a);
$this->latestfoo2= $b;
}
return $this->latestfoo2;
}
}
$v = new notaglobal();
echo $v->foo2($cat_id);
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。