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