데이터베이스 작업에 PDO를 사용해야 하는 이유 PHP PDO - 데이터베이스를 올바르게 사용하기 Php 요청 삭제 PDO 예




얼마 전 나는 PHP PDO를 다루기로 결정했습니다. 새로운 기술을 배우는 것은 흥미롭고 필요합니다. 러시아어 문서를 어디에서도 찾을 수 없어서 게시하기로 결정했습니다. 이 기사가 당신에게 흥미로울 것이기를 바랍니다.

소개

먼저 PHP 언어로 데이터베이스에 액세스하기 위한 경량 인터페이스인 PDO(PHP Data Objects)부터 시작해 보겠습니다. MS SQL, Firebird, MySQL, Oracle, PostgreSQL, SQLite 등과 같은 대부분의 데이터베이스에서 작동할 수 있습니다. 그러나 여기서는 PDO가 데이터베이스 작업에 필요한 기능을 제공한다는 점에 주의할 필요가 있습니다. 그러나 각 데이터베이스 유형에 대해 자체 데이터베이스 액세스 드라이버를 PHP 확장 형식으로 설치해야 합니다.

PDO를 사용하면 데이터베이스 유형과 완전히 독립적인 애플리케이션을 생성할 수 있으면서도 준비된 명령문이나 트랜잭션 생성과 같은 대부분의 데이터베이스 기능을 계속 사용할 수 있습니다. 이 기능이 데이터베이스에서 지원되지 않는 경우 PDO는 자체 수단을 사용하여 이 기능을 에뮬레이트하므로 어떤 방식으로든 프로그램 논리를 위반하지 않습니다.

연결하는 데이터베이스 유형, 호스트 이름 및 데이터베이스 이름을 한 줄에 즉시 표시해야 한다는 점을 제외하면 연결은 매우 간단합니다.

형식은 다음과 같습니다.

데이터베이스_유형:호스트=호스트 이름;db=이름

예제를 살펴보겠습니다. 하지만 PDO 라이브러리의 예외(PDOException)를 사용하여 예제를 조금 복잡하게 만들어 보겠습니다. 따라서 데이터베이스 연결에 실패하는 경우 우리는 이에 대한 명확한 메시지를 받게 되며, 아무데도 나온 코드 덩어리가 아닙니다.

try ( $db = new PDO("mysql:host=localhost;dbname=test" , "root" , "" ) ; $rows = $db -> exec ("CREATE TABLE `testing`(id INT PRIMARY KEY AUTO_INCREMENT, fname VARCHAR(20) NOT NULL DEFAULT "", 이메일 VARCHAR(50) NOT NULL DEFAULT "")" ) ; ) catch(PDOException $e ) ( 다이("오류: " . $e -> getMessage () ) ; )

SQL 표현식에 실수가 있는 경우 PDO에는 다음과 같은 특수 기능이 있습니다.

errorCode() – 오류 번호를 반환합니다.

errorInfo() – 오류 번호와 설명 텍스트가 모두 포함된 배열을 반환합니다.

요청은 다음 두 가지 기능을 통해 직접 이루어질 수 있습니다.

exec() 및 쿼리()

차이점은 반환된 결과의 유형에 있으며, exec는 쿼리 결과로 영향을 받은 행 수를 반환하고, 두 번째는 쿼리 결과를 PDOStatement 객체로 반환합니다. 이에 대해 조금 이야기하겠습니다. 나중에.

이제 이러한 함수를 코드에 추가하고 예제를 좀 더 복잡하게 만들어 보겠습니다.

// 구성 시작 부분에 정의("DB_DRIVER" , "mysql" ) ; 정의하다("DB_HOST" , "localhost" ) ; 정의하다("DB_NAME" , "테스트" ) ; 정의하다("DB_USER" , "루트" ) ; 정의하다("DB_PASS" , "" ) ; try ( // 데이터베이스에 연결 $connect_str = DB_DRIVER . ":host=" . DB_HOST . ";dbname=" . DB_NAME; $db = new PDO($connect_str , DB_USER, DB_PASS) ; // 여러 행을 데이터베이스에 삽입 이전 예의 테이블 $rows = $db -> exec ("INSERT INTO `testing` VALUES (null, "Ivan"," [이메일 보호됨]"), (null, "페트르", " [이메일 보호됨]"), (null, "바실리", " [이메일 보호됨]") " ) ; $error_array = $db -> errorInfo () ; 만약 ($db ->
" ; // 요청이 성공하면 // 영향을 받은 행 수를 인쇄합니다. if ($rows ) echo "영향을 받은 행 수: " . $rows ."
" ; // 이제 데이터베이스에서 몇 줄을 선택합니다. $result = $db -> query ("SELECT * FROM `testing` LIMIT 2" ) ; // SQL 표현식에 오류가 있는 경우 오류 메시지를 표시합니다 $ error_array = $db -> errorInfo () ; if ($db -> errorCode () != 0000) echo "SQL 오류: " . $error_array [ 2 ] . "

" ; // 이제 PDOStatement 클래스에서 데이터를 얻습니다. while ($row = $result -> fetch () ) ( // 결과적으로 연관 배열을 얻습니다. print_r($행); ) ) catch(PDOException $e ) ( 죽다("오류: " . $e -> getMessage () ) ; )

준비된 표현

준비된 표현식은 일반 SQL 쿼리와 매우 유사하지만 몇 가지 장점이 있습니다. 첫째, 실행 속도가 더 빠르며, 둘째, 전달된 모든 매개 변수가 모든 종류의 주입으로부터 자동으로 보호되므로 보안 관점에서 더 안정적입니다.

매번 쿼리를 새로 구성하는 것보다 여러 개의 동일한 쿼리를 실행할 때 속도가 크게 향상됩니다. 애플리케이션과 데이터베이스 간의 트래픽도 저장됩니다.

PDO는 준비된 표현식 작업에 편리한 기능을 제공합니다. 선택한 데이터베이스 유형이 준비된 표현식 작업을 지원하지 않는 경우 PDO는 단순히 자체 메서드를 사용하여 작업을 에뮬레이션합니다.

먼저 준비된 표현식을 생성해 보겠습니다. 이는 prepare() 함수에 의해 수행됩니다.

SQL 쿼리를 매개 변수로 사용하지만 그 안에는 변경해야 하는 값 대신 물음표(?) 형태의 의사 변수 또는 의사의 이름이 배치됩니다. 콜론(:)으로 시작하는 변수

$sth1 = $db->prepare(“SELECT * FROM `testing` WHERE id=:id”);

$sth2 = $db->prepare(“SELECT * FROM `testing` WHERE id=?");

변수를 어떻게 정의하느냐에 따라 향후 작업이 달라집니다.

물음표로 변수를 정의한 경우 변수가 나타나는 순서대로 값 배열을 실행 함수에 전달합니다.

이름으로 변수를 지정한 경우 함수를 사용하여 각 변수에 값을 할당해야 합니다.

BindValue() - 의사 변수에 값을 할당합니다.

BindParam() - 의사 변수를 실제 변수에 바인딩하고, 실제 변수가 변경되면 더 이상 추가 함수를 호출할 필요가 없으며 즉시 실행()할 수 있습니다.

다음은 첫 번째 옵션을 사용하는 예입니다.


PDO 객체가 PDOStatement 클래스에서 준비된 표현식을 생성한 후에는 이를 사용하기만 하므로 자체 함수 errorCode, errorInfo 및 쿼리 실행 결과도 즉시 저장됩니다.

이제 두 번째 방법입니다.

의사 변수에 값을 할당하려면 바인딩값() 함수를 사용하세요.

이 코드는 의사 변수를 실제 변수와 연결하여 더욱 간단하게 작성할 수 있습니다.

(불필요한 오류를 피하기 위해) 변수의 유형을 세 번째 매개변수로 나타내는 것이 매우 바람직하다는 점도 덧붙일 필요가 있습니다. 저는 개인적으로 변수 유형이 없을 때 WHERE 문에서 오류가 발생했습니다. WHERE 문에서는 변수를 숫자가 아닌 텍스트로 간주했기 때문입니다.

$sth3->bindParam(':id',$id, PDO::PARAM_INT);

$sth3->bindParam(':id',$id, PDO::PARAM_STR);

이렇게 준비된 표현식을 사용하는 또 다른 아주 좋은 이점은 변수를 이스케이프하는 것입니다. 프로시저로 대체하기 전에 모든 변수가 이스케이프되며 SQL 주입이 무섭지 않습니다.

업무

트랜잭션은 모두 실행되어야 하는 데이터베이스 쿼리의 모음입니다. 요청이 완료되지 않거나 오류가 발생하여 실행되면 트랜잭션이 취소되고 데이터베이스에서 데이터 변경이 발생하지 않습니다.

이는 여러 요청에서 데이터 무결성이 유지되는지 확인하는 데 필요합니다. 예를 들어 계좌에서 계좌로 자금을 이체하는 경우입니다.

PDO에서 거래를 완료하려면 수동 확인 모드로 전환해야 합니다.

그런데 트랜잭션은 항상 사용되지만 일반적으로 PDO는 자동 확인 모드로 작동하므로 모든 트랜잭션은 하나의 요청으로 구성됩니다.

자동 확인 모드를 끄려면 다음 명령을 실행하십시오.

$db->beginTransaction();

그런 다음 이 트랜잭션에서 필요한 만큼 데이터베이스에 대한 쿼리를 실행합니다.

그리고 모든 요청이 완료된 후에만 해당 기능을 통해 거래를 확인할 수 있습니다.

$db->커밋();

아니면 거래를 취소하세요

$db->롤백();

다음은 거래의 작은 예입니다.

try ( $connect_str = DB_DRIVER . ":host=" . DB_HOST . ";dbname=" . DB_NAME; $db = new PDO($connect_str , DB_USER, DB_PASS) ; $rows = $db -> exec ("CREATE TABLE ` 테스트`(id INT PRIMARY KEY AUTO_INCREMENT, fname VARCHAR(20) NOT NULL DEFAULT "", 이메일 VARCHAR(50) NOT NULL DEFAULT "", Money INT NOT NULL DEFAULT 0) ENGINE=InnoDB;" ) ; $rows = $db -> exec("INSERT INTO `testing` VALUES(null, "Ivan", " [이메일 보호됨]", 15000), (null, "페트르", " [이메일 보호됨]", 411000), (null, "바실리", " [이메일 보호됨]", 1500000) " ) ; // Ivan에게서 Peter에게 // 50000의 금액을 이체해 보겠습니다. $summ = 50000 ; $트랜잭션 = true ; $db -> 시작트랜잭션() ; $sth1 = $db -> query ("테스트 WHERE fname="Ivan""에서 자금 선택) ; $sth2 = $db -> query ("테스트 WHERE fname="Petr""에서 자금 선택) ; $row1 = $sth1 -> 가져오기() ; $row2 = $sth2 -> 가져오기() ; if (! $row1 || ! $row2 ) $transaction = false ; $total2 = $summ + $row2 [ "돈" ] ; $total1 = $row1 [ "돈" ] - $summ ; if ($total1< 0 || $total2 < 0) $transaction = false ; $num_rows1 = $db ->exec ( . $total1 . "" WHERE fname="Ivan"" ) ; $num_rows2 = $db -> exec ("UPDATE `testing` SET 돈="" . $total2 . "" WHERE fname="Petr"" ) ; if ($transaction ) ( echo "트랜잭션이 성공적으로 완료되었습니다" ; $db -> commit () ; ) else ( echo "트랜잭션 실패" ; $db -> 롤백 () ; ) ) catch(PDOException $e ) ( 다이("오류: " . $e -> getMessage () ) ; )

또한 모든 테이블 유형이 트랜잭션을 지원하는 것은 아니므로 이 예에서는 표준 MyISAM 테이블 대신 InnoDb 테이블을 사용했습니다.

결론적으로 이 책은 PDO에 대한 완전한 매뉴얼과는 거리가 멀다는 점을 말씀드리고 싶습니다. 언제든지 여기에서 완전한 최신 정보를 얻을 수 있습니다: http://www.php.net/manual/en/book.pdo.php

탐색하고 창조하세요.

오늘 저는 PDO에 관한 일련의 기사를 시작하겠습니다. 이 기사에서는 PDO가 무엇인지, 왜 필요한지, 어떻게 사용하는지 살펴보겠습니다.

확실히 많은 사람들이 이미 PDO라는 약어를 들어봤지만 그것이 무엇인지 아는 사람은 거의 없습니다. 그럼 오늘은 이것에 대해 이야기해 봅시다.

PDO 란 무엇입니까?

PDO(PHP Data Objects)는 단순히 특정 데이터베이스에서 추상화할 수 있게 해주는 인터페이스입니다. 예를 들어 보여주는 것이 가장 좋습니다.

Mysql_connect($host, $user, $pass); // MySQL
mysql_select_db($db);

SQLite_open($db); //sqlite

Pg_connect("호스트=$host, dbname=$db, 사용자=$user, 비밀번호=$pass"); // 포스트그레SQL

위의 코드는 MySQL, sqlite 및 PostgreSQL의 세 가지 데이터베이스에 연결하는 방법을 제공합니다. 보시다시피 각 데이터베이스의 기능은 다릅니다.

다른 행동도 마찬가지다. 예를 들어 데이터베이스에서 데이터를 샘플링합니다.

$sql = "INSERT INTO(이름, 패스) VALUES($name, $pass)";

Mysql_query($sql); // MySQL
sqlite_query($sql); //sqlite
pg_query($sql); // 포스트그레SQL

PDO가 왜 필요한가요?

거대한 PostgreSQL 데이터베이스가 있고 이를 MySQL로 변경하기로 결정했다고 가정해 보겠습니다. 우리는 많은 코드를 다시 작성해야 할 것이며 대부분 오류가 있을 것입니다. 이 문제를 해결하기 위해 특정 데이터베이스에 의존하지 않게 해주는 PDO가 존재합니다.

이제 어떻게 연결할 수 있는지 살펴보겠습니다.

$db = new PDO("mysql:host=$host;dbname=$db", $user, $pass); // MySQL
$db = new PDO("sqlite:host=$host;dbname=$db", $user, $pass); //sqlite
$db = new PDO("pgsql:host=$host;dbname=$db", $user, $pass); // 포스트그레SQL

위의 코드에서 볼 수 있듯이, 이 세 가지 연결에서는 데이터베이스 이름이 있는 줄만 변경되고 나머지는 동일합니다.

무언가를 선택하려면 다음과 같이 작성할 수 있습니다.

$db->exec($sql);

모두! 요청은 우리가 가지고 있는 데이터베이스에 관계없이 실행됩니다.

지원하다

PDO는 PHP 5.1부터 사용할 수 있습니다. 우리가 어떤 데이터베이스를 사용하고 있는지 "잊을" 수 있도록 해당 드라이버가 우리를 위해 모든 작업을 수행합니다. 이를 활성화하려면 php.ini 파일로 이동하여 거기서 Extension=php_pdo_로 시작하는 줄과 데이터베이스 이름을 찾아 주석을 제거하세요.

소개 기사는 이것이 전부이고 다음 기사에서는 PDO를 사용하는 방법을 알아내기 시작할 것입니다.












PDO에는 . 게다가, 연결하는 동안 엄청나게 많은 옵션을 설정할 수 있으며, 그 중 일부는 매우 유용합니다. 전체 목록을 찾을 수 있지만 중요한 것은 몇 가지뿐입니다.

올바른 연결의 예:

$호스트 = "127.0.0.1" ;
$db = "테스트" ;
$user = "루트" ;
$패스 = "" ;
$charset = "utf8" ;

$dsn = "mysql:호스트= $host ;dbname= $db ;charset= $charset " ;
$선택 = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => 거짓,
];
$pdo = 새 PDO($dsn, $user, $pass, $opt);

여기서 무슨 일이 일어나고 있는 걸까요?

$dsn은 작업할 데이터베이스 유형(mysql), 호스트, 데이터베이스 이름 및 문자 세트를 지정합니다.
- 그 뒤에 사용자 이름과 비밀번호가 옵니다.
- 그 후에는 어떤 매뉴얼에도 기록되지 않은 옵션 배열이 지정됩니다.

위에서 언급했듯이 이 배열은 매우 유용한 것이라는 사실에도 불구하고. 가장 중요한 것은 에러 모드를 Exception 형태로만 설정해야 한다는 점이다.
- 첫째, 다른 모든 모드에서는 PDO가 오류에 대해 이해할 수 있는 어떤 것도 보고하지 않기 때문에,
- 둘째, 예외에는 항상 대체할 수 없는 스택 추적이 포함되어 있기 때문에
- 셋째, 예외는 처리하기가 매우 편리합니다.

또한 부지런한 햄스터가 좋아하는 것처럼 모든 요청에 ​​FETCH_MODE를 쓰지 않도록 기본적으로 FETCH_MODE를 설정하는 것이 매우 편리합니다.
또한 여기에서는 pconnect 모드, 준비된 표현의 에뮬레이션 및 기타 많은 무서운 단어를 설정할 수 있습니다.

결과적으로 우리는 전체 스크립트에서 작업하는 $pdo 변수를 얻습니다.

두 가지 방법을 사용하여 쿼리를 실행할 수 있습니다.
요청에 변수가 전달되지 않으면 query() 함수를 사용할 수 있습니다. 요청을 실행하고 특수 개체인 PDO 문을 반환합니다. 대략적으로 mysql_query()에 의해 반환된 mysql 리소스와 비교할 수 있습니다. 전통적인 방법, while 또는 foreach()를 통해 이 개체에서 데이터를 가져올 수 있습니다. 또한 아래에서 설명하는 특수 형식으로 수신된 데이터를 반환하도록 요청할 수도 있습니다.
$stmt = $pdo -> query ("사용자에서 이름 선택");
while ($row = $stmt -> 가져오기())
{
}

하나 이상의 변수가 요청에 전달되면 이 요청은 준비된 표현식을 통해서만 실행되어야 합니다. 그것은 무엇입니까? 이는 변수(자리 표시자) 대신 특수 마커가 배치되는 일반 SQL 쿼리입니다. PDO는 전달된 변수의 순서가 중요한 위치 지정자(?)와 순서가 중요하지 않은 명명된 자리 표시자(:name)를 지원합니다. 예:
$sql = ;
$sql = ;
이러한 쿼리를 실행하려면 먼저 prepare() 함수를 사용하여 쿼리를 준비해야 합니다. 또한 PDO 문을 반환하지만 아직 데이터가 없습니다. 이를 얻으려면 이전에 변수를 전달한 후 이 요청을 실행해야 합니다. 다음 두 가지 방법으로 전송할 수 있습니다.
대부분의 경우 간단하게 실행() 메서드를 실행하여 변수 배열을 전달할 수 있습니다.
$stmt = $pdo -> prepare ("이메일이 있는 사용자로부터 이름을 선택하세요 = ?" );
$stmt -> 실행(array($email ));

$stmt = $pdo -> prepare ("SELECT name FROM users WHERE email = :email" );
$stmt -> 실행(array("email" => $email ));
보시다시피 명명된 자리 표시자의 경우 키가 자리 표시자의 이름과 일치해야 하는 배열을 실행()에 전달해야 합니다.

때로는 매우 드물게 변수가 먼저 요청에 바인딩되어 있는 경우(bindValue()/bindParam()) 두 번째 방법이 필요할 수 있습니다. 이 경우, Execute()에는 아무 것도 전달되지 않습니다. 예제는 매뉴얼에서 찾을 수 있습니다.
이 방법을 사용할 때 항상 BindValue()를 선호해야 합니까? 왜냐하면 BindParam()의 동작은 초보자에게는 명확하지 않고 문제를 일으킬 것이기 때문입니다.

그런 다음 위와 동일한 방법으로 PDO 문을 사용할 수 있습니다. 예를 들어 foreach를 통해 다음을 수행합니다.
$stmt = $pdo -> prepare ("이메일이 있는 사용자로부터 이름을 선택하세요 = ?" );
$stmt ->
foreach ($stmt를 $row로)
{
echo $row [ "이름" ] . "\N" ;
}

중요: 준비된 표현식은 PDO를 사용하는 주요 이유입니다. 이는 변수가 포함된 SQL 쿼리를 실행하는 유일한 안전한 방법이기 때문입니다.

또한 prepare() / excute()를 사용하면 한 번 준비된 쿼리를 다른 데이터 세트로 반복적으로 실행할 수 있습니다. 실제로 이는 극히 드물게 필요하며 속도가 크게 향상되지 않습니다. 그러나 동일한 유형의 쿼리를 여러 개 작성해야 하는 경우 다음과 같이 작성할 수 있습니다.

$데이터 = 배열(
1 => 1000,
5 => 300,
9 => 200,
);

$stmt = $pdo -> 준비("사용자 설정 보너스 업데이트 = 보너스 + ? WHERE id = ?" );
foreach($data를 $id => $bonus로)
{
$stmt -> 실행([ $bonus , $id ]);
}

여기서는 요청을 한 번 준비한 다음 여러 번 실행합니다.

우리는 데이터베이스에서 순차적으로 행을 가져오는 데 사용되는 fetch() 메서드에 대해 이미 익숙해졌습니다. 이 메소드는 mysq_fetch_array() 함수 및 유사한 함수와 유사하지만 다르게 작동합니다. 여기서는 많은 함수 대신 하나가 사용되지만 해당 동작은 전달된 매개변수에 의해 지정됩니다. 이 매개변수에 대해서는 나중에 자세히 쓰겠지만 간략한 권장 사항으로 FETCH_LAZY 모드에서 fetch()를 사용하는 것이 좋습니다.
$stmt = $pdo -> prepare ("이메일이 있는 사용자로부터 이름을 선택하세요 = ?" );
$stmt -> 실행([ $_GET [ "이메일" ]]);
while ($row = $stmt -> 가져오기 (PDO :: FETCH_LAZY ))
{
에코 $행 [ 0 ] . "\N" ;
echo $row [ "이름" ] . "\N" ;
에코 $row -> 이름 . "\N" ;
}
이 모드에서는 추가 메모리가 낭비되지 않으며 인덱스, 이름 또는 속성을 통해 세 가지 방법 중 하나로 열에 액세스할 수 있습니다.

PDO 문에는 단일 열의 값을 가져오는 도우미 함수도 있습니다. 하나의 필드만 요청하면 매우 편리합니다. 이 경우 작성량이 크게 줄어듭니다.
$stmt = $pdo -> prepare ("SELECT name FROM table WHERE id=?" );
$stmt -> 실행(배열($id ));
$name = $stmt -> fetchColumn();

그러나 가장 뛰어난 기능을 갖춘 가장 흥미로운 함수는 fetchAll()입니다. 이것이 PDO를 단지 저수준 드라이버가 아닌 데이터베이스 작업을 위한 고수준 라이브러리로 만드는 것입니다.

FetchAll()은 쿼리가 반환한 모든 행으로 구성된 배열을 반환합니다. 이를 통해 다음과 같은 두 가지 결론을 내릴 수 있습니다.
1. 쿼리에서 많은 양의 데이터가 반환되는 경우에는 이 기능을 사용하면 안 됩니다. 이 경우 fetch()와 함께 전통적인 루프를 사용하는 것이 더 좋습니다.
2. 최신 PHP 응용 프로그램에서는 데이터가 수신 즉시 출력되지 않고 이 목적을 위해 템플릿으로 전송되므로 fetchAll()은 대체할 수 없게 되어 수동으로 루프를 작성하는 것을 방지하고 코드 양을 줄일 수 있습니다.

간단한 배열을 얻습니다.
매개변수 없이 호출되는 이 함수는 기본적으로 FETCH_MODE에 지정된 형식으로 데이터베이스의 행을 포함하는 일반 인덱스 배열을 반환합니다. 상수 PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_OBJ는 즉시 형식을 변경할 수 있습니다.

열을 가져오는 중입니다.
때로는 문자열 묶음에서 단일 필드를 요청하여 간단한 1차원 배열을 얻어야 하는 경우도 있습니다. 이렇게 하려면 PDO::FETCH_COLUMN 모드를 사용하세요.
$data = $pdo -> 쿼리("SELECT name FROM users" ) -> fetchAll(PDO :: FETCH_COLUMN );
배열(
0 => "존" ,
1 => "마이크" ,
2 => "메리" ,
3 => "캐시" ,
)

키-값 쌍을 검색하는 중입니다.
동일한 열을 가져오는 것이 바람직하지만 숫자가 아닌 필드 중 하나로 색인화되는 경우에도 널리 사용되는 형식입니다. PDO::FETCH_KEY_PAIR 상수가 이를 담당합니다.
$data = $pdo -> 쿼리("SELECT id, name FROM users" ) -> fetchAll (PDO :: FETCH_KEY_PAIR );
배열(
104 => "존" ,
110 => "마이크" ,
120 => "메리" ,
121 => "캐시" ,
)

필드로 색인화된 모든 행을 가져옵니다.
또한 데이터베이스에서 모든 행을 가져와야 하는 경우가 많지만 숫자가 아닌 고유 필드로 색인을 생성해야 하는 경우도 있습니다. PDO::FETCH_UNIQUE 상수가 이를 수행합니다.
$data = $pdo -> 쿼리("SELECT * FROM 사용자") -> fetchAll(PDO :: FETCH_UNIQUE );
배열(
104 => 배열(
"이름" => "존" ,
"자동차" => "도요타" ,
),
110 => 배열(
"이름" => "마이크" ,
"자동차" => "포드" ,
),
120 => 배열(
"이름" => "메리" ,
"자동차" => "마즈다" ,
),
121 => 배열(
"이름" => "캐시" ,
"자동차" => "마즈다" ,
),
)
열에서 먼저 고유한 필드를 선택해야 한다는 점을 기억해야 합니다.

PDO에는 15개 이상의 다양한 데이터 수집 모드가 있습니다. 게다가 그것들을 결합할 수도 있습니다! 그러나 이것은 별도의 기사에 대한 주제입니다.

준비된 표현식으로 작업할 때 자리 표시자는 문자열이나 숫자만 바꿀 수 있다는 점을 이해해야 합니다. 키워드, 식별자, 문자열의 일부 또는 문자열 집합은 자리 표시자를 통해 대체될 수 없습니다. 따라서 LIKE의 경우 먼저 전체 검색 문자열을 준비한 다음 이를 쿼리에 대체해야 합니다.

$이름 = "% $이름 %" ;
$stm = $pdo -> prepare ("SELECT * FROM table WHERE name LIKE ?" );
$stm -> 실행(배열($name ));
$data = $stm -> fetchAll();

글쎄, 당신은 아이디어를 얻습니다. 여기도 모든 것이 나쁘다. PDO는 식별자 작업을 위한 도구를 전혀 제공하지 않으며 구식 방식으로 수동으로 형식을 지정해야 합니다(또는 그럼에도 불구하고 다른 많은 문제와 마찬가지로 이 문제를 간단하고 우아하게 해결하는 SafeMysql을 찾으십시오).
식별자 형식 지정 규칙은 데이터베이스마다 다르다는 점을 기억해야 합니다.

mysql에서 식별자의 형식을 수동으로 지정하려면 다음 두 가지 작업을 수행해야 합니다.
- 백틱("`")으로 묶습니다.
- 두 배로 식별자 내에서 이러한 문자를 검색합니다.

$필드 = "`" . str_replace ("`" , "``" , $_GET [ "필드" ]). "`" ;
$sql = $필드 " ;

그러나 여기에는 한 가지 주의 사항이 있습니다. 포맷만으로는 충분하지 않을 수 있습니다. 위의 코드는 일반적인 삽입으로부터 우리를 보호하지만 어떤 경우에는 우리가 무심코 필드 및 테이블 이름을 쿼리에 직접 대체하면 적이 여전히 원치 않는 내용을 작성할 수 있습니다. 예를 들어 사용자 테이블에는 관리 필드가 있습니다. 들어오는 필드 이름이 필터링되지 않으면 POST에서 자동으로 요청을 생성할 때 바보라도 이 필드에 불쾌한 내용을 쓸 것입니다.

따라서 아래 예와 같이 사용자로부터 오는 테이블 및 필드 이름의 유효성을 확인하는 것이 좋습니다.

수많은 튜토리얼에서 볼 수 있는 임베드 코드는 우울함과 앱스텐을 죽이고 싶은 욕구를 불러일으킵니다. $_POST 인덱스, 변수 이름, 요청의 필드 이름, 요청의 자리 표시자 이름, 바인딩 시 자리 표시자 이름 및 변수 이름에서 동일한 이름이 반복되는 수 킬로미터의 구성입니다.
이 코드를 보면 누군가를 죽이고 싶거나 적어도 코드를 좀 더 짧게 만들고 싶은 생각이 듭니다.

이는 양식의 필드 이름이 테이블의 필드 이름과 일치하는 규칙을 채택하여 수행할 수 있습니다. 그런 다음 이러한 이름은 한 번만 나열될 수 있으며(위에서 언급한 대체를 방지하기 위해) 작은 도우미 함수를 사용하여 쿼리를 조합할 수 있습니다. 이는 mysql의 특성으로 인해 INSERT와 쿼리 모두에 적합합니다. 업데이트 쿼리:

함수 pdoSet($allowed, & $values ​​​​, $source = array()) (
$세트 = "" ;
$값 ​​= 배열();
if (!$source ) $source = & $_POST ;
foreach ($field로 $허용) (
if (isset($source [ $field ])) (
$set .= "`" . str_replace ("`" , "``" , $field ). "`". "=: $필드 , " ;
$values ​​​​[ $field ] = $source [ $field ];
}
}
return substr($set, 0, - 2);
}

따라서 Embed 코드는 다음과 같습니다.

$allowed = array("이름" , "성" , "이메일" ); // 허용되는 필드
$sql = "사용자 SET에 삽입" . pdoSet($허용, $값);
$stm = $dbh -> 준비($sql );
$stm -> 실행($values);

업데이트 내용은 다음과 같습니다.

$allowed = array("이름" , "성" , "이메일" , "비밀번호" ); // 허용되는 필드
$_POST ["비밀번호" ] = MD5 ($_POST [ "로그인" ]. $_POST [ "비밀번호" ]);
$sql = "사용자 설정 업데이트" . pdoSet($허용, $값). "ID = :id" ;
$stm = $dbh -> 준비($sql );
$values ​​​​["id" ] = $_POST ["id" ];
$stm -> 실행($values);

그다지 인상적이지는 않지만 매우 효과적입니다. 그런데 MySQL에서 안전하고 편리한 작업을 위해 Class를 사용한다면 이 모든 작업이 두 줄로 완료된다는 점을 상기시켜 드리겠습니다.

PDO 및 키워드
여기서 필터링하는 것 외에 다른 것을 생각해내는 것은 불가능합니다. 따라서 요청에 직접 지정되지 않은 모든 연산자를 화이트 리스트를 통해 실행하는 것은 어리석은 일입니다.

$dirs = array("ASC" , "DESC" );
$key = array_search($_GET["dir"], $dirs));
$dir = $orders [ $key ];
$sql = "SELECT * FROM`table` ORDER BY $field $dir " ;

PDO 클래스의 인스턴스가 생성되면 데이터베이스에 대한 연결이 설정됩니다. 어떤 드라이버를 사용하도록 선택하는지는 중요하지 않습니다. 항상 PDO 클래스를 사용해야 합니다. 해당 생성자는 데이터베이스 소스(DSN이라고 함)를 지정하기 위한 매개변수와 사용자 이름 및 비밀번호에 대한 선택적 매개변수를 허용합니다.

MySQL에 연결: $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass);

연결 오류가 발생하면 PDOException 클래스의 객체라는 예외가 발생합니다. 이 상황을 처리하고 싶다면 이를 잡을 수도 있고, set_Exception_handler()를 통해 설정된 전역 예외 처리기에 남겨 둘 수도 있습니다.

연결 오류 처리: try ( $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); foreach($dbh->query('SELECT * from FOO') as $row) ( print_r($row); ) $dbh = null; ) catch (PDOException $e) ( die("오류! 바로 그거예요. 도착했습니다...".$e->getMessage()); )

경고: PDO 생성자에서 발생한 예외를 포착하지 못한 경우 zend 엔진이 취하는 기본 조치는 스크립트를 중지하고 추적을 표시하는 것입니다. 이 쓰레기는 데이터베이스와의 통신에 대한 모든 친밀한 세부 정보를 공개합니다. 즉, 사용자 이름과 비밀번호를 포함하여 데이터베이스 연결에 대한 자세한 세부 정보가 표시됩니다! 명시적으로(try catch 문을 통해) 또는 암시적으로 set_Exception_handler()를 통해 이 예외를 포착하는 것은 사용자에게 달려 있습니다.

데이터베이스 연결이 성공하면 PDO 개체 인스턴스의 전체 수명 동안 활성 상태로 유지됩니다. 연결을 닫으려면 개체를 삭제해야 하며 개체에 대한 나머지 모든 참조가 제거되었는지 확인해야 합니다. 이는 개체가 포함된 변수에 NULL 값을 할당하여 수행할 수 있습니다. 이 작업을 명시적으로 수행하지 않으면 스크립트가 종료될 때 PHP가 자동으로 연결을 닫습니다.

연결 닫기: $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); // 여기서 뭔가를 하고 있습니다: ... // 이제 주의: 연결이 종료되었습니다! $dbh = 널;

많은 웹 애플리케이션은 데이터베이스 서버에 대한 지속적인 연결을 생성함으로써 이점을 얻습니다. 영구 연결은 스크립트가 종료될 때 닫히지 않지만 다른 스크립트가 동일한 연결 자격 증명을 사용하여 연결을 요청할 때 캐시되어 재사용됩니다. 영구 연결 캐시는 스크립트가 데이터베이스와 통신해야 할 때마다 새 연결을 설정하는 오버헤드를 방지하여 웹 애플리케이션이 더 빠르게 실행되도록 합니다.

영구 연결 설정: $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => true));

참고: 영구 연결을 사용하려면 다음을 설정해야 합니다. PDO::ATTR_PERSISTENT PDO 클래스 생성자에 전달되는 드라이버 옵션 배열에 있습니다. 객체가 인스턴스화된 후 PDO::setAttribute()를 통해 이 속성을 설정하면 드라이버는 영구 링크를 사용하지 않습니다. 또한 이 경우 일부 요구 사항에 맞게 PDOStatement 클래스를 확장할 수 없습니다. 다음을 설치할 수 없습니다. PDO::ATTR_STATEMENT_CLASS

  • 번역

많은 PHP 개발자는 데이터베이스 작업을 위해 mysql 및 mysqli 확장을 사용하는 데 익숙합니다. 그러나 PHP 버전 5.1부터 더 편리한 방법인 PHP 데이터 개체가 있습니다. 줄여서 PDO라고 하는 이 클래스는 생산성을 크게 향상시킬 개체 및 준비된 명령문을 사용하는 방법을 제공합니다!

PDO 소개 "PDO - PHP 데이터 개체는 여러 데이터베이스와 작업할 수 있는 보편적인 방법을 제공하는 계층입니다."
이는 다양한 DBMS의 구문 기능에 대한 관심을 개발자에게 맡기지만 플랫폼 간 전환 프로세스를 훨씬 덜 고통스럽게 만듭니다. 종종 데이터베이스 연결 문자열만 변경하면 됩니다.


이 기사는 mysql 및 mysqli를 사용하여 보다 강력하고 유연한 PDO로 마이그레이션하는 데 도움을 주기 위해 작성되었습니다. DBMS 지원 이 확장은 PDO 드라이버가 존재하는 모든 데이터베이스 관리 시스템을 지원할 수 있습니다. 이 글을 쓰는 시점에는 다음 드라이버를 사용할 수 있습니다.
  • PDO_CUBRID (CUBRID)
  • PDO_DBLIB(FreeTDS/Microsoft SQL Server/Sybase)
  • PDO_FIREBIRD(파이어버드/인터베이스 6)
  • PDO_IBM(IBM DB2)
  • PDO_INFORMIX(IBM Informix 동적 서버)
  • PDO_MYSQL(MySQL 3.x/4.x/5.x)
  • PDO_OCI(오라클 호출 인터페이스)
  • PDO_ODBC(ODBC v3(IBM DB2, unixODBC 및 win32 ODBC))
  • PDO_PGSQL(포스트그레SQL)
  • PDO_SQLITE(SQLite 3 및 SQLite 2)
  • PDO_SQLSRV(마이크로소프트 SQL 서버)
  • PDO_4D (4D)
그러나 이들 모두가 서버에 있는 것은 아닙니다. 다음과 같이 사용 가능한 드라이버 목록을 볼 수 있습니다.
print_r(PDO::getAvailableDrivers()); 서로 다른 DBMS에 연결하는 연결 방법은 약간 다를 수 있습니다. 다음은 가장 인기 있는 항목에 연결하는 예입니다. 처음 세 개는 SQLite와 달리 동일한 구문을 가지고 있음을 알 수 있습니다.
try ( # PDO_DBLIB를 통한 MS SQL Server 및 Sybase $DBH = new PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = new PDO("sybase:host=$host ;dbname=$dbname", $user, $pass); # PDO_MYSQL을 통한 MySQL $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = new PDO("sqlite:my/database/path/database.db"); ) catch(PDOException $e) ( echo $e->getMessage(); )
try/catch 블록에 주의하세요. 항상 모든 PDO 작업을 여기에 래핑하고 예외 메커니즘을 사용하는 것이 좋습니다(나중에 자세히 설명).

$DBH는 "데이터베이스 핸들"을 나타내며 기사 전체에서 사용됩니다.

해당 변수를 null로 다시 정의하여 모든 연결을 닫을 수 있습니다.
# 연결을 닫습니다. $DBH = null;
다양한 DBMS의 고유한 옵션과 연결 방법에 대한 자세한 내용은 php.net에서 확인할 수 있습니다.

예외 및 PDO PDO는 오류 시 예외를 발생시킬 수 있으므로 모든 것이 try/catch 블록에 있어야 합니다. 연결을 생성한 직후 PDO는 세 가지 오류 모드 중 하나로 전환될 수 있습니다.
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
그러나 연결을 시도할 때 오류가 발생하면 항상 예외가 발생한다는 점은 주목할 가치가 있습니다. PDO::ERRMODE_SILENT 이것이 기본 모드입니다. mysql 및 mysqli 확장에서 오류를 포착하기 위해 거의 동일한 방법을 사용할 것입니다. 다음 두 가지 모드는 DRY 프로그래밍에 더 적합합니다. PDO::ERRMODE_WARNING 이 모드는 표준 경고를 발생시키고 스크립트가 계속 실행되도록 합니다. 디버깅에 편리합니다.PDO::ERRMODE_EXCEPTION 대부분의 상황에서는 이러한 유형의 스크립트 실행 제어가 바람직합니다. 예외를 발생시켜 오류를 영리하게 처리하고 민감한 정보를 숨길 수 있습니다. 예를 들면 다음과 같습니다.
# 데이터베이스에 연결 try ( $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; # 젠장! SELECT 대신 DELECT를 입력했습니다! $DBH->prepare("DELECT name FROM people")->execute(); ) catch(PDOException $e) ( echo "휴스턴, 문제가 발생했습니다."; file_put_contents ("PDOErrors .txt", $e->getMessage(), FILE_APPEND); )
예외를 발생시키는 SQL 표현식에 구문 오류가 있습니다. 로그 파일에 오류의 세부 사항을 기록하고 인간의 언어로 사용자에게 무언가 발생했음을 암시할 수 있습니다.삽입 및 업데이트 새 데이터를 삽입하고 기존 데이터를 업데이트하는 것은 가장 일반적인 데이터베이스 작업 중 일부입니다. PDO의 경우 이 프로세스는 일반적으로 두 단계로 구성됩니다. (다음 섹션은 UPDATE와 INSERT에 관한 것입니다.)


새 데이터를 삽입하는 간단한 예:
# STH는 "명령문 핸들"을 의미합니다. $STH = $DBH->prepare("INSERT INTO people (first_name) 값 ​​("Cathy")"); $STH->실행();
실제로 하나의 exec() 메서드로 동일한 작업을 수행할 수 있지만 2단계 메서드는 준비된 문의 모든 이점을 제공합니다. SQL 주입으로부터 보호하는 데 도움이 되므로 일회성 쿼리에도 사용하는 것이 좋습니다.Prepared 문 준비된 문을 사용하면 SQL 주입에 대한 보호가 강화됩니다.
준비된 문은 서로 다른 데이터 세트만 서버에 전송하여 반복적으로 실행할 수 있는 미리 컴파일된 SQL 문입니다. 또 다른 장점은 자리 표시자에 사용된 데이터를 통해 SQL 주입을 수행할 수 없다는 것입니다.

다음은 준비된 진술의 세 가지 예입니다.
# 자리 표시자 없음 - SQL 주입의 문이 열려 있습니다! $STH = $DBH->prepare("INSERT INTO people (name, addr, city) 값 ​​($name, $addr, $city)"); # 이름 없는 자리 표시자 $STH = $DBH->prepare("INSERT INTO people (name, addr, city) value ​(?, ?, ?)"); # 명명된 자리 표시자 $STH = $DBH->prepare("INSERT INTO people (name, addr, city) 값 ​​(:name, :addr, :city)");
첫 번째 예는 단지 비교를 위한 것이므로 사용하지 않는 것이 좋습니다. 이름 없는 자리 표시자와 명명된 자리 표시자의 차이점은 준비된 문에 데이터를 전달하는 방법입니다.

명명되지 않은 자리 표시자 # 각 자리 표시자에 1부터 3까지의 인덱스를 사용하여 변수를 할당합니다. $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $city); # 한 줄 삽입 $name = "Daniel" $addr = "1 Wicked Way"; $city = "알링턴 하이츠"; $STH->실행(); # 다른 데이터를 사용하여 다른 줄을 삽입합니다. $name = "Steve" $addr = "5 Circle Drive"; $city = "샴버그"; $STH->실행();
여기에는 두 단계가 있습니다. 첫 번째에서는 모든 자리 표시자(라인 2-4)에 변수를 할당합니다. 그런 다음 이러한 변수에 값을 할당하고 쿼리를 실행합니다. 새로운 데이터 세트를 보내려면 변수 값을 변경하고 요청을 다시 실행하면 됩니다.

SQL 표현식에 매개변수가 많으면 각 매개변수에 변수를 할당하는 것이 매우 불편합니다. 이러한 경우 데이터를 배열에 저장하고 전달할 수 있습니다.
# 삽입할 데이터 세트 $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("사용자(이름, 주소, 도시) 값을 삽입하세요 ​(?, ?, ?)"); $STH->실행($data);
$data는 첫 번째 자리 표시자 자리에 삽입되고, $data는 두 번째 자리 표시자 자리에 삽입됩니다. 하지만 주의하세요. 인덱스가 엉망이면 작동하지 않습니다.

명목상의 자리 표시자 # 첫 번째 인수는 자리 표시자의 이름입니다. # 일반적으로 콜론으로 시작합니다. # 콜론 없이도 작동하지만 $STH->bindParam(":name", $name);
여기에서 배열을 전달할 수도 있지만 연관적이어야 합니다. 키는 짐작할 수 있듯이 자리 표시자의 이름이어야 합니다.
# 삽입한 데이터 $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO people (name, addr, city) 값 ​​(:name, :addr, :city)"); $STH->실행($data);
명명된 자리 표시자 사용의 편리한 점 중 하나는 속성 이름이 매개 변수 이름과 일치하는 경우 데이터베이스에 개체를 직접 삽입할 수 있다는 것입니다. 예를 들어 다음과 같은 데이터를 삽입할 수 있습니다.
# 간단한 객체 클래스를 위한 클래스 person ( public $name; public $addr; public $city; function __construct($n,$a,$c) ( $this->name = $n; $this->addr = $ a ; $this->city = $c; ) # 등등... ) $cathy = 새로운 사람("Cathy","9 Dark and Twisty","Cardiff"); # 여기에 흥미로운 부분이 있습니다. $STH = $DBH->prepare("INSERT INTO people (name, addr, city) value ​​(:name, :addr, :city)"); $STH->execute((array)$cathy);
Execute() 중에 객체를 배열로 변환하면 속성이 배열 키로 처리됩니다.

->fetch() 메소드를 사용하여 데이터를 검색할 수 있습니다. 호출하기 전에 어떤 형식으로 필요한지 명시적으로 표시하는 것이 좋습니다. 몇 가지 옵션이 있습니다:
  • PDO::FETCH_ASSOC: 열 이름을 키로 사용하여 배열을 반환합니다.
  • PDO::FETCH_BOTH(기본값): 열 이름과 열 번호 모두로 인덱싱된 배열을 반환합니다.
  • PDO::FETCH_BOUND: ->bindColumn() 메서드를 사용하여 지정된 해당 변수에 열 값을 할당합니다.
  • PDO::FETCH_CLASS: 지정된 클래스의 해당 속성에 열 값을 할당합니다. 일부 열에 속성이 없으면 생성됩니다.
  • PDO::FETCH_INTO: 지정된 클래스의 기존 인스턴스를 업데이트합니다.
  • PDO::FETCH_LAZY: PDO::FETCH_BOTH와 PDO::FETCH_OBJ를 결합합니다.
  • PDO::FETCH_NUM: 키가 열 번호인 배열을 반환합니다.
  • PDO::FETCH_OBJ: 열 ​​이름에 해당하는 속성을 가진 익명 개체를 반환합니다.
실제로는 일반적으로 FETCH_ASSOC, FETCH_CLASS 및 FETCH_OBJ의 세 가지가 필요합니다. 데이터 형식을 지정하려면 다음 구문을 사용하십시오.
$STH->setFetchMode(PDO::FETCH_ASSOC);
->fetch() 메소드를 호출할 때 직접 설정할 수도 있습니다. FETCH_ASSOC 이 형식은 열 이름을 인덱스로 사용하여 연관 배열을 생성합니다. 이는 mysql/mysqli 확장을 사용하는 사람들에게 친숙할 것입니다.
# 자리 표시자가 없는 일반 쿼리이므로 # 즉시 query() 메서드를 사용할 수 있습니다. $STH = $DBH->query("SELECT name, addr, city from people"); # 가져오기 모드를 설정합니다. $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] . "\N"; )
while() 루프는 전체 쿼리 결과를 반복합니다.FETCH_OBJ 이 유형의 데이터 가져오기는 각 행에 대해 std 클래스의 인스턴스를 생성합니다.
# 쿼리 생성 $STH = $DBH->query("SELECT name, addr, city from people"); # 가져오기 모드 선택 $STH->setFetchMode(PDO::FETCH_OBJ); # 결과를 인쇄합니다 while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n"; ) FETCH_CLASS fetch_class를 사용하면 지정된 클래스의 인스턴스에 데이터가 기록됩니다. 이 경우 생성자를 호출하기 전에 객체의 속성에 값이 할당됩니다. 열 이름에 해당하는 이름을 가진 속성이 없으면 자동으로 생성됩니다(범위는 public).

데이터가 데이터베이스에서 수신된 후 즉시 필수 처리가 필요한 경우 클래스 생성자에서 데이터를 구현할 수 있습니다.

예를 들어, 개인의 거주지 주소 중 일부를 숨겨야 하는 상황을 가정해 보겠습니다.
class secret_person ( public $name; public $addr; public $city; public $other_data; function __construct($other = "") ( $this->addr = preg_replace("//", "x", $this-> addr); $this->other_data = $other; ) )
객체를 생성할 때 라틴 소문자는 모두 x로 바꿔야 합니다. 점검 해보자:
$STH = $DBH->query("이름, 주소, 도시를 선택하세요."); $STH->setFetchMode(PDO::FETCH_CLASS, "secret_person"); while($obj = $STH->fetch()) ( echo $obj->addr; )
데이터베이스의 주소가 '5 Rosebud'과 같은 경우 출력은 '5 Rxxxxxx'가 됩니다.

물론 때로는 값을 할당하기 전에 생성자를 호출하기를 원할 수도 있습니다. PDO도 이것을 허용합니다.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "비밀_사람");
이제 추가 옵션(PDO::FETCH_PROPS_LATE)으로 이전 예제를 보완했으므로 값이 작성된 후에는 아무 일도 일어나지 않으므로 주소는 수정되지 않습니다.

마지막으로, 필요한 경우 객체를 생성할 때 생성자에 직접 인수를 전달할 수 있습니다.
$STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", array("stuff"));
각 객체에 서로 다른 인수를 전달할 수도 있습니다.
$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // 뭔가를 합니다 $i++; )

기타 유용한 기술 이 기사가 PDO 작업의 모든 측면을 다룰 수는 없지만(거대한 모듈입니다!) 다음 몇 가지 기능을 언급하지 않고 빼놓아서는 안 됩니다.
$DBH->마지막 삽입ID();
->lastInsertId() 메소드는 마지막으로 삽입된 레코드의 ID를 반환합니다. 표현식($STH)이 있는 개체가 아니라 항상 데이터베이스 개체(이 문서에서는 $DBH라고 함)에서 호출된다는 점은 주목할 가치가 있습니다.
$DBH->exec("1번 위치에서 삭제"); $DBH->exec("SET time_zone = "-8:00"");
->exec() 메소드는 영향을 받은 레코드 수 외에는 어떠한 데이터도 반환하지 않는 작업에 사용됩니다.
$safe = $DBH->quote($unsafe);
->quote() 메소드는 문자열 데이터에 따옴표를 배치하여 쿼리에서 안전하게 사용할 수 있도록 합니다. 준비된 문을 사용하지 않는 경우 유용합니다.
$rows_affected = $STH->rowCount();
->rowCount() 메서드는 작업에 참여한 레코드 수를 반환합니다. 불행하게도 이 함수는 PHP 5.1.6까지 SELECT 쿼리에서 작동하지 않았습니다. PHP 버전을 업데이트할 수 없는 경우 다음과 같이 레코드 수를 얻을 수 있습니다.
$sql = "SELECT COUNT(*) FROM 사람들"; if ($STH = $DBH->query($sql)) ( # 레코드 수를 확인합니다. if ($STH->fetchColumn() > 0) ( # 데이터가 발견되었으므로 여기에서 전체 선택을 수행합니다! ) else ( # 요청을 충족하는 데이터를 찾을 수 없다는 메시지를 인쇄합니다.) ) 결론 이 자료가 mysql 및 mysqli 확장에서 마이그레이션하는 데 도움이 되기를 바랍니다.