2009-08-14 9 views
2

J'essaie de suivre toutes les modifications apportées à une variable PHP. La variable peut être un objet ou un tableau.Suivi des modifications des propriétés de l'objet PHP

Par exemple, il ressemble à quelque chose comme:

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

Cet objet est ensuite persisté au stockage en utilisant un cache d'objets. Lorsque le script php s'exécute à nouveau. Par conséquent, lorsque le script s'exécute pour la deuxième fois ou qu'un autre script exécute et modifie cet objet, je souhaite que ces modifications soient suivies, soit en cours, soit en une fois après l'exécution du script.

par exemple:

$object[] = 'c'; 

Je voudrais savoir que 'c' a été ajouté à l'objet.

Maintenant, le code fait ressemble à quelque chose comme ceci:

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

deuxième charge:

$storage = new Storage(); 

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

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

Ce que je veux savoir est que 'c' a été poussé dans l'objet $ Stockage-> donc en la classe "Stockage" Je peux définir cette valeur pour le stockage persistant.

J'ai essayé quelques méthodes qui fonctionnent, mais qui ont des inconvénients.

1) Enveloppez tous les objets dans une classe « stockable » qui suit les modifications à l'objet

La classe « stockable » sauve tout l'objet de données réelles comme une propriété, et fournit ensuite __get() et __set() méthodes pour y accéder. Lorsqu'un membre/propriété de l'objet est modifié ou ajouté, la classe "Storable" le note. Lorsqu'une propriété est accédée __get() sur la classe Storable renvoie la propriété, enveloppée dans une autre classe Storable de sorte que les modifications sur ce sont également suivies, récursivement pour chaque nouveau niveau.

Le problème est que les objets ne sont plus des types de données natifs et que vous ne pouvez donc pas exécuter les fonctions de tableau sur les tableaux.

par exemple:

$storage = new Storage(); 

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

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

Ainsi, au lieu que nous aurions à mettre en œuvre ces fonctions de tableau comme méthodes de stockable.

par exemple:

$storage = new Storage(); 

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

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

Tout cela est bien, mais je voudrais savoir s'il est possible d'utiliser les fonctions natives d'une certaine manière, de réduire les frais généraux de la bibliothèque que je développe, tout le suivi des changements afin tout changement peut être ajouté au stockage persistant.

2) Oubliez le suivi des modifications, et simplement mettre à jour des structures entières d'objets

Ceci est la méthode la plus simple de garder les objets dans le programme synchronisé avec les objets effectivement stockés dans le cache d'objet (qui peut être sur une machine différente).Cependant, cela signifie que des structures entières, comme un tableau avec 1000 index, doivent être envoyées via un socket au cache d'objets lorsqu'un seul index change.

3) Gardez un miroir de l'objet localement

J'ai aussi clonage essayé l'objet, et de garder un objet clone intact. Ensuite, lorsque tout le traitement est effectué par le script PHP, comparez le clone à l'objet modifié de manière récursive et soumettez les propriétés modifiées à l'objet-cache.

Cela nécessite cependant que l'objet entier soit téléchargé pour pouvoir l'utiliser. Il faut aussi que l'objet occupe deux fois plus de mémoire, puisqu'il est cloné. Je sais que c'est assez vague, mais il y a pas mal de code en cause. Si quelqu'un veut voir le code, je peux le poster, ou le mettre sur un dépôt SVN ouvert. Le projet est open source mais je n'ai pas encore mis en place de référentiel public.

Répondre

1

Puisque votre 'objet' est vraiment un tableau, vous ne pouvez pas y ajouter de fonctionnalité. Votre idée de l'encapsuler avec des méthodes de classe est la bonne approche. S'inquiéter des performances par rapport à une conception correcte à ce stade est sans importance et mal orienté - les frais généraux que vous encourez avec cette approche seront probablement insignifiants pour la performance globale de votre application.

Vous devriez regarder dans les classes de matrice SPL telles que ArrayObject. Ils fournissent une interface de type tableau complète et sont facilement extensibles.

+0

Merci. Quand j'ai dit overhead, je voulais dire la quantité de code écrit et non la performance. Je suppose que c'est aussi malavisé, je suis juste un programmeur paresseux essayant de faire le moins de travail possible. Je suppose que les interfaces de tableau seraient le chemin à parcourir. – bucabay

+0

@bucabay, rien de mal à essayer d'écrire le moins de code pour faire le travail ;-) –

1

En toute honnêteté, je voudrais reconsidérer ce que vous faites. Vous essayez vraiment de transformer PHP en quelque chose que ce n'est pas. C'est le type d'ORM que vous voyez en Java et C# pas PHP, qui est fondamentalement transitoire dans la nature (ce qui signifie que tout, sauf memcache/APC/etc, est recréé à chaque requête). Ceci est un anathème à la mise en cache sophistiquée des objets et au suivi des modifications.

Cela étant dit, la seule façon que vous pouvez faire est tout envelopper dans quelque chose qui surchargent __get(), __set() et __isset() et met en œuvre ArrayAccess.

+0

Il s'agit en fait d'une interface avec les caches d'objets, y compris memcache et APC. Je crois que la nature transitoire de PHP est un avantage ici. – bucabay

+0

L'implémentation de ArrayAccess permettrait-elle d'utiliser toutes les fonctions de tableau, par exemple: array_pop()? – bucabay

+0

+1 pour __get et __set – Josh

Questions connexes