
さあ、練習しましょう。 私の意見では、LSBを使用する最も示唆的な例は、同様のアクションを実行する一連のクラスがある場合です。 Web開発の観点では、特にORMシステムでデータベーステーブルにアクセスするときに、このようなタスクに遭遇することがよくあります。 テーブルを操作するためのすべてのオブジェクトは本質的に似ていますが、同時に独自の機能(および、それに応じてサブクラス)を持ちます。
Storableパターンを実装する(ご想像のとおり)システムにStorableクラスがあるとします(翻訳者のメモ:推測できませんでした:))。 Storableクラスから継承するクラスを定義し、コンストラクターでテーブル名を設定します。 これは次のようなものです。
ArticleEntryクラスはStorableを拡張します{ パブリック関数__construct($ id = null){ if(!is_null($ id)){ $ id = array( 'id' => $ id); } 親:: __コンストラクト( 'articleEntry'、 '*'、$ id); } } //エントリのテキストを出力します: $ entry = new ArticleEntry(10); // id = 10のarticleEntryテーブルからエントリを取得します。 echo $ entry-> html( 'articleBody'); //ロードされたエントリの本文を出力します //レコードを更新します: $エントリ['ts'] =時間(); //時間をNOWに設定します $ entry-> save(); //レコードを更新します
コンストラクターの詳細はスキップできます。Storableクラスがどのように機能するかを想像するためにのみ提供されています。 既に理解しているように、これにより時間を節約でき、単純なSELECT 、 INSERT 、 UPDATEクエリなどの些細なことに費やすことはありません。
このシステムでは、 記事のメインテーブル( ArticleEntry )に加えて、メタデータ(多対1に関連)を含むいくつかのテーブル(タグ、添付ファイルなど)が使用されます。 メインテーブルのデータを更新する前に、サブテーブルからデータを簡単に削除する方法も必要です(データの同期を心配するよりもメタデータを削除して再作成する方が簡単です)。 そこで、データベーススキーマに最も近いコードをシミュレートするために、この実装に決めました。
抽象クラスArticleEntryAbstractはStorableを拡張します{ パブリック関数__construct($テーブル、$ id = null){ if(!is_null($ id)){ $ id = array( 'id' => $ id); } 親:: __コンストラクト($テーブル、 '*'、$ id); } public function purge(){ $ s = $ this-> db-> prepare( 'DELETE FROM'。$ this-> tableName。 'WHERE pulseEntryId =?'); $ s-> execute(array($ this-> data ['entryId'])); } }
purge()メソッドにすべてフォーカスします。 $ this-> tableNameプロパティは、 Storableクラスから受け取った保護されたプロパティです。 以下に使用例を示します。
ArticleEntryAttachmentはArticleEntryAbstractを拡張します{ パブリック関数__construct($ id = null){ 親:: __コンストラクト( 'articleEntryAttachment'、$ id); } }
メタデータテーブルを操作するためのこのような小さなクラスがたくさんあります。 残念ながら、システムではPHPバージョン5.2を使用しているため、 この記事の最初の部分で説明したLSB機能を使用できませんでした。 メタデータを削除するには、次のように書く必要があります。
$ attach = new ArticleEntryAttachment(10); // articleEntryAttachmentテーブルから選択しますWHERE entryId = 10 $ attach-> purge();
purge()メソッドの定義方法を上で見ると、StorableクラスからtableNameを取得していることがわかります。Storableクラスは、子孫クラスのコンストラクターからtableNameを取得しています。 この些細な(しかし絶対に必要な)データに加えて、データベースオブジェクトを$ this-> dbで取得するだけでなく、 articleentryattachmentクラスのオブジェクトを作成しても何も達成できませんでした。 purge()メソッドを静的に呼び出すことができれば、コードはずっと明確できれいになります(確かに効率的です)。 次のコードを検討してください。
抽象クラスArticleEntryAbstractはStorableを拡張します{ パブリック関数__construct($テーブル、$ id = null){ if(!is_null($ id)){ $ id = array( 'id' => $ id); } 親:: __コンストラクト(静的:: TABLE_NAME、 '*'、$ id); } 静的関数パージ($ entryId){ $ db = Db :: get(); //シングルトンデータベースを取得します $ s = $ db-> prepare( 'DELETE FROM'。static :: TABLE_NAME。 'WHERE pulseEntryId =?'); $ s-> execute(array($ entryId)); } } ArticleEntryAttachmentはArticleEntryAbstractを拡張します{ const TABLE_NAME = 'articleAttachment'; }
最初に気づいたことは、 ArticleEntryAttachmentがずっと簡単になったことです。 親クラスのコンストラクタは自己完結型であるため、サブクラスのコンストラクタを再定義する必要はありません。 そして今、あなたは(LSBを使用して)パージ()メソッドを使用することができます:
ArticleEntryAttachment :: purge(10);
現在、 purge()は実行時に決定されるテーブルの名前を取得できるため、静的にすることができます。 その結果、冗長性が完全に削除されるため、コードはよりクリーンになり、実行はより効率的になり、サポート(たとえば、新しいサブクラスの追加)は無意味になります。 これを可能にしてくれたPHP開発者に感謝します!
このマニュアルでは、 __ CLASS__定数の使用など、LSBを使用する他の方法についても説明しているため、必ずphp.netにアクセスしてください。
Via Denis.in.ua:PHPの遅延静的バインディング(パートII:練習)
オリジナル: 遅延静的バインディング:実際的な例