2010-05-04 14 views
0

Je veux créer une sorte de DataMapper bibliothèque, où vous feriez quelque chose comme ceci:Y at-il une raison pour laquelle je ne devrais pas faire des appels de base de données à partir du destructeur?

$users = Users::getTable(); 
$users->add($newUser1); 
$users->add($newUser2); 

maintenant $users contient 2 enregistrements d'utilisateurs, mais ils ne sont pas encore à la base de données persistaient. Pour être efficace, je voudrais les débusquer tous en même temps. Je voudrais avoir une méthode flush() pour ce faire (pas un problème), mais j'aimerais aussi que cela se produise implicitement lorsque la référence de la table $users tombe hors de la portée. Y a-t-il une raison pour laquelle je ne devrais pas faire ça dans le destructeur?

+0

Je voudrais seulement noter que, selon le nombre d'enregistrements ajoutés, cela pourrait prendre une assez longue période de temps. – KevinDTimm

Répondre

2

Je suggérerais une meilleure solution serait de soulever une erreur dans votre destructeur si la méthode flush() n'a pas été explicitement appelée.

Dans ce cas, il est probablement préférable d'être explicite et d'élever une erreur dans le destructeur assure que vous avez certainement appelé flush() (ou "rollback" ou peu importe comment vous l'appelez). En soulevant une erreur, vous obtenez également une notification en face-à-face que quelque chose s'est mal passé, alors que si vous ne faites rien, vous ne le remarquerez peut-être pas.

1

Qui garantit que votre base de données est disponible lorsque votre destructeur est appelé?

Les garbage collectors ne garantissent généralement pas l'ordre d'exécution des destructeurs dans les graphiques d'objets, vous ne pouvez donc même pas vous fier à des références externes. Une base de données est encore pire. OK, php utilise le comptage de référence au lieu d'un GC générationnel, mais il est toujours mauvais d'avoir des effets secondaires dans les destructeurs.

Qu'y a-t-il de mal à appeler explicitement flush? Peut-être que les utilisateurs de votre bibliothèque veulent simplement laisser certains changements s'évaporer.

+0

Je ne sais pas si je suis, mais la table aurait une référence à la connexion db qui garantirait sa disponibilité. – ryeguy

+0

Les destructeurs PHP sont quelque peu déterministes (en ce sens qu'ils sont appelés dès que la dernière référence est hors champ). Au moins, c'est ma compréhension ... –

+0

Non, ce n'est pas le cas. Le garbage collector a peut-être détruit la connexion db, donc votre référence n'est pas valide au moment du destructeur. Que se passe-t-il si votre appel de base de données déclenche une exception à quelque fin que ce soit? Il pourrait planter votre serveur Web. –

1

Il n'existe aucune garantie que l'ordre d'arrêt de l'interpréteur PHP actuel ne changera pas, et vos handles de base de données pourraient être détruits avant d'être appelés. (C'est pourquoi il est non documenté btw ..)