2011-12-16 15 views
0

いくつかのオブジェクトのリストがあるとします。これらのオブジェクトは、基本クラスを拡張しているさまざまなクラスのインスタンスです。 これらのオブジェクトをデータベースに保存したいと思います。ダイナミッククラスインスタンス:良いプラクティス?

追加要件として、基本クラスを拡張するクラスの数はかなり大きくなる可能性があります。

は、データベースに文字列としてクラス名を保存し、そのようにそれを取得することをお勧めし:

<?php 
class Page { 
    abstract public function foo($args); 
} 

class ChartPage : Page{ 
    public function foo($args){ 
     var_dump($args); 
    } 
} 

// other classes like ChartPage would be defined here 

// fetched row from a MySQL database 
$row = array("id" => 21, "title" => "Test", "class" => "ChartPage", "args" => "{}"); 
$object = new $row['class']; 
$object->foo($row['args']); 
?> 

は、より良い方法でそのような何かをするために任意のプラクティスはありますか?

答えて

1

あなたはシリアライズ/デシリアライゼーションのPHPでネイティブに利用可能なものを使用するための独自の関数を書くための特別な理由がない限り:

あなたが読むことができる

を次のリンクのPHPのObject Serializationの詳細:

シリアライズされたデータを使用して、JSONやXMLなどの直列化の別の方法を、選択することがありますPHPの外のものと共有する場合。しかし、後でPHPでアクセスするためにオブジェクトを格納するだけの問題であれば、標準の直列化メソッドで十分です。


識別子のいくつかの並べ替えを使用すると、オブジェクトが本当に何であるかの種類を判別するために、それ以外の場合は不可能になり、シリアル化されたデータを格納する必要があります。

確かに、シリアライズされたデータのキーを使用して最良の一致するオブジェクトタイプを検索したことがありますが、これは100%正確ではないため推奨しませんケース。あなたの例では


私はPage::fooがあなたの新しいクラスを作成するファクトリとして使用されることを前提としスニペット。

データをシリアライズ/デシリアライズする独自のメソッドを作成し、オブジェクトにすべてのデータを保存する場合は、継承するクラスに強制的にファクトリを実装する必要はありません。

Pageは、オブジェクトに含まれるキー/値ペアをループすることによって任意のクラスをシリアライズする統一されたメソッドを持つこともできます。しかし、このアプローチには若干の問題があります。

継承されたオブジェクトがかなり複雑なメンバー(つまり、ユーザー定義クラスなど基本的ではない)を持つ場合、それを正確に保存したくない場合があります。

たとえば、オブジェクトにアクティブなmysql接続がある場合、その接続自体をシリアル化されたデータにどのように格納するのかという理由で、そのような接続を再オープンするための資格情報を保存するだけです。

さらに、ソケット接続に関連付けられたファイルディスクリプタを保存し、常にバックグラウンドで実行されている仮想のMySQLKeepConnAliveオブジェクトを使用して開いたままにしておくと、すばらしいことになります。

Anyhow;私があなただったら、基底オブジェクトで利用可能な直列化/逆直列化のためのデフォルトのメソッドを書くでしょう。継承された型が複雑な場合、これらのメソッドをオーバーライドして独自のメソッドを提供するのは開発者次第です。

データ構造を使用して以下のようにオブジェクトを保存しますが、これは先ほど説明したものとはそれほど違いはありません。 '__PAYLOAD'にはオブジェクトのメンバーが含まれ、他の値は基本クラスで定義されている必要があります。

'__PAYLOAD'は異なるクラスの2つのインスタンスでは同じに見えませんが、特定のIDとタイプのオブジェクトをロードし、そのオブジェクトに関する基本情報を見つける統一的な方法があります。

言うまでもなく、以下の「ベース」フィールドを追加することができます。これは私が考えているものの例です。

$serialized_data = array (
    '__TITLE': 'Test', 
    '__TYPE': 'CharPage', 
    '__ID':   21, 
    '__PAYLOAD': array (
    'member_1' => 'foobar', 
    'member_2' => 'barbaz', 
    'member_3' => 'bazbir' 
) 
); 
関連する問題