問題描述
當開發一個外掛應該將這些功能分組到一個類中以避免名稱空間衝突?
使用類建立 PHP 的效能開銷?
如果有效能打擊,應該是功能名稱只是 pre-fixed 而不是?
最佳解決方案
When developing a plugin should the functions be grouped together into a Class to avoid namespace conflicts?
是的,但這只是一個小小的論據。 In-fact 不是 OOAD 中的一個類的”true” 性質。
Does using classes create performance overheads for PHP?
不,不是特別。糟糕的設計和/或壞的書寫程式碼或 pre-mature 最佳化比實際的語言功能創造出更多的效能問題。
If there is a performance hit, should function names just be pre-fixed instead?
如書面所述,沒有表現打擊。糟糕的書面程式碼將會更好的表現出色,而不是強制您做壞事的良好程式碼。
底線:
您可以對外掛進行不同的使用。您可以使用它們具有某種名稱空間,並將其用於全域性函式”just” 。最直接的形式是靜態類函式,下面的 code-example 顯示了第一個全域性函式,然後是全域性靜態類函式:
/* global function */
function myplug_hook()
{
}
add_filter('the_hook', 'myplug_hook');
/* global static function */
class myplug
{
public static function hook()
{
}
}
add_filter('the_hook', 'myplug::hook');
這只是一個示例,顯示您需要為單個鉤子鍵入更多。另外,它顯示了名稱空間的工作原理:您可以更容易地替換單個類名稱來重新命名所有靜態函式,然後搜尋並替換 myplug::,因為 myplug_可能因為錯誤的肯定而更難。但最終沒有什麼區別。
關鍵是:靜態類函式 Docs 不是真的很多,然後是全域性 functionsDocs 。
這個例子也是如此:名稱空間很好,但是使用 worpdress,名稱空間停止使用鉤子:回撥函式是硬編碼的,因此使用類的名稱空間的好處 (base-name 的一個位置,類名) 不會有幫助你的程式碼與 wordpress 的鉤子名稱進行幹預。
真正的好處是使用實際的類例項和 non-static 函式。這有利於您開始使用 OO 原則,您可以簡化程式碼。靜態類函式比一個解決方案更為問題。
那麼它不僅僅是語法糖。
要點是:做一些有助於您編寫可以輕鬆處理和維護的程式碼的東西。不要 over-rate 的表現,這是一個常見的錯誤。更重要的是你編寫的程式碼很容易閱讀和理解,只是做你所需要的。也許這個問題和答案在這個上下文中有更大的幫助:多個自定義的 Metabox 幫助。
一個常見的方法我甚至使用較小的外掛是使用靜態幫助函式例項化外掛,其餘的駐留在外掛例項中。這有助於封裝主要的外掛邏輯,它可以從名稱空間中獲益,而私有成員也可以使用不符合標準全域性功能的鉤子之間的 re-used 。以下 code-example 顯示模式:
<?php
/** Plugin Headers ... */
return MyPlugin::bootstrap();
class MyPlugin
{
/** @var MyPlugin */
static $instance;
static public function bootstrap() {
if (NULL === self::$instance) {
self::$instance = new __CLASS__;
}
return self::$instance;
}
# ...
}
這是我用於基本外掛檔案的常見模式。外掛類一方面表示 Wordpress 的外掛,另一方面它允許開始為自己的程式碼使用物件導向的範例,甚至可以完全物件導向 (但不需要) 。它是一個控制器,與整個 wordpress API 介面作為請求。
如示例所示,將建立一個外掛的例項。這樣可以使用像建構函式檔案 (__construct) 這樣的已知的常量來初始化實際的外掛:
# ...
class MyPlugin
{
# ...
public function __construct()
{
add_filter('the_hook', array($this, 'hook'));
}
public function hook()
{
}
# ...
}
當鉤子被註冊時,這個外掛物件已經受益於它的設計:你已經停止了 hard-code 的具體外掛類名的實際鉤子功能。這是可能的,因為該類與回撥的物件例項繫結。聽起來很複雜,只是說:$this 是外掛。可以在鉤子回撥中使用,比較註冊類方法作為鉤子回撥。
這種模式允許與 wordpress 更容易的介面:注入被減少到鉤子的名稱以及它們提供的資料。然後,您可以開始直接實現這個外掛類,或者重構對它的實現,所以只能將程式碼放入外掛類,這是最小限度,以定義你的外掛與 wordpress 的介面,但保持一般的邏輯除了 worpdress 。這是樂趣開始的地方,最有可能是每個外掛作者想要從長遠來看。
所以不要用 worpdress 程式設計,而是反對它。由於 worpdress 是相當靈活的,沒有通用或容易描述程式的介面。一個基本的外掛類可以承擔起這個角色,使您可以為自己的程式碼提供更多的靈活性,這將導致更容易的程式碼和更好的效能。
因此,對於 name-spacing 來說,不僅僅是一個好處。我可以給的最佳建議是:嘗試自己。沒有多少你會鬆動,只有新的東西要發現。
在您保持外掛相容性的同時,您透過了更多主要的 WordPress 更新之後,您可能會注意到差異。
注意事項:如果您的外掛直接與 wordpress 整合以完成工作,則使用一個或兩個公共功能可能更適合您。為工作採取正確的工具。
次佳解決方案
類 VS 函式集
Performance
一般:Afaik,”performance” 在類和函式集之間沒有區別。
詳情:
- 如果您對
function_exists()和class_exists()提出質疑,那麼通常您會得到很多功能 (wp core 中的〜 1.800(?)) 與類 (〜 100(?) 在 wp core 中) 有很大差異。所以製作的東西”pluggable”,因此質疑存在是執行時間的不同。 - 類比函式集提供了一個很大的優勢:你可以更容易地避免在不需要它的請求上呼叫它,然後使用函式。您只需要對類進行條件檢查,而不是為每個函式執行條件檢查。所以如果你不需要它在每一個頁面載入,並可以避免呼叫大量的 if / else 語句,功能”performs better” 。
建築 – 工作原理:
函式集:通常,函式在你呼叫的行中被執行。所以每次你打電話的東西,你必須再寫一次,如果你不得不多說一次。
類:類有不同的褻瀆。最接近函式集的類是”factory” 類 (wikipedia / google) 。 Imo 它幾乎與一組函式相同,但封裝在一個類中。但也有其他”types” 的類。你可以這樣寫一個抽象的或者一個父類的類,你可以用一個子類來擴充套件它。在一個現實世界的例子中:假設你有一個類來建立一些靜態文字欄位。在您的__construct()功能中,您有一組場景,如”left_column”,”right_column”& “footer_field” 。然後你呼叫類似 $text_field = new TextFieldClass(); 來例項化類。之後你只需呼叫 $text_field->add( $case => 'left_column', 'case' => 'foo text' ); 和 $text_field->add( $case => 'footer_field', 'case' => 'bar text' ); 。然後,當您例項化類時,只有當您構建文字欄位時才會呼叫兩個類函式,那麼所有的條件都已經被執行了。在這個 szenario 中,你可以節省一些 ms 的執行時間。
個人想法
如果你明智地寫下你的課,那麼你的表現會有一個小的優勢。但是,您將有一個組織良好的結構來工作。到目前為止沒有什麼壯觀。但是,如果您考慮以下”split” 用於外掛中的類和函式的用例,那麼您將得到我的最後一點:類是內部的,函式是 API 。只要您透過公共可用功能 (即呼叫類或類函式) 提供 API,那麼您將進一步開發您的外掛。您可以自由地改變內部結構,甚至改變外掛的可能性,而無需隨時隨地影響使用者。
例:
// construction of object
if ( ! class_exists( 'WPSE_HelloWorld' ) )
{
class WPSE_HelloWorld
{
function __construct( $args = array( 'text', 'html', 'echo' ) )
{
// call your object building procedures here
$this->hello_world( 'text', 'html', 'echo' );
}
function hello_world( 'text', 'html', 'echo' )
{
$start_el = '<{$html}>';
$end_el = '</{$html}>';
if ( $echo )
{
return print "{$start_el}{$some}{$end_el}";
}
return "{$start_el}{$some}{$end_el}";
}
} // END Class
}
// API: public functions
function the_hello_world( $args( 'echo' => true ) )
{
$new = new WPSE_HelloWorld();
return $new->hello_world( $args );
}
function get_hello_world( array( $args( 'echo' => false) ) )
{
$new = new WPSE_HelloWorld();
return $new->hello_world( $args );
}
// then you can call it like get_the_title() or the_title(), which you know from the WP API:
// 'echo' is set to false per default:
$some_var = get_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *returns* "<strong>hello reader</strong>"
// 'echo' is set to true per default:
the_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *prints/echos* "<strong>hello reader</strong>"
注意:請同時閱讀在評論中釋出的連結 @ t310s 。
第三種解決方案
這是外掛作者的一種純粹的風格選擇。速度沒有真正的區別。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。