回答:
プラグインを開発するとき、名前空間の競合を避けるために、関数をクラスにグループ化する必要がありますか?
はい、しかしそれはマイナーな議論の1つにすぎません。OOADのクラスの「真の」性質ではない事実。
クラスを使用すると、PHPのパフォーマンスのオーバーヘッドが発生しますか?
いいえ、特に。設計が不適切であるか、記述されたコードが不適切であるか、最適化が早すぎると、実際の言語機能よりもはるかに多くのパフォーマンスの問題が発生します。
パフォーマンスが低下した場合、代わりに関数名をあらかじめ固定する必要がありますか?
書かれているように、パフォーマンスに影響はありません。悪い記述のコードは、コードの行がいくつかありますが、悪いことを強いることはありません。
ボトムライン:
プラグインのクラスをさまざまに使用できます。それらを使用して、ある種の名前空間を持ち、グローバル関数に「ちょうど」使用することができます。その最も直接的な形式は静的クラス関数です。次のコード例は、最初にグローバル関数、次にグローバル静的クラス関数の両方を示しています。
/* 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');
これは、1つのフックにさらに入力する必要があることを示すほんの一例です。さらに、名前空間がどのように機能するかを示します。単一のクラス名を簡単に置き換えて、すべての静的関数の名前を変更し、誤検出のためにmyplug::
困難な検索と置換を行うことができますmyplug_
。しかし、最終的には大きな違いはありません。
重要な点は次のとおりです。静的クラス関数Docsは、グローバル関数Docs以外の実際にはありません。
この例も示しています:Namespacingは問題ありませんが、worpdressを使用すると、フックの使用で名前空間が停止します。コールバック関数はハードエンコードされているため、クラス(base-nameの1つの場所)フック名のワードプレスでコードに介入するときに役立ちます。
実際の利点は、実際のクラスインスタンスと非静的関数を使用することから始まります。これには、OOの原則を利用し始めることができ、コードを合理化できるという利点があります。静的クラス関数は、ソリューションの事実よりも問題です。
そして、それは単なる構文糖以上のものです。
重要な点は次のとおりです。簡単に処理および保守できるコードを記述するのに役立つ何かをします。パフォーマンスを過大評価しないでください。これはよくある間違いです。さらに重要なのは、読みやすく理解しやすいコードを書くことで、必要なことだけを行うということです。たぶん、この質問と回答は、このコンテキストでの全体像に役立つでしょう:Multiple Custom Metabox Help。
小さいプラグインでも私が持っている一般的なアプローチの1つは、静的ヘルパー関数を使用してプラグインをインスタンス化し、残りはプラグインインスタンス内に常駐することです。これは、メインプラグインロジックをカプセル化するのに役立ちます。また、フックを使用して名前空間を設定することや、標準のグローバル関数では不可能なフック間でプライベートメンバーを再利用できます。次のコード例は、パターンを示しています。
<?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のプラグインを表し、他方では、完全にオブジェクト指向である場合もある(ただし、そうである必要はない)独自のコードに対してオブジェクト指向のパラダイムの使用を開始できます。これは一種のコントローラーであり、リクエストとしてワードプレスAPI全体とインターフェースします。
例が示すように、プラグインのインスタンスが作成されます。これにより、Constructor Docs(__construct
)などの既知のコモンを使用して、実際のプラグインを初期化できます。
# ...
class MyPlugin
{
# ...
public function __construct()
{
add_filter('the_hook', array($this, 'hook'));
}
public function hook()
{
}
# ...
}
フックが登録された時点で、このプラグインオブジェクトはすでにその設計から恩恵を受けています。具体的なプラグインクラス名に対して実際のフック関数をハードコーディングするのをやめました。これは、クラスがコールバックのオブジェクトインスタンスにバインドされているために可能です。複雑に聞こえます$this
が、ただ言っているのはプラグインです。フックコールバックで使用できます。登録メソッドをフックコールバックとして比較します。
このパターンにより、ワードプレスとのインターフェースがより簡単になります:注入はフックの名前とそれらが提供するデータに削減されます。その後、このプラグインクラスに直接実装するか、実装をリファクタリングすることで、wordpressに対してプラグインインターフェイスを定義するために最低限必要なコードのみをプラグインクラスに配置し、worpdress以外の一般的なロジックを保持することができます。これが楽しみの始まりであり、おそらく各プラグイン作成者が長期的に達成したいことです。
したがって、worpdressを使用してプログラミングするのではなく、それに反対します。worpdressは非常に柔軟であるため、プログラムに対して一般的または簡単に説明できるインターフェイスはありません。基本プラグインクラスがこの役割を引き受けることができるため、独自のコードの柔軟性が高まり、コードが簡単になり、パフォーマンスが向上します。
そのため、名前の間隔だけでなく、利点もあります。私が与えることができる最もよい提案は次のとおりです。あなたが失うことはそれほど多くなく、発見するのは新しいことだけです。
プラグインの互換性を保ちながら、WordPressのメジャーアップデートをいくつかパスした後、おそらく違いに気付くでしょう。
警告:プラグインがwordpressと直接統合されて仕事を成し遂げる場合、1つまたは2つのパブリック関数を使用する方が適している場合があります。仕事に最適なツールを選択してください。
return $myPlugin = new MyPlugin();
ものも同様です。ただし、全体像としては、単純な新しいものでは不十分な場合があります。WordPressプラグインを比較してください。「密結合」を回避するにはどうすればよいですか?。
一般: Afaik、クラスと関数セットの間に「パフォーマンス」に違いはありません。
詳細:
function_exists()
vs. class_exists()
通常どおり多くの関数(wpコアで〜1.800(?))とクラス(wpコアで〜100(?))を取得した場合、大きな違いがあります。そのため、「プラグ可能」なものを作成し、その存在を疑うことは実行時間の違いです。関数セット:一般に、関数は呼び出した行で実行されます。そのため、ものを呼び出すたびに、複数回呼び出す必要がある場合は、もう一度書く必要があります。
クラス:クラスにはさまざまなアプローチがあります。関数セットに最も近いクラスは「ファクトリー」クラス(wikipedia / google)です。Imoは、一連の関数とほぼ同じですが、クラスにカプセル化されています。しかし、クラスには他の「タイプ」もあります。たとえば、抽象クラスまたは親クラスを記述して、子クラスで拡張できます。実際の例では、いくつかの静的テキストフィールドを構築するクラスがあるとしましょう。あなたでは__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' );
。その後、クラスをインスタンス化したときにすべての条件文と他の条件がすでに実行されており、テキストフィールドを作成するときに2つのクラス関数だけが呼び出されます。このシナリオでは、実行時間を数ミリ秒節約できました。
クラスを賢明に書くと、パフォーマンスにわずかな利点があります。しかし、あなたは取り組むためによく組織された構造を持つでしょう。これまでのところ、見事なものは何もありません。ただし、プラグインのクラスと関数の次の「分割」ユースケースを検討すると、最終的なポイントが得られます。クラスは内部で、関数は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>"
注:Qへのコメントに投稿されたリンク@ t310sもお読みください。
if( ! class_exists )
あなたが最初に持っている行を指していると思いますか?
class_exists
チェックを行うのは、それが複数回含まれる可能性があるからではなく、別のクラスとの競合を避けるためだと思いますか?
通常、クラスはパフォーマンスの面で利点を提供しませんが、いずれかのマイナス効果をもたらすことはほとんどありません。それらの本当の利点は、コードをより明確にし、名前空間の競合を回避することです。
ほとんどの場合、関数を使用する場合は、各関数名にプラグインの名前を入力します。そのため、プラグインに1ダースの関数が数十個ある場合、その名前を何十回も複製します。 。
クラスの場合、クラス名にプラグインの名前が1回だけ含まれている可能性があります。
さらに、継承またはその他のoo構造を使用して、非常にクリーンな方法で動作を実装できます。例は次のとおりです。
class animalplugin{
//plugin functions...
function talk(){print "animalnoise";}
}
class animalplugin_with_cat_mods extends abcplugin{
//cat functions overrides
function talk(){print "meow";}
}
if (iscat()){
new animalplugin_with_cat_mods();
} else {
new animalplugin();
}