2

PHP 変数に加えられたすべての変更を追跡しようとしています。変数は、オブジェクトまたは配列にすることができます。

たとえば、次のようになります。

$object = array('a', 'b');

このオブジェクトは、オブジェクト キャッシュを使用してストレージに永続化されます。PHPスクリプトが再び実行されるとき。

そのため、スクリプトが 2 回目に実行されるとき、または別のスクリプトが実行されてそのオブジェクトが変更されたときに、それらの変更が行われている間、またはスクリプトの実行後に一度に追跡されるようにしたいと考えています。

例えば:

$object[] = 'c';

オブジェクトに「c」が追加されたことを知りたいです。

実際のコードは次のようになります。

$storage = new Storage();
$storage->object = array('a', 'b');

2 回目のロード:

$storage = new Storage();

var_dump($storage->object); // array('a', 'b')

$storage->object[] = 'c';

私が知りたいのは、'c' が $storage->object にプッシュされたので、クラス "Storage" でその値を永続ストレージに設定できるということです。

私はいくつかの方法を試しましたが、うまくいきましたが、欠点があります。

1)オブジェクトへの変更を追跡するクラス「Storable」ですべてのオブジェクトをラップします

クラス「Storable」は、実際のデータ オブジェクトをプロパティとして保存し、それにアクセスするための __get() および __set() メソッドを提供します。オブジェクトのメンバー/プロパティが変更または追加されると、「Storable」クラスがこれを認識します。プロパティがアクセスされると、Storable クラスの __get() は、別の Storable クラスにラップされたプロパティを返すため、新しいレベルごとに再帰的にその変更も追跡されます。

問題は、オブジェクトがネイティブ データ型ではなくなったため、配列に対して配列関数を実行できないことです。

例えば:

$storage = new Storage();

var_dump($storage->object); // array('a', 'b')

array_push($storage->object, 'c'); // fails

代わりに、これらの配列関数を Storable のメソッドとして実装する必要があります。

例えば:

$storage = new Storage();

var_dump($storage->object); // array('a', 'b')

$storage->object->push('c');

これで問題ありませんが、ネイティブ関数を何らかの方法で使用して、開発中のライブラリのオーバーヘッドを削減し、変更を追跡して変更を永続ストレージに追加できるかどうかを知りたいです。

2) 変更の追跡を忘れて、オブジェクト構造全体を更新するだけです

これは、プログラム内のオブジェクトをオブジェクト キャッシュ (別のマシン上にある可能性があります) に実際に格納されているオブジェクトと同期させる最も簡単な方法です。

ただし、これは、1 つのインデックスが変更されたときに、1000 個のインデックスを持つ配列のような構造全体をソケットを介してオブジェクト キャッシュに送信する必要があることを意味します。

3) オブジェクトのミラーをローカルに保持する

また、オブジェクトのクローンを作成し、クローン オブジェクトをそのままにしておくことも試みました。次に、PHP スクリプトによってすべての処理が完了したら、複製を変更されたオブジェクトと再帰的に比較し、変更されたプロパティをオブジェクト キャッシュに送信します。

ただし、これを使用するには、オブジェクト全体をダウンロードする必要があります。また、オブジェクトは複製されるため、2 倍のメモリを消費する必要があります。


これはかなりあいまいですが、かなりのコードが含まれています。誰かがコードを見たい場合は、投稿するか、開いている SVN リポジトリに投稿できます。このプロジェクトはオープン ソースですが、まだパブリック リポジトリをセットアップしていません。

4

2 に答える 2

1

正直なところ、私はあなたがしていることを再考します。あなたは本当にPHPをそうではないものに変えようとしています。これは、PHP ではなく Java や C# で見られる種類の ORM であり、基本的に一時的な性質のものです (つまり、memcache/APC/etc を除くすべてが要求ごとに再作成されます)。これは、洗練されたオブジェクト キャッシングと変更追跡にとって忌み嫌われます。

そうは言っても、これを行う唯一の方法は、すべてをオーバーロードし__get()、実装するものでラップすることです。__set()__isset()ArrayAccess

于 2009-08-14T00:34:06.917 に答える
1

「オブジェクト」は実際には配列であるため、機能を追加することはできません。クラスメソッドでカプセル化するというあなたの考えは正しいアプローチです。この段階で適切な設計よりもパフォーマンスを心配することは適切ではなく、見当違いです。このアプローチで発生するオーバーヘッドは、アプリケーション全体のパフォーマンスにとって重要ではない可能性があります。

ArrayObjectなどの SPL 配列クラスを調べる必要があります。それらは完全な配列のようなインターフェイスを提供し、簡単に拡張できます。

于 2009-08-14T00:35:51.027 に答える