PHPPDO 연구 노트 lib.culog.cn 2007년 11월 13일 09:36 작성자: Liu Shui Meng Chun [대형, 중형, 소형]
■PDO란?
POD(PHP 데이터 개체) 확장은 PHP5에 추가되었습니다. PHP6에서는 기본적으로 PDO가 아닌 모든 확장이 PHP6의 확장에서 제거됩니다. 이 확장은 데이터베이스에 액세스하기 위해 PHP 내장 클래스 PDO를 제공합니다. 서로 다른 데이터베이스는 일관성 없는 데이터베이스 연결 문제를 해결하기 위해 동일한 메소드 이름을 사용합니다.
Windows에서 개발하도록 구성했습니다.
■PDO의 목표는 다양한 RDBMS 라이브러리의 공통 기능을 통합하되 고급 기능을 배제하지 않는 가볍고 명확하며 편리한 API를 제공하는 것입니다. PHP 스크립트를 통해 선택적으로 더 높은 수준의 추상화/호환성을 제공합니다.
■PDO의 특징:
성능. PDO는 기존 데이터베이스 확장의 성공과 실패에 대해 처음부터 배웠습니다. PDO의 코드는 완전히 새로운 것이기 때문에 PHP 5의 최신 기능을 활용하기 위해 처음부터 성능을 다시 설계할 수 있는 기회가 있습니다. 능력. PDO는 공통 데이터베이스 기능을 기반으로 제공하는 동시에 RDBMS의 고유한 기능에 쉽게 액세스할 수 있도록 설계되었습니다. 단순한. PDO는 데이터베이스 작업을 쉽게 하도록 설계되었습니다. API는 코드에 강제로 들어가지 않으며 각 함수 호출이 수행하는 작업을 명확하게 보여줍니다. 런타임 시 확장 가능합니다. PDO 확장은 모듈식이므로 전체 PHP 프로그램을 다시 컴파일하거나 다시 설치하지 않고도 런타임에 데이터베이스 백엔드용 드라이버를 로드할 수 있습니다. 예를 들어, PDO_OCI 확장은 PDO 확장 대신 Oracle 데이터베이스 API를 구현합니다. MySQL, PostgreSQL, ODBC 및 Firebird용 드라이버도 있으며 더 많은 드라이버가 개발 중입니다.
■PDO 설치
여기에 있는 것은 WINDOWS에서 개발하기 위한 PDO 확장입니다. Linux에서 설치하고 구성하려면 다른 곳을 살펴보십시오.
버전 요구사항:
이는 이미 php5.1 및 이후 버전의 프로그램 패키지에 포함되어 있습니다.
php5.0.x의 경우, pecl.php.net에서 다운로드하여 PHP가 있는 폴더의 ext 폴더인 확장 라이브러리에 넣어야 합니다.
매뉴얼에는 5.0 이전 버전에서는 PDO 확장을 실행할 수 없다고 나와 있습니다.
구성:
pdo를 지원하도록 php.ini 구성 파일을 수정하세요. (php.ini를 이해하지 못한다면 먼저 phpinfo() 함수를 호출할 때 표시되는 php.ini를 수정해야 한다는 점을 알아보세요.)
묶음
Extension=php_pdo.dll 앞의 세미콜론을 제거하십시오. 세미콜론은 PHP 구성 파일 주석 기호입니다.
더 있습니다
;확장자=php_pdo.dll
;확장자=php_pdo_firebird.dll
;확장자=php_pdo_informix.dll
;확장자=php_pdo_mssql.dll
;확장자=php_pdo_mysql.dll
;확장자=php_pdo_oci.dll
;확장자=php_pdo_oci8.dll
;확장자=php_pdo_odbc.dll
;확장자=php_pdo_pgsql.dll
;확장자=php_pdo_sqlite.dll
각 확장에 해당하는 데이터베이스는 다음과 같습니다.
드라이버 이름지원되는 데이터베이스PDO_DBLIBFreeTDS / Microsoft SQL Server / SybasePDO_FIREBIRDFirebird/Interbase 6PDO_INFORMIXIBM Informix Dynamic ServerPDO_MYSQLMySQL 3.x/4.xPDO_OCIOracle 호출 인터페이스PDO_ODBCODBC v3(IBM DB2, unixODBC 및 win32 ODBC)PDO_PGSQLPostgreSQLPDO_SQLITESQLite 3 및 SQLite 2
어떤 데이터베이스를 사용하고 싶은지 해당 데이터베이스를 입력하세요. 확장하기 전에 주석 기호 ";"를 제거하십시오.
■PDO 사용
여기서는 mysql을 설치했다고 가정하고, 그렇지 않다면 먼저 설치 방법을 찾아보세요. 내 것은 mysql5.0.22이고, MySQL 4.0.26을 사용하는 다른 사람들도 사용할 수 있습니다.
★데이터베이스 연결:
다음 예제를 사용하여 PDO 연결 데이터베이스를 분석합니다.
<?php
$dbms='mysql'; //오라클에서는 ODI를 사용하는 데이터베이스 종류 개발자의 경우, 다른 데이터베이스를 사용한다면 이것만 바꾸면 되고 그렇게 많은 기능을 기억할 필요는 없습니다.
$host='localhost';//데이터베이스 호스트 이름
$dbName='test'; //사용된 데이터베이스
$user='root'; //데이터베이스 연결 사용자 이름
$pass=''; //해당 비밀번호
$dsn="$dbms:host=$host;dbname=$dbName";
//
노력하다{
$dbh=newPDO($dsn,$user,$pass);//PDO 객체를 초기화한다는 것은 데이터베이스 연결 객체 $dbh를 생성한다는 의미입니다.
echo "연결 성공<br/>";
foreach($dbh->query('SELECT * from FOO')as$row){에 대한
검색 작업을 수행할 수도 있습니다
.
print_r($row);//echo($GLOBAL)를 사용하여 이 값을 볼 수 있습니다.
}
*/
$dbh=널;
}캐치(PDOException$e){
die("오류!: ".$e->getMessage()."<br/>");
}
//기본적으로 이는 긴 연결이 아닙니다. 데이터베이스에 대한 긴 연결이 필요한 경우 끝에 array(PDO::ATTR_PERSISTENT => true) 매개변수를 추가해야 합니다.
$db=newPDO($dsn,$user,$pass,array(PDO::ATTR_PERSISTENT=>true))
?>
★데이터베이스 쿼리:
위의 쿼리를 이미 수행했으며 다음 쿼리를 사용할 수도 있습니다.
<?php
$db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER) //속성 설정
$rs=$db->query("SELECT * FROM foo");
$rs->setFetchMode(PDO::FETCH_ASSOC);
$result_arr=$rs->fetchAll();
print_r($result_arr);
?>
위에서 setAttribute() 메소드를 사용했기 때문에 필드 이름을 대문자로 강제하기 위해 두 개의 매개변수가 추가되었습니다. 다음은 PDO::setAttribute()의 매개변수입니다.
PDO::ATTR_CASE: 아래에 설명된 대로 열 이름을 형식으로 지정합니다(두 번째 매개변수):
PDO::CASE_LOWER: 열 이름을소문자
로 지정합니다.
: :CASE_NATURAL: 열 이름은 원래 방식을 따릅니다.
PDO::CASE_UPPER: 열 이름을 대문자로 강제합니다.
PDO::ATTR_ERRMODE: 오류 메시지.
PDO::ERRMODE_SILENT: 오류 정보를 표시하지 않고 오류 코드만
표시합니다.
PDO::ERRMODE_EXCEPTION: 예외를 발생시킵니다.
PDO::ATTR_ORACLE_NULLS (ORACLE뿐만 아니라 다른 데이터베이스에도 유효함): )는 데이터베이스에서 반환된 NULL 값에 대해 PHP에서 해당 값을 지정합니다.
PDO::NULL_NATURAL: 변경되지 않았습니다.
PDO::NULL_EMPTY_STRING: 빈 문자열이 NULL로 변환됩니다.
PDO::NULL_TO_STRING: NULL이 빈 문자열로 변환됩니다.
PDO::ATTR_STRINGIFY_FETCHES: 가져올 때 숫자 값을 문자열로 변환합니다.
PDO::ATTR_STATEMENT_CLASS: PDOStatement에서 파생된 사용자 제공 명령문 클래스를 설정합니다. Requiresarray(string classname, array(mixed constructor_args) )) .
PDO::ATTR_AUTOCOMMIT(OCI, Firebird 및 MySQL에서 사용 가능): 모든 단일 문을 자동 커밋할지 여부.
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY(MySQL에서 사용 가능): 버퍼링된 쿼리를 사용합니다.
$rs->setFetchMode(PDO::FETCH_ASSOC); 예제에서는 반환 유형 선언인 PDOStatement::setFetchMode()가 있습니다.
다음과 같은 것들이 있습니다:
PDO::FETCH_ASSOC-- 연관 배열 형식
PDO::FETCH_NUM -- 숫자 인덱스 배열 형식
PDO::FETCH_BOTH -- 둘 다 배열 형식으로 사용 가능하며 이는 기본값입니다.
PDO::FETCH_OBJ - 이전 mysql_fetch_object()와 유사한 객체 형식입니다.
더 많은 반환 유형 선언(PDOStatement::method 이름)을 보려면 매뉴얼을 참조하세요.
★데이터 삽입, 업데이트, 삭제,
$db->exec("mid=43인 `xxxx_menu`에서 삭제");
위 작업을 간략하게 요약하면 다음과 같습니다.
쿼리 작업은 주로 PDO::query(), PDO::exec(), PDO::prepare()입니다.
PDO::query()는 기록된 결과를 반환하는 작업, 특히 SELECT 작업에 주로 사용됩니다.
PDO::exec()는 주로 INSERT, UPDATE, DELETE 및 기타 작업과 같이 결과 집합을 반환하지 않는 작업에 사용됩니다. 반환되는 결과는 현재 작업의 영향을 받는 열 수입니다.
PDO::prepare()는 주로 전처리 작업입니다. 전처리에서 SQL 문을 실행하려면 $rs->execute()를 사용해야 합니다. 이 방법은 매개 변수를 바인딩할 수 있으며 이 기사에서는 간단하게 설명할 수 없습니다. . 모두 매뉴얼 및 기타 문서를 참조할 수 있습니다.
결과 세트를 얻기 위한 주요 작업은 PDOStatement::fetchColumn(), PDOStatement::fetch(), PDOStatement::fetchALL()입니다.
PDOStatement::fetchColumn()은 가져오기 결과에 지정된 첫 번째 레코드의 필드입니다. 기본값은 첫 번째 필드입니다.
PDOStatement::fetch()는 레코드를 얻는 데 사용됩니다.
PDOStatement::fetchAll()은 모든 레코드 세트를 하나로 가져오는 것입니다. 결과를 얻으려면 PDOStatement::setFetchMode를 통해 필요한 결과 세트의 유형을 설정하면 됩니다.
두 가지 주변 작업도 있습니다. 하나는 PDO::lastInsertId() 및 PDOStatement::rowCount()입니다. PDO::lastInsertId()는 마지막 삽입 작업을 반환하고 기본 키 열 유형은 마지막 자동 증가 ID입니다.
PDOStatement::rowCount()는 주로 PDO::query() 및 PDO::prepare()의 DELETE, INSERT 및 UPDATE 작업의 영향을 받는 결과 집합에 사용되며 PDO::exec() 메서드에는 유효하지 않습니다. 및 SELECT 작업.
★트랜잭션 및 자동 제출
이제 PDO를 통해 mysql에 연결한 후 쿼리를 실행하기 전에 PDO가 트랜잭션을 관리하는 방법을 이해해야 합니다. 이전에 트랜잭션을 접해본 적이 없다면 먼저 트랜잭션의 4가지 특성인 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 내구성(Durability), 즉 ACID를 알아야 합니다. 평신도의 관점에서 보면 트랜잭션 내에서 수행되는 모든 작업은 단계적으로 수행되더라도 해당 작업이 데이터베이스에 안전하게 적용되고 작업이 제출되는 동안 다른 연결의 요청에 영향을 받지 않는다는 보장이 있습니다. . 영향. 요청 시 트랜잭션 작업을 자동으로 취소할 수 있으므로(아직 커밋하지 않은 경우) 스크립트의 오류 처리가 훨씬 쉬워집니다.
트랜잭션은 일반적으로 일괄 변경 사항을 누적하고 동시에 적용함으로써 구현됩니다. 이것의 장점은 이러한 업데이트의 효율성을 크게 향상시킬 수 있다는 것입니다. 즉, 트랜잭션을 통해 스크립트를 더 빠르고 잠재적으로 더 강력하게 만들 수 있습니다(단, 이러한 이점을 얻으려면 트랜잭션을 올바르게 사용해야 함).
불행히도 모든 데이터베이스가 트랜잭션을 지원하는 것은 아닙니다(Mysql5는 트랜잭션을 지원하지만 mysql4는 모르겠습니다). 따라서 연결이 처음 열릴 때 PDO는 소위 "자동 커밋" 모드에서 실행되어야 합니다. 자동 커밋 모드는 데이터베이스가 트랜잭션을 지원하는 경우 실행하는 모든 쿼리에 자체 암시적 트랜잭션이 있고 데이터베이스가 트랜잭션을 지원하지 않는 경우 모든 쿼리에 그러한 트랜잭션이 없음을 의미합니다. 트랜잭션이 필요한 경우 PDO::beginTransaction() 메서드를 사용하여 트랜잭션을 시작해야 합니다. 기본 드라이버가 트랜잭션을 지원하지 않으면 PDOException이 발생합니다(오류 처리 설정에 관계없이 이는 항상 치명적인 오류 조건입니다). 트랜잭션 내에서 PDO::commit() 또는 PDO::rollBack()을 사용하여 트랜잭션에서 실행 중인 코드가 성공했는지 여부에 따라 트랜잭션을 종료할 수 있습니다.
스크립트가 종료되거나 연결이 닫히려고 할 때 미해결 트랜잭션이 있는 경우 PDO는 자동으로 트랜잭션을 롤백합니다. 이는 스크립트가 비정상적으로 종료되는 경우 불일치를 방지하는 데 도움이 되는 안전 조치입니다. 트랜잭션이 명시적으로 커밋되지 않으면 어딘가에 불일치가 있다고 가정하므로 데이터 보안을 유지하기 위해 롤백이 수행됩니다.
//http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505furlong/index.html 의 예
노력하다{
$dbh=새 PDO('odbc:SAMPLE','db2inst1','ibmdb2',
배열(PDO_ATTR_PERSISTENT=>참));
echo"연결됨n";
$dbh->setAttribute(PDO_ATTR_ERRMODE,PDO_ERRMODE_EXCEPTION);
$dbh->beginTransaction();
$dbh->exec("직원(ID, 이름, 마지막) 값에 삽입 (23, 'Joe', 'Bloggs')");
$dbh->exec("급여변경에 삽입(ID, 금액, 변경된 날짜)
값 (23, 50000, NOW())");
$dbh->커밋();
}catch(예외 $e){
$dbh->롤백();
echo"실패: ".$e->getMessage();
}
위의 예에서는 ID 번호가 23인 신입 직원에 대한 항목 세트를 생성한다고 가정합니다. 개인의 기본 데이터를 입력하는 것 외에도 직원의 급여도 기록해야 합니다. 두 업데이트를 개별적으로 수행하는 것은 간단하지만 BeginTransaction() 및 commit() 호출에 두 업데이트를 모두 포함하면 완료될 때까지 다른 사람이 변경 사항을 볼 수 없도록 할 수 있습니다. 오류가 발생하면 catch 블록은 트랜잭션 시작 이후 발생한 모든 변경 사항을 롤백하고 오류 메시지를 인쇄할 수 있습니다.
트랜잭션 내에서 업데이트를 수행할 필요는 없습니다. 또한 복잡한 쿼리를 실행하여 데이터를 추출하고 해당 정보를 사용하여 추가 업데이트 및 쿼리를 작성할 수도 있습니다. 트랜잭션이 활성화되면 작업이 진행되는 동안 다른 사람이 변경할 수 없다는 것이 보장됩니다. 사실 100% 맞는 것은 아니지만 이전에 거래에 대해 들어본 적이 없다면 좋은 소개가 될 것입니다.
★Prepared 문 및 저장 프로시저 더 많은 성숙한 데이터베이스가 준비된 문 개념을 지원합니다. 준비된 진술이란 무엇입니까? 준비된 명령문은 실행하려는 SQL의 컴파일된 템플릿으로 생각할 수 있으며, 이는 변수 매개변수를 사용하여 사용자 정의할 수 있습니다. 준비된 문은 두 가지 주요 이점을 제공합니다.
쿼리는 한 번만 구문 분석(또는 준비)하면 되지만 동일하거나 다른 매개 변수를 사용하여 여러 번 실행할 수 있습니다. 쿼리가 준비되면 데이터베이스는 쿼리 실행 계획을 분석, 컴파일 및 최적화합니다. 복잡한 쿼리의 경우 이 프로세스가 더 오래 걸리며, 다른 매개변수를 사용하여 동일한 쿼리를 여러 번 반복해야 하는 경우 애플리케이션 속도가 크게 느려질 수 있습니다. 준비된 문을 사용하면 반복적인 분석/컴파일/최적화 주기를 피할 수 있습니다. 간단히 말해서, 준비된 명령문은 더 적은 리소스를 사용하므로 더 빠르게 실행됩니다.
준비된 명령문에 제공된 매개변수는 따옴표로 묶을 필요가 없습니다. 드라이버가 이를 처리합니다. 애플리케이션이 준비된 명령문을 독점적으로 사용하는 경우 SQL 침입이 발생할 수 없다는 것을 확신할 수 있습니다. (그러나 여전히 신뢰할 수 없는 입력을 쿼리의 다른 부분에 기반으로 하는 경우 여전히 위험이 있습니다.)
준비된 문은 매우 유용하므로 PDO는 실제로 목표 4에 설정된 규칙을 위반합니다. 드라이버가 준비된 문을 지원하지 않으면 PDO는 준비된 문을 에뮬레이트합니다.
예: PDO 적용 예:
<?php
'
;//데이터베이스 유형 Oracle은 ODI를 사용합니다. 개발자의 경우 다른 데이터베이스를 사용하면 이를 변경하기만 하면 많은 기능을 기억할 필요가 없습니다.
호스트 이름
$dbName='test';//사용된 데이터베이스
$user='root';//데이터베이스 연결 사용자 이름
$pass='';//해당 비밀번호
$dsn="$dbms:host=$host;dbname= $db이름";
클래스확장PDO{
publicfunction__construct(){
노력하다{
parent::__construct("$GLOBALS[dsn]",$GLOBALS['사용자'],$GLOBALS['pass']);
}캐치(PDOException$e){
die("오류: ".$e->__toString()."<br/>");
}
}
공개최종함수쿼리($sql){
노력하다{
returnparent::query($this->setString($sql));
}캐치(PDOException$e){
die("오류: ".$e->__toString()."<br/>");
}
}
privatefinalfunctionsetString($sql){
echo "$sql을 처리하고 싶습니다";
$sql을 반환;
}
}
$db=newdb();
$db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER);
foreach($db->query('SELECT * from xxxx_menu')as$row){
print_r($행);
}
$db->exec(''xxxx_menu`에서 삭제, mid=43');
?>