Lorsque vous utilisez la méthode PDOSTATION :: FetchObject () de PHP, nous pouvons généralement cartographier facilement les résultats de la requête de la base de données directement dans les objets. Cependant, parfois en raison de certains besoins spéciaux (comme la prévention des problèmes de référence), nous voulons obtenir une copie de l'objet au lieu d'un seul objet d'instance qui est directement mappé. Cet article introduira une méthode simple et efficace pour acquérir des compétences de réplication profondes.
Dans des circonstances normales, FetchObject () renvoie un nouvel objet de la ligne de requête, mais si l'objet contient des attributs de référence à l'intérieur, ou si la copie de l'objet est mise en cache via une autre logique, elle peut entraîner des fuites de données ou des conflits de modification.
Par exemple:
$stmt = $pdo->query('SELECT id, name FROM users');
$user = $stmt->fetchObject(User::class);
// Suivi $user Les modifications peuvent affecter une autre logique
$user->name = 'New Name';
Pour éviter cet effet secondaire, nous espérons que l'objet que nous obtenons sera indépendant et non pertinent à chaque fois, et pourra être correctement déconnecté même si les attributs internes sont référencés.
Le moyen le plus direct d'implémenter une réplication profonde dans PHP est de sérialiser et de désérialiser les objets. Les exemples sont les suivants:
function deepCopy($object) {
return unserialize(serialize($object));
}
Cette fonction DeepCopy garantit que l'objet et ses propriétés internes sont complètement copiées et ne sont plus partagées de références.
Nous pouvons légèrement envelopper le processus d'utilisation de fetchObject () afin qu'après que chaque objet soit récupéré, une copie profonde est effectuée immédiatement:
class UserRepository
{
protected PDO $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function findAllUsers(): array
{
$stmt = $this->pdo->query('SELECT id, name, profile FROM users');
$users = [];
while ($user = $stmt->fetchObject(User::class)) {
$users[] = $this->deepCopy($user);
}
return $users;
}
protected function deepCopy(object $object): object
{
return unserialize(serialize($object));
}
}
Dans cet exemple, nous utilisons DeepCopy () pour envelopper l'objet extrait de la base de données, garantissant que chaque élément du tableau des utilisateurs $ est une copie indépendante.
Bien que la méthode de désérialisation de sérialisation soit simple et facile à utiliser, il existe plusieurs points à noter:
Performance Overhead : La réplication profonde sérialisée a un certain impact sur les performances, en particulier lors du traitement de grandes quantités de données, l'impact doit être évalué.
Restrictions d'objet : Si l'objet contient des poignées de ressources (telles que les connexions de base de données, les pointeurs de fichiers, etc., qui ne sont pas sérialisables, alors la sérialisation échouera.
Copie personnalisée : si l'objet est complexe, vous pouvez envisager d'implémenter la méthode __clone () pour une logique de copie manuellement profonde.
Si vous avez souvent besoin de copier des objets dans votre projet, vous pouvez encapsuler une classe d'outils:
class ObjectHelper
{
public static function deepCopy(object $object): object
{
return unserialize(serialize($object));
}
}
Ensuite, il est plus clair lorsque vous appelez:
$copy = ObjectHelper::deepCopy($user);
Si vous êtes intéressé, vous pouvez également publier cet outil en tant que package compositeur et le télécharger dans votre propre référentiel privé, tels que https://gitbox.net/your-username/object-helper , ce qui est pratique pour la réutilisation dans plusieurs projets.
La meilleure astuce pour mettre en œuvre une réplication profonde dans Pdostatement :: fetchObject () consiste à combiner la sérialisation pour s'assurer que chaque objet n'interfère pas les uns avec les autres. Bien qu'il soit nécessaire de prêter attention aux limitations des performances et de la structure des objets, cette méthode est simple, efficace et très pratique dans la plupart des projets de petite et moyenne taille.
Si vous souhaitez optimiser davantage, vous pouvez également explorer des stratégies de réplication personnalisées basées sur la réflexion, mais c'est un autre sujet!
Étiquettes associées:
PDOStatement