PHP의 pdostatement :: fetchObject () 메소드를 사용할 때는 일반적으로 데이터베이스 쿼리 결과를 객체에 직접 맵핑 할 수 있습니다. 그러나 때로는 특정 특수 요구 (예 : 참조 문제 방지)로 인해 직접 맵핑되는 단일 인스턴스 객체 대신 객체 사본을 가져 오려고합니다. 이 기사는 깊은 복제 기술을 달성하기위한 간단하고 효율적인 방법을 소개합니다.
정상적인 상황에서 FetchObject ()는 쿼리 라인의 새 객체를 반환하지만 객체에 내부에 참조 속성이 포함되어 있거나 객체 사본이 다른 논리를 통해 캐시 된 경우 데이터 누출 또는 수정 충돌로 이어질 수 있습니다.
예를 들어:
$stmt = $pdo->query('SELECT id, name FROM users');
$user = $stmt->fetchObject(User::class);
// 후속 조치 $user 수정은 다른 논리에 영향을 줄 수 있습니다
$user->name = 'New Name';
이 부작용을 피하기 위해, 우리는 우리가 얻는 객체가 매번 독립적이고 관련이 없으며 내부 속성을 참조하더라도 올바르게 연결을 끊을 수 있기를 바랍니다.
PHP에서 깊은 복제를 구현하는 가장 직접적인 방법은 객체를 직렬화 하고 실질화하는 것 입니다. 예는 다음과 같습니다.
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 () 에서 깊은 복제를 구현하는 가장 좋은 요령은 각 객체가 서로 방해하지 않도록 직렬화를 결합하는 것입니다. 성능 및 객체 구조 제한에주의를 기울여야하지만,이 방법은 대부분의 중소 규모 프로젝트에서 간단하고 효율적이며 매우 실용적입니다.
더 이상 최적화하려면 반사를 기반으로 사용자 정의 복제 전략을 탐색 할 수도 있지만 또 다른 주제입니다!