2009-08-14 9 views
2

PHP変数に対するすべての変更を追跡しようとしています。変数はオブジェクトまたは配列です。このオブジェクトは、オブジェクト・キャッシュを使用してストレージに永続化されPHPオブジェクトのプロパティの変更を追跡する

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

は、例えば、それは何かのように見えます。 PHPスクリプトが再び実行されるとき。

したがって、スクリプトが2回目に実行されたり、別のスクリプトが実行されてそのオブジェクトが変更された場合、それらの変更は、実行中、またはスクリプトの実行後に追跡する必要があります。

例:

$object[] = 'c'; 

私は、 'C' がオブジェクトに追加されたことを知っていただきたいと思います。

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

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

第二の負荷:

$storage = new Storage(); 

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

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

私が知りたいことは、 'C' の中のSO> $ storage-にオブジェクトを押されたということですクラス "ストレージ"私は永続的なストレージにその値を設定することができます。

私はいくつかの方法を試しましたが、それは機能しますが、欠点があります。

1)オブジェクトへの変更を追跡する「格納可能」クラス内のすべてのオブジェクトをラップ

「格納可能」クラスは単にプロパティとして実際のデータオブジェクトを保存し、次いで__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)とすることができる(これは実際にオブジェクト・キャッシュ内に格納されたオブジェクトと同期プログラム内のオブジェクトを維持する最も簡単な方法であるトラッキング変更忘れ、とだけオブジェクト全体構造を

を更新別のマシンで)。

しかし、インデックスが1000個の配列のような構造全体が、単一のインデックスが変更されたときにオブジェクトキャッシュへのソケットを通して送信されなければならないことを意味します。

3)オブジェクトのクローンを作成し、手つかずのクローンオブジェクトを保持し、オブジェクトのミラーをローカルに

私も試してみたください。そして、すべての処理がPHPスクリプトで完了したら、クローンと変更されたオブジェクトを再帰的に比較し、変更されたプロパティをオブジェクトキャッシュに戻して返します。

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


これはかなり曖昧ですが、かなりのコードが含まれています。誰かがコードを見たいと思ったら、私はそれを投稿したり、公開SVNリポジトリに載せることができます。プロジェクトはオープンソースですが、私は公開リポジトリをまだ設定していません。

答えて

1

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

ArrayObjectなどのSPL配列クラスを調べる必要があります。完全なアレイ状のインターフェースを提供し、容易に拡張できます。

+0

ありがとうございます。私がオーバーヘッドを言ったとき、私はコード・ライティングの量を意味し、パフォーマンスは意味しません。私はそれが間違っていると思う、私はちょうど私がしなければならない仕事を最小限に抑えようとしている怠惰なプログラマーです。私はアレイのインターフェイスが行く方法だろうと思います。 – bucabay

+0

@bucabay、仕事をするためのコード量を最小限に抑えようとすると何も問題はありません;-) –

1

すべての正直なところで私はあなたがしていることを再考するでしょう。あなたは本当にPHPをそうでないものに変えようとしています。これはJavaやC#で見られるORMのようなもので、基本的に一時的なものです(memcache/APC/etcを除くすべての意味で、リクエストごとに再作成されます)。これは、洗練されたオブジェクトキャッシングと変更トラッキングには困ります。言われていること

、あなたがこれを行うことができる唯一の方法は、__get()__set()__isset()をオーバーロードしてArrayAccessを実装して何かのすべてを包んであります。

+0

これは実際にmemcacheとAPCを含むオブジェクトキャッシュへのインタフェースです。私はPHPの一時的な性質がここで利益であると信じています。 – bucabay

+0

ArrayAccessを実装すると、array_pop()などのすべてのArray関数を使用できますか? – bucabay

+0

__getと__setの場合は+1 – Josh