問題描述

有沒有人在外掛或主題中使用 autoloading 和/或 PHP 名稱空間?

使用它們的想法?有什麼傷害嗎陷阱?

注意:名稱空間僅限於 PHP 5.3+。假設在這個問題上,你知道你會處理你所知道的具有 PHP 5.3 或更高版本的伺服器。

最佳解決方案

好吧,我有兩個大專案,我已經控制了伺服器足夠的名稱空間,並依靠自動載入。

第一。自動載入真棒不用擔心需求是一件比較好的事情。

這是一個我在幾個專案中使用的裝載機。檢查以確保類在當前的名稱空間中,然後 bails 如果沒有。從那裡只是一些字串操作來找到類。

<?php
spl_autoload_register(__NAMESPACE__ . 'autoload');
function autoload($cls)
{
    $cls = ltrim($cls, '');
    if(strpos($cls, __NAMESPACE__) !== 0)
        return;

    $cls = str_replace(__NAMESPACE__, '', $cls);

    $path = PLUGIN_PATH_PATH . 'inc' .
        str_replace('', DIRECTORY_SEPARATOR, $cls) . '.php';

    require_once($path);
}

人們可以很容易地適應這個使用沒有名稱空間。假設你的外掛’s/theme’s 的字首是統一的,你可以測試該字首。然後在類名中使用下劃線作為目錄分隔符的佔位符。如果你正在使用很多類,你可能想要使用某種類的自動載入器。

名稱空間和掛鉤

WordPress 的鉤子系統透過使用 call_user_func(和 call_user_func_array) 工作,它將函式名稱作為字串,並在 do_action(以及隨後的 call_user_func) 函式呼叫時呼叫它們。

使用名稱空間,這意味著您需要將包含名稱空間的完全限定的函式名稱傳遞給鉤子。

<?php
namespace WPSESomeNameSpace;

add_filter('some_filter', 'WPSESomeNameSpacethe_function');
function the_function()
{
   return 'did stuff';
}

如果要這樣做,自由使用__NAMESPACE__魔法常數可能會更好。

<?php
namespace WPSESomeNameSpace;

add_filter('some_filter', __NAMESPACE__ . 'the_function');
function the_function()
{
   return 'did stuff';
}

如果你總是將你的鉤子放在課堂上,那就更容易了。使用 $this 的建構函式中的類的標準建立例項和所有鉤子都可以正常工作。

<?php
namespace WPSESomeNameSpace;

new Plugin;

class Plugin
{
    function __construct()
    {
        add_action('plugins_loaded', array($this, 'loaded'));
    }

    function loaded()
    {
        // this works!
    }
}

如果您使用像我想要的靜態方法,則需要將完整的類名作為陣列的第一個引數傳遞。這是很多工作,所以你可以使用魔術__CLASS__常數或 get_class

<?php
namespace WPSESomeNameSpace;

Plugin::init();

class Plugin
{
    public static function init()
    {
        add_action('plugins_loaded', array(__CLASS__, 'loaded'));
        // OR: add_action('plugins_loaded', array(get_class(), 'loaded'));
    }

    public static function loaded()
    {
        // this works!
    }
}

使用核心類

PHP 的類名解析有點不了瞭如果要使用核心 WP 類 (WP_Widget 在下面的示例中),您必須提供 use 語句。

  

use WP_Widget;

class MyWidget extends WP_Widget
{
   // ...
}

或者您可以使用完全限定的類名稱 – 基本上只是使用反斜槓字首。

<?php
namespace WPSESomeNameSpace;

class MyWidget extends WP_Widget
{
   // ...
}

Defines

這是更通用的 PHP,但它有點我,所以這裡是。

你可能想要定義你經常使用的東西,就像外掛的路徑一樣。使用 define 語句將東西放在根名稱空間中,除非你明確地將名稱空間傳遞給 define 的第一個引數。

<?php
namespace WPSESomeNameSpace;

// root namespace
define('WPSE_63668_PATH', plugin_dir_path(__FILE__));

// in the current namespace
define(__NAMESPACE__ . 'PATH', plugin_dir_path(__FILE__));

您還可以使用 PHP 5.3 plus 的檔案根級別中的 const 關鍵字。 consts 始終在當前的名稱空間中,但是 define 呼叫的靈活性較低。

<?php
namespace WPSESomeNameSpace;

// in the current namespace
const MY_CONST = 1;

// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);

請隨意新增您可能有的任何其他提示!

次佳解決方案

我使用自動載入 (因為我的外掛有很多類,部分原因是它包括 Twig),從來沒有引起我的注意 (外掛安裝> 20,000 次) 。

如果您有信心,永遠不會需要使用不支援名稱空間的 php 安裝,那麼您再次可以使用 (約 70%的當前 wordpress 部落格不支援名稱空間) 。需要注意的幾件事情

我似乎記得,名稱空間在常規 PHP 中不區分大小寫,但是當在 iis 上使用 fastcgi php 時,這會導致一些頭痛,如果您在 linux 上測試並且不會發現流氓小寫字母。

即使您確定您正在開發的程式碼只能在> 5.3.0 您將無法重用任何沒有奢侈專案的程式碼,這就是為什麼我沒有在內部專案中使用名稱空間的主要原因。我發現名稱空間真的不會增加那麼多,與可能的頭痛不得不刪除它們的依賴。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。