데이터베이스 개발에 PHP를 사용할 때 Pdostatement :: FetchObject는 쿼리 결과를 객체에 직접 매핑 할 수있는 매우 실용적인 방법입니다. 그러나 PHP 5 및 PHP 7에서는 FetchObject 의 행동에 미묘하지만 중요한 차이가 있습니다. 이러한 호환성 문제를 이해할 수 없으면 다른 버전의 코드에서 예상치 못한 오류가 발생할 수 있습니다.
이 기사에서는 이러한 차이점을 깊이 설명하고 이해하는 데 도움이되는 실제 코드 예제를 제공합니다.
pdostatement의 기본 사용 :: FetchObject는 결과 세트에서 객체로 행을 가져 오는 것입니다.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT id, name FROM users');
$user = $stmt->fetchObject();
echo $user->id;
echo $user->name;
?>
기본 반환은 STDClass 객체입니다. 물론 데이터를 수신 할 사용자 정의 클래스 이름을 지정할 수도 있습니다.
PHP 5 : 객체가 인스턴스화 된 후 속성이 할당 된 후 생성자 (__construct)가 호출됩니다.
PHP 7 : 객체가 인스턴스화되면 속성이 할당되기 전에 생성자가 먼저 호출됩니다 .
이로 인해 중요한 문제가 발생합니다. 생성자가 특정 필드 초기화에 의존하면 PHP 5 및 PHP 7에서 완전히 다르게 행동 할 수 있습니다.
간단한 수업이 있다고 가정합니다.
<?php
class User {
public $id;
public $name;
public function __construct() {
echo "생성자가 호출됩니다:id = {$this->id}, name = {$this->name}\n";
}
}
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT id, name FROM users LIMIT 1');
$user = $stmt->fetchObject('User');
?>
PHP 5 에서는 출력이 다음과 같습니다.
생성자가 호출됩니다:id = 1, name = John
PHP 7 에서는 출력이 다음과 같습니다.
생성자가 호출됩니다:id = , name =
PHP 7은 속성 할당 전에 생성자를 호출하기 때문입니다!
PHP 5 및 7에서 FetchObject 방법의 서명은 약간 다릅니다.
fetchObject ([ string $class_name = "stdClass" [, array $ctor_args = array() ]] ) : object
PHP 5 : $ class_name 및 $ ctor_args를 지원합니다
PHP 7 : 또한 $ class_name 및 $ ctor_args 도 지원하지만 PHP 7.2 이후 매개 변수 유형 확인이 더 엄격합니다. 예를 들어 $ ctor_args는 배열이어야합니다.
PHP 7에서 두 번째 매개 변수로 비 어선을 통과하면 TypeError 오류에 직접 문의합니다.
<?php
// 오류 데모(PHP 7.2+ 오류를보고합니다)
$user = $stmt->fetchObject('User', '잘못된ctor_args');
?>
글을 쓰는 올바른 방법은 다음과 같습니다.
<?php
$user = $stmt->fetchObject('User', ['매개 변수1', '매개 변수2']);
?>
PHP 5 : 지정된 $ class_name이 존재하지 않으면 FetchObject는 False를 반환합니다.
PHP 7 : 지정된 $ class_name이 존재하지 않으면 오류 예외가 직접 던져집니다!
따라서 PHP 7에서는 $ class_name 이 올바르게로드되도록해야합니다. 그렇지 않으면 코드가 중단됩니다.
안전한 접근 방식은 다음과 같습니다.
<?php
$className = 'User';
if (class_exists($className)) {
$user = $stmt->fetchObject($className);
} else {
throw new Exception("친절한 {$className} 존재하지 않습니다");
}
?>
클래스 생성자의 데이터베이스 필드에 의존하는 경우 PHP 7의 초기화 로직을 다시 방문하여 아직 생성자에 할당되지 않은 속성을 직접 사용하지 않도록하십시오.
배열이 $ ctor_args 로 전달 된 배열이 항상 PHP 7.2 이후 유형 오류를 방지하기위한 배열인지 확인하십시오.
FetchObject를 호출하기 전에 Class_Exists를 사용하여 클래스가 존재하는지 여부를 확인하십시오.
PHP 5 및 PHP 7과 호환 해야하는 경우 간단한 STDClass를 균일하게 사용하고 필요한 객체에 수동으로 할당하는 것이 좋습니다.