問題描述

更新:我的原始問題已經解決了,但這正在成為一個有效的討論,為什麼不使用全域性變數,所以我正在更新這個問題來反映。該解決方案是<?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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。