다른 데이터베이스 확장과 마찬가지로 PDO는 선택한 데이터에서 직접 기존 클래스의 인스턴스를 생성할 수 있습니다. 그러나 다른 확장과 달리 PDO는 강력하고 유연한 개체 조작을 위한 많은 기능을 제공합니다.
단일 객체 가져오기
쿼리 결과에서 단일 객체를 생성하려면 두 가지 방법이 있습니다.
1. 친숙한 fetch() 메소드를 사용하세요:
class User {}; $stmt = $pdo->query('SELECT name FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS, 'User'); $user = $stmt->fetch();
2. 전용 fetchObject() 메소드:
class User {}; $user = $pdo->query('SELECT name FROM users LIMIT 1')->fetchObject('User');
두 코드 조각 모두 동일한 User 클래스 인스턴스를 제공하지만
/* object(User)#3 (1) { ["name"] => string(4) "John" } */
후자 메소드는 확실히 더 깨끗해 보입니다. 또한 fetch() 메서드를 사용했지만 클래스가 해당 이름으로 정의되지 않은 경우 배열이 자동으로 반환되는 반면 fetchObject()를 사용하면 적절한 오류가 발생합니다.
객체 배열 가져오기
물론 위에서 설명한 두 가지 방법 모두 익숙한 while 문과 함께 사용하여 데이터베이스에서 결과 행을 가져올 수 있습니다.
편리한 fetchAll() 메소드를 사용하여 객체 배열의 반환된 모든 레코드를 한 번에 가져옵니다.
class User {}; $users = $pdo->query('SELECT name FROM users')->fetchAll(PDO::FETCH_CLASS, 'User');
는 속성을 채우는 반환된 데이터와 함께 User 클래스의 객체로 구성된 배열을 제공합니다.
/* array(2) { [0]=> object(User)#3 (1) { ["name"] => string(4) "John" } [1]=> object(User)#4 (1) { ["name"]=> string(4) "Mike" } } */
참고 이 패턴을 PDO::FETCH_UNIQUE 및 PDO::FETCH_GROUP과 결합하여 고유 필드로 색인화된 결과 배열을 얻거나 고유하지 않은 필드를 사용하여 별도로 결과를 그룹화할 수 있습니다.
예를 들어 아래 코드는 연속된 숫자 대신 레코드 ID가 배열 인덱스로 사용되는 배열을 반환합니다.
class User {}; $stmt = $pdo->query('SELECT id, id, name, car FROM users'); $users = ->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_UNIQUE, 'User');
클래스 속성 할당
어떤 방법을 선택하든 쿼리에서 반환된 모든 열은 다음 규칙에 따라 해당 클래스 속성에 할당됩니다.
1. 이름이 열과 동일합니다. 이름이 동일하면 열 값이
2 속성에 할당됩니다. 해당 속성이 없으면 __set() 매직 메서드가 호출됩니다
3. 클래스에 정의된 __set() 메서드가 없으면 공용 속성이 생성되고 열 값이 할당됩니다.
예를 들어, 이 코드
class User { public $name; } $user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User');
는 클래스에 존재하는지 여부에 관계없이 모든 속성이 자동으로 할당된 객체를 제공합니다.
/* object(User)#3 (4) { ["id"] => string(3) "104" ["name"] => string(4) "John" ["sex"] => string(4) "male" ["car"] => string(6) "Toyota" } */
여기에서 볼 수 있듯이 속성 자동 생성을 방지하려면 다음을 사용할 수 있습니다. 매직 메소드 __set()은 속성을 필터링합니다. 가장 간단한 필터링 기술은 빈 __set() 메서드입니다. 이를 사용하면 기존 속성만 설정됩니다.
class User { private $name; public function __set($name, $value) {} } $user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User'); /* array(1) { [0]=> object(User)#3 (1) { ["name":"User":private]=> string(4) "John" } } */
위와 같이 PDO는 개인 속성에 값을 할당할 수도 있습니다.
객체에 생성자 매개변수 전달
물론 새로 생성된 객체의 경우 생성자 매개변수를 제공해야 할 수도 있습니다. 이를 위해 fetchObject() 및 fetchAll() 메서드에는 생성자 매개변수를 배열 형식으로 전달하는 데 사용할 수 있는 전용 매개변수가 있습니다.
다음 변수를 제공하여 생성자에서 설정할 수 있는 자동차 속성이 있는 User 클래스가 있다고 가정합니다.
class User { public function __construct($car) { $this->car = $car; } }
레코드를 가져오는 동안 생성자 매개변수가 있는 배열을 추가해야 합니다.
$users = $pdo->query('SELECT name FROM users LIMIT 1') ->fetchAll(PDO::FETCH_CLASS, 'User', ['Caterpillar']); $user = $pdo->query('SELECT name FROM users LIMIT 1') ->fetchObject('User',['Caterpillar']);
/* object(User)#3 (2) { ["name"] => string(4) "John" ["car"] => string(11) "Caterpillar" } */
좋아요, 값을 보세요 기본적으로 PDO는 생성자를 호출하기 전에 클래스 속성을 할당하기 때문에 데이터베이스에서 덮어쓰여집니다. 이는 문제가 될 수 있지만 쉽게 해결됩니다.
생성자 호출 후 클래스 속성 설정
mysql_fetch_object() 참고:
mysql_fetch_object를 사용하고 클래스를 지정하는 경우 속성은 생성자 Set에 있습니다. 함수 실행 전. 이는 일반적으로 문제가 되지 않지만, 속성이 __set() 매직 메서드를 통해 설정된 경우 생성자 논리를 먼저 수행해야 합니다. 그렇지 않으면 몇 가지 심각한 문제가 발생할 수 있습니다.
안타깝게도 mysql은 mysqli 확장이지만 우리는 PDO를 사용하고 있습니다. 그렇다면 생성자가 실행된 후 속성을 할당하도록 PDO에 지시하는 방법이 있습니까? 이를 위해서는 PDO::FETCH_PROPS_LATE 상수를 사용해야 합니다.
fetchAll()을 사용하는 것은 매우 간단합니다.
class User { public function __construct($car) { $this->car = $car; } } $stmt = $pdo->query('SELECT name, car FROM users LIMIT 1'); $users = $stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']);
단일 행을 가져올 때 setFetchMode()와 fetchObject()를 동시에 호출해야 하는데 이는 다소 불편할 수 있습니다.
class User { public function __construct($car) { $this->car = $car; } } $stmt = $pdo->query('SELECT name, car FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User'); $user = $stmt->fetchObject('User', ['Caterpillar']); /* object(User)#3 (2) { ["car"] => string(6) "Toyota" ["name"] => string(4) "John" } */
위 코드는 클래스 이름을 두 번 써야 하기 때문에 그다지 효율적이지 않습니다.
또는 fetch():
$stmt = $pdo->query('SELECT name, car FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']); $user = $stmt->fetch();
를 사용할 수도 있습니다. 하지만 위에서 언급한 것처럼 클래스가 정의되지 않은 경우 오류 메시지를 처리하는 데 도움이 되지 않습니다.
데이터베이스에서 클래스 이름 가져오기
PDO에게 첫 번째 열의 값에서 클래스 이름을 가져오도록 지시하는 더 흥미로운 플래그도 있습니다. 이 플래그를 사용하면 setFetchMode() 및 fetch() 사용을 피할 수 있습니다.
$data = $pdo->query("SELECT 'User', name FROM users") ->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE); /* object(User)#3 (1) { ["name"]=> string(4) "John" } */
또한 이 패턴은 동일한 쿼리에서 서로 다른 클래스의 객체를 생성할 수 있는 경우 매우 유용합니다.
class Male {}; class Female {}; $stmt = $pdo->query('SELECT sex, name FROM users'); $users = $stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE); /* array(6) { [0]=> object(Male)#3 (1) { ["name"]=> string(4) "John" } [1]=> object(Male)#4 (1) { ["name"]=> string(4) "Mike" } [2]=> object(Female)#5 (1) { ["name"]=> string(4) "Mary" } [3]=> object(Female)#6 (1) { ["name"]=> string(5) "Kathy" } }*/
그러나 이 패턴을 사용할 때는 , 클래스 생성자에서 매개변수를 전달하는 것이 불가능해 보입니다.
기존 개체 업데이트
除了创建新对象,PDO还可以更新现有对象。只使用setFetchMode(),它将现有变量作为参数。显然,使用fetchAll()是无用的。
class User { public $name; public $state; public function __construct() { $this->name = NULL; } } $user = new User; $user->state = "up'n'running"; var_dump($user); $stmt = $pdo->query('SELECT name FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_INTO, $user); $data = $stmt->fetch(); var_dump($data, $user); /* object(Foo)#2 (2) { ["name"] => NULL ["state"] => string(12) "up'n'running" } object(Foo)#2 (2) { ["name"] => string(4) "John" ["state"] => string(12) "up'n'running" } object(Foo)#2 (2) { ["name"] => string(4) "John" ["state"] => string(12) "up'n'running" } */
如上,fetch()调用返回的是相同的对象,这在我看来是多余的。还要注意,与PDO::FETCH_CLASS不同,这种模式不分配私有属性。
위 내용은 PDO 객체를 얻고 속성을 설정하는 방법은 무엇입니까? (자세한 코드 설명)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!