PHPのpdostatement :: fetchObject()メソッドを使用する場合、通常、データベースクエリの結果を直接オブジェクトにマップすることができます。ただし、特定の特別なニーズ(参照の問題の防止など)のために、直接マッピングされた単一のインスタンスオブジェクトの代わりに、オブジェクトのコピーを取得する必要があります。この記事では、深い複製スキルを実現するためのシンプルで効率的な方法を紹介します。
通常の状況では、 fetchObject()はクエリ行の新しいオブジェクトを返しますが、オブジェクトに内部の参照属性が含まれている場合、またはオブジェクトコピーが他のロジックを使用してキャッシュされている場合、データの漏れまたは変更の競合につながる可能性があります。
例えば:
$stmt = $pdo->query('SELECT id, name FROM users');
$user = $stmt->fetchObject(User::class);
// フォローアップ $user 変更は、他のロジックに影響を与える可能性があります
$user->name = 'New Name';
この副作用を回避するために、私たちが得るオブジェクトが毎回独立していて無関係であり、内部属性が参照されていても正しく切断できることを願っています。
PHPに深い複製を実装する最も直接的な方法は、オブジェクトをシリアル化して脱izeすることです。例は次のとおりです。
function deepCopy($object) {
return unserialize(serialize($object));
}
このディープコピー関数により、オブジェクトとその内部プロパティが完全にコピーされ、参照が共有されなくなることが保証されます。
fetchObject()の使用プロセスをわずかにラップすることができます。そのため、各オブジェクトが取得された後、深いコピーがすぐに実行されます。
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));
}
}
この例では、 DeepCopy()を使用してデータベースから取得したオブジェクトをラップし、 $ユーザー配列の各要素が独立したコピーであることを確認します。
シリアル化決定方法はシンプルで使いやすいですが、注意すべき点がいくつかあります。
パフォーマンスオーバーヘッド:シリアル化されたディープレプリケーションは、特に大量のデータを処理する場合、影響を評価する必要があります。
オブジェクトの制限:オブジェクトにリソースハンドル(データベース接続、ファイルポインターなどなど、シリアル化できない場合、シリアル化が失敗します。
カスタムコピー:オブジェクトが複雑な場合は、 __clone()メソッドを実装して手動でコピーするロジックを実装することを検討できます。
プロジェクトのオブジェクトをコピーする必要がある場合は、ツールクラスをカプセル化できます。
class ObjectHelper
{
public static function deepCopy(object $object): object
{
return unserialize(serialize($object));
}
}
その後、呼び出すときは明確になります:
$copy = ObjectHelper::deepCopy($user);
興味がある場合は、このツールを作曲家パッケージとして公開し、https: //gitbox.net/your-username/object-helperなどの独自のプライベートリポジトリにアップロードすることもできます。
pdostatement :: fetchObject()に深い複製を実装する最良のトリックは、シリアル化を組み合わせて、各オブジェクトが互いに干渉しないようにすることです。パフォーマンスとオブジェクトの構造の制限に注意を払う必要がありますが、この方法は、ほとんどの中小プロジェクトでシンプルで効率的で非常に実用的です。
さらに最適化したい場合は、リフレクションに基づいてカスタムレプリケーション戦略を探索することもできますが、それは別のトピックです!