問題描述
有沒有人在插件或主題中使用 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。