MySQLi
MySQLiMySQLi Extension(MySQL 개선됨)은 MySQL 데이터베이스와의 인터페이스를 제공하기 위해 PHP 스크립팅 언어에 사용되는 관계형 데이터베이스 드라이버다.
MySQL 데이터베이스 서버 연결을 고려할 때 다음과 같은 3가지 주요 API 옵션이 있다.
- PHP의 MySQL 확장
- PHP의 MySQLi 확장
- PHP 데이터 개체(PDO)
PHP 코드는 코어(core)로 구성되며, 코어 기능에는 옵션으로 확장된다.MySQLi 확장, MySQL 확장 등 PHP의 MySQL 관련 확장은 PHP 확장 프레임워크를 사용하여 구현된다.증축은 일반적으로 PHP 개발자에게 API를 노출시켜 그것의 설비가 프로그램적으로 사용될 수 있도록 한다.그러나 PHP 확장 프레임워크를 사용하는 일부 확장은 API를 PHP 개발자에게 노출시키지 않는다.
예를 들어 PDO MySQL 드라이버 확장은 API를 PHP 개발자에게 노출하지 않고 그 위의 PDO 계층에 인터페이스를 제공한다.
MySQLi는 이전 버전의 PHP MySQL 드라이버로 다양한 혜택을 제공한다.[1]
PHP 스크립팅 언어의 저자는 MySQL 서버 버전 4.1.3 이상을 다룰 때 MySQLi를 사용할 것을 권장한다(새로운 기능을 활용함).[1]
기술적 세부사항
MySQLi 확장은 이전 버전과 관련하여 다양한 혜택을 제공하며, PHP 웹사이트에[1] 따르면 가장 두드러진 기능은 다음과 같다.
형상비교
| PHP의 MySQLi 확장 | PDO | PHP의 MySQL 확장 | |
|---|---|---|---|
| PHP 버전이 도입됨 | 5.0 | 5.0 | 3.0 이전 |
| PHP 5.x에 포함 | 네 | 네 | 네 |
| PHP 7.x에 포함 | 네 | 네 | 아니요. |
| 개발여부 | 능동개발 | PHP 5.3 기준 적극적 개발 | PHP 5.5 현재 사용되지 않음 PHP 7.0에서 제거됨 |
| MySQL에서 새 프로젝트에 권장 | 예 - 선호 옵션 | 네 | 아니요. |
| API에서 문자 집합 지원 | 네 | 네 | 아니요. |
| API에서 서버측 준비 문 지원 | 네 | 네 | 아니요. |
| API에서 클라이언트측 준비된 문 지원 | 아니요. | 네 | 아니요. |
| API에서 저장 프로시저를 지원 | 네 | 네 | 아니요. |
| API에서 다중 문 지원 | 네 | 대부분 | 아니요. |
| 모든 MySQL 4.1 이상 기능 지원 | 네 | 대부분 | 아니요. |
시작 안내서
듀얼 인터페이스
MySQLi 확장자는 절차적 및 객체 지향적 프로그래밍 패러다임을 모두 지원하는 이중 인터페이스를 특징으로 한다.
이전 MySQL 확장자에서 마이그레이션하는 사용자는 절차 인터페이스를 선호할 수 있다.절차 인터페이스는 이전 MySQL 확장의 인터페이스와 유사하다.함수 이름은 접두사별로만 차이가 나는 경우가 많다.일부 MySQLi 함수는 연결 핸들을 첫 번째 인수로 사용하는 반면, 이전 MySQL 인터페이스의 일치 함수는 이 핸들을 선택적 마지막 인수로 받아들였다.
새 및 이전 기본 함수 호출
<?php $mysqli = mysqli_connect("example.com", "사용자", "비밀번호", "database"); 달러화 = mysqli_mysqli_mission($mysqli, "SELECT * from myDatabase"); 메아리치다 mysqli_num_rows(달러화); $mysql = mysql_connect("example.com", "사용자", "비밀번호"); mysql_select_db("database"); $res = mysql_sql("SELECT * from myDatabase", $mysql); 메아리치다 mysql_num_rows(달러화); ?> 연결
MySQL 서버는 연결을 위해 서로 다른 전송 계층의 사용을 지원한다.연결은 TCP/IP, Unix 도메인 소켓 또는 Windows 명명된 파이프를 사용한다.
호스트 이름localhost특별한 의미가 있다.그것은 유닉스 도메인 소켓의 사용에 구속되어 있다.호스트 이름을 사용하여 TCP/IP 연결을 열 수 없음localhost사용해야만 한다127.0.0.1대신에
예localhost의 특별한 의미
<?php $mysqli = 새로운 mysqli("localhost", "사용자", "비밀번호", "database"); 만일 ($mysqli->connect_cnectno) { 메아리치다 "MySQL에 연결하지 못함: (") . $mysqli->connect_cnectno . ") " . $mysqli->connect_message; } 메아리치다 $mysqli->host_message . "\n"; $mysqli = 새로운 mysqli("127.0.0.1", "사용자", "비밀번호", "database", 3306); 만일 ($mysqli->connect_cnectno) { 메아리치다 "MySQL에 연결하지 못함: (") . $mysqli->connect_cnectno . ") " . $mysqli->connect_message; } 메아리치다 $mysqli->host_message . "\n"; ?> 출력
TCP/IP를 통한 UNIX 소켓 127.0.0.1을 통한 로컬 호스트
명령문 실행 중
문은 mysqli_query(), mysqli_real_query() 및 mysqli_multi_query() 함수로 실행할 수 있다.mysqli_query() 함수가 가장 일반적이며, 실행 문과 결과 집합의 버퍼링된 가져오기(있는 경우)를 하나의 통화로 결합한다.mysqli_query()를 호출하는 것은 mysqli_real_query() 다음에 mysqli_store_result()를 호출하는 것과 동일하다.
예: MySQL에 연결
<?php $mysqli = 새로운 mysqli("example.com", "사용자", "비밀번호", "database"); 만일 ($mysqli->connect_cnectno) { 메아리치다 "MySQL에 연결하지 못함: (") . $mysqli->connect_cnectno . ") " . $mysqli->connect_message; } 만일 (!$mysqli->질의하다("시험이 있는 경우 테이블 삭제") !$mysqli->질의하다("CREATE TABLE test(ID INT)") !$mysqli->질의하다("시험(id) 값에 삽입(1)")) { 메아리치다 "테이블 생성 실패: (") . $mysqli->실수하지 않다 . ") " . $mysqli->착오; } ?> 버퍼링된 결과 집합
애프터 문 실행 결과를 한 번에 검색하여 클라이언트에 의해 버퍼링되거나 행별로 읽혀질 수 있다.클라이언트측 결과 집합 버퍼링은 서버가 가능한 빨리 문 결과와 관련된 자원을 확보할 수 있도록 한다.일반적으로 말해서, 고객들은 결과들을 느리게 소비하고 있다.따라서 버퍼링된 결과 집합을 사용하는 것이 좋다. mysqli_query()는 문 실행과 결과 집합 버퍼링을 결합한다.
PHP 애플리케이션은 버퍼링된 결과를 통해 자유롭게 탐색할 수 있다.결과 세트가 클라이언트 메모리에 저장되기 때문에 탐색 속도가 빠르다.서버를 확장하는 것보다 클라이언트에 의해 확장하는 것이 종종 더 쉽다는 것을 명심하십시오.
예: 버퍼링된 결과를 탐색
<?php $mysqli = 새로운 mysqli("example.com", "사용자", "비밀번호", "database"); 만일 ($mysqli->connect_cnectno) { 메아리치다 "MySQL에 연결하지 못함: (") . $mysqli->connect_cnectno . ") " . $mysqli->connect_message; } 만일 (!$mysqli->질의하다("시험이 있는 경우 테이블 삭제") !$mysqli->질의하다("CREATE TABLE test(ID INT)") !$mysqli->질의하다("시험(id) 값(1), (2) (3)에 삽입")) { 메아리치다 "테이블 생성 실패: (") . $mysqli->실수하지 않다 . ") " . $mysqli->착오; } $res = $mysqli->질의하다("ID ASC별 테스트 오더에서 ID 선택"); 메아리치다 "역순서...\n"; 을 위해 ($row_no = $res->num_rows - 1; $row_no >= 0; $row_no--) { $res->data_seek($row_no); 달러화 = $res->fetch_association(); 메아리치다 " id = " . 달러화['id'] . "\n"; } 메아리치다 "결과 설정 순서...\n"; $res->data_seek(0); 하는 동안에 (달러화 = $res->fetch_association()) { 메아리치다 " id = " . 달러화['id'] . "\n"; } ?> 위의 예제가 출력된다.
역순서...id = 3 id = 2 id = 1 결과 집합 순서...id = 1 id = 2 id = 3
버퍼링되지 않은 결과 집합
클라이언트 메모리가 짧은 자원이고 서버 로드를 낮게 유지하기 위해 가능한 일찍 서버 자원을 확보할 필요가 없다면, 버퍼링되지 않은 결과를 사용할 수 있다.모든 행을 읽기 전에는 버퍼링되지 않은 결과를 스크롤할 수 없다.
예: 버퍼링되지 않은 결과를 탐색
<?php $mysqli->real_message("ID ASC별 테스트 오더에서 ID 선택"); $res = $mysqli->use_use(); 메아리치다 "결과 설정 순서...\n"; 하는 동안에 (달러화 = $res->fetch_association()) { 메아리치다 " id = " . 달러화['id'] . "\n"; } ?> 결과 집합 값 데이터 유형
mysqli_query(), mysqli_real_query() 및 mysqli_multi_query() 함수를 사용하여 준비되지 않은 문장을 실행한다.MySQL Client Server Protocol 수준에서는 COM_QUERY 명령어와 텍스트 프로토콜이 문 실행에 사용된다.텍스트 프로토콜을 사용하여 MySQL 서버는 결과 집합의 모든 데이터를 문자열로 변환한 후 전송한다.이 변환은 SQL result set column data type에 관계없이 수행된다.MySQL 클라이언트 라이브러리는 모든 열 값을 문자열로 수신한다.기둥을 다시 고유 유형으로 변환하기 위해 클라이언트 측 주물은 더 이상 수행되지 않는다.대신 모든 값은 PHP 문자열로 제공된다.
예:텍스트 프로토콜이 기본적으로 문자열을 반환함
<?php $mysqli = 새로운 mysqli("example.com", "사용자", "비밀번호", "database"); 만일 ($mysqli->connect_cnectno) { 메아리치다 "MySQL에 연결하지 못함: (") . $mysqli->connect_cnectno . ") " . $mysqli->connect_message; } 만일 (!$mysqli->질의하다("시험이 있는 경우 테이블 삭제") !$mysqli->질의하다("CREATE TABLE test(ID INT, 라벨 CHAR(1))") !$mysqli->질의하다("시험(id, label) 값(1, 'a')에 삽입")) { 메아리치다 "테이블 생성 실패: (") . $mysqli->실수하지 않다 . ") " . $mysqli->착오; } $res = $mysqli->질의하다("SELECT id, 라벨 FROM test where id = 1"); 달러화 = $res->fetch_association(); 활자화하다("id = %s(%s)\n", 달러화['id'], 활자를 맞추다(달러화['id'])); 활자화하다("csv = %s(%s)\n", 달러화['label'], 활자를 맞추다(달러화['label'])); ?> 위의 예제가 출력된다.
id = 1 (문자열) 레이블 = a (문자
MYSQLI_OPT_를 설정하여 정수 및 플로트 열을 다시 PHP 번호로 변환할 수 있다.mysqlnd 라이브러리를 사용하는 경우 INT_AND_FLOAT_NATE 연결 옵션.mysqlnd 라이브러리는 결과 집합 메타 데이터 열 유형을 확인하고 PHP 데이터 유형 값 범위가 허용하면 숫자 SQL 열을 PHP 번호로 변환한다.예를 들어 SQL INT 열은 정수로 반환된다.
예: mysqlnd 및 연결 옵션이 있는 기본 데이터 유형
<?php $mysqli = mysqli_init(); $mysqli->옵션들(MYSQLI_OPT_INT_AND_FLOAT_NATE, 1); $mysqli->real_connect("example.com", "사용자", "비밀번호", "database"); 만일 ($mysqli->connect_cnectno) { 메아리치다 "MySQL에 연결하지 못함: (") . $mysqli->connect_cnectno . ") " . $mysqli->connect_message; } 만일 (!$mysqli->질의하다("시험이 있는 경우 테이블 삭제") !$mysqli->질의하다("CREATE TABLE test(ID INT, 라벨 CHAR(1))") !$mysqli->질의하다("시험(id, label) 값(1, 'a')에 삽입")) { 메아리치다 "테이블 생성 실패: (") . $mysqli->실수하지 않다 . ") " . $mysqli->착오; } $res = $mysqli->질의하다("SELECT id, 라벨 FROM test where id = 1"); 달러화 = $res->fetch_association(); 활자화하다("id = %s(%s)\n", 달러화['id'], 활자를 맞추다(달러화['id'])); 활자화하다("csv = %s(%s)\n", 달러화['label'], 활자를 맞추다(달러화['label'])); ?> 위의 예제가 출력된다.
id = 1(수직) 레이블 = a(문자열)
작성된 명세서
MySQL 데이터베이스는 준비된 문장을 지원한다.준비된 문장이나 매개 변수화된 문장은 동일한 문장을 고효율적으로 반복적으로 실행하는 데 사용된다.
기본 워크플로우
작성된 진술서 실행은 작성과 실행의 두 단계로 구성된다.준비 단계에서 문 템플릿은 데이터베이스 서버로 전송된다.서버는 구문 검사를 수행하고 나중에 사용할 수 있도록 서버 내부 자원을 초기화한다.
MySQL 서버는 ?와 함께 익명의 위치 자리 표시자 사용을 지원한다.
예제를 참조하십시오.[3]
저장 프로시저
MySQL 데이터베이스는 저장 프로시저를 지원한다.저장 프로시저는 데이터베이스 카탈로그에 저장된 서브루틴이다.애플리케이션은 저장 프로시저를 호출하고 실행할 수 있다.CALL SQL 문은 저장 프로시저를 실행하는 데 사용된다.
매개변수
MySQL 버전에 따라 저장 프로시저에는 IN, INOUT 및 OUT 매개 변수가 있을 수 있다.MySQLi 인터페이스는 다양한 종류의 매개 변수에 대해 특별한 개념이 없다.
IN 매개변수
입력 매개변수는 CALL 문과 함께 제공된다.값이 올바르게 이스케이프되었는지 확인하십시오.
의 예를 참조하십시오.[4]
다중문
MySQL은 선택적으로 하나의 문 문자열에 여러 개의 문을 갖는 것을 허용한다.한 번에 여러 개의 문구를 보내면 클라이언트-서버 라운드 트립은 줄지만 특별한 처리가 필요하다.
mysqli_multi_query()를 사용하여 다중 문 또는 다중 쿼리를 실행해야 한다.문 문자열의 개별 문장은 세미콜론으로 구분된다.그런 다음 실행된 명령문으로 반환되는 모든 결과 집합을 가져와야 한다.
MySQL 서버는 결과 집합을 반환하는 문과 결과 집합을 반환하지 않는 문을 하나의 다중 문으로 만들 수 있다.
예제 참조
트랜잭션에 대한 API 지원
MySQL 서버는 사용되는 스토리지 엔진에 따라 트랜잭션을 지원한다.MySQL 5.5 이후 기본 스토리지 엔진은 InnoDB이다.InnoDB는 완전한 AIDE 거래 지원을 가지고 있다.
트랜잭션은 SQL 또는 API 호출을 사용하여 제어할 수 있다.자동 커밋 모드를 활성화 및 비활성화하고 트랜잭션을 커밋 및 롤백할 때는 API 호출을 사용하는 것이 좋다.
여기 예시들.[6]
메타데이터
MySQL 결과 집합에는 메타데이터가 포함되어 있다.메타데이터는 결과 집합에서 발견된 열을 설명한다.MySQL이 전송하는 모든 메타데이터는 MySQLi 인터페이스를 통해 액세스할 수 있다.확장은 수신하는 정보에 대해 어떠한 변경도 수행하지 않거나 무시할 수 있다.MySQL 서버 버전 간의 차이가 정렬되지 않음.
mysqli_result 인터페이스를 통한 메타 데이터 액세스.
여기서 자세히 보십시오.[7]
MySQLi 확장 및 영구 연결
지속적인 연결 지원은 MySQLi 확장에 대해 PHP 5.3에 도입되었다.지원은 이미 PDO MYSQL 및 ext/mysql에서 제공되었다.지속적인 연결의 이면에 있는 아이디어는 클라이언트 프로세스와 데이터베이스 사이의 연결이 여러 번 생성되고 파괴되는 것이 아니라 클라이언트 프로세스에 의해 재사용될 수 있다는 것이다.이렇게 하면 사용하지 않는 연결이 캐시되어 재사용할 준비가 되므로 필요할 때마다 새 연결을 만드는 오버헤드가 감소한다.
MySQL 확장자와 달리 MySQLi는 영구 연결을 여는 별도의 기능을 제공하지 않는다.영구 연결을 열려면 연결할 때 p:를 호스트 이름으로 미리 전송하십시오.
지속적인 연결의 문제는 클라이언트에 의해 예측할 수 없는 상태로 남겨질 수 있다는 것이다.예를 들어, 테이블 잠금은 클라이언트가 예기치 않게 종료되기 전에 활성화될 수 있다.이 영구 연결을 재사용하는 새로운 클라이언트 프로세스는 "있는 그대로" 연결을 얻는다.모든 정리는 새로운 클라이언트 프로세스에 의해 수행되어야만 지속적인 연결을 잘 활용할 수 있고 프로그래머의 부담을 증가시킬 수 있을 것이다.
그러나 MySQLi 확장의 지속적인 연결은 내장된 정리 처리 코드를 제공한다.MySQLi에서 수행하는 정리에는 다음이 포함된다.
- 활성 트랜잭션 롤백
- 임시 테이블 닫기 및 삭제
- 테이블 잠금 해제
- 세션 변수 재설정
- 준비된 문장 닫기(PHP와 함께 항상 발생)
- 클로즈 핸들러
- GET_LOCK()으로 획득한 해제 잠금
이렇게 하면 클라이언트 프로세스가 영구 연결을 사용하기 전에 연결 풀에서 반환할 때 영구 연결이 깨끗한 상태에 있게 된다.
MySQLi 확장자는 C-API 함수 mysql_change_user()를 자동으로 호출하여 이 정리를 수행한다.
하지만 자동 정리 기능은 장단점이 있다.개발자가 자동으로 호출되기 때문에 더 이상 정리코드 추가에 대해 걱정할 필요가 없다는 것이 장점이다.그러나 연결 풀에서 연결이 반환될 때마다 정리를 수행하기 위한 코드가 실행되어야 하기 때문에 코드가 약간 더 느릴 수 있다는 단점이 있다.
MYSQLI_NO_CHANGE_USER_ON_PCONNECT를 정의한 상태에서 PHP를 컴파일하여 자동 정리 코드를 끌 수 있다.
참고: MySQLi 확장 기능은 MySQL Native Driver 또는 MySQL Client Library를 사용할 때 영구 연결을 지원함.
참조
- ^ a b c d e "Overview - Manual". PHP. Retrieved August 11, 2014.
- ^ "PHP: Quick start guide - Manual". In2.php.net. Retrieved August 11, 2014.
- ^ "PHP: Prepared Statements - Manual". In2.php.net. Retrieved August 11, 2014.
- ^ a b Jonathon (May 24, 2013). "PHP: Stored Procedures - Manual". In2.php.net. Retrieved August 11, 2014.
- ^ a b eric dot noel at gmail dot com (March 31, 2014). "PHP: Multiple Statements - Manual". In2.php.net. Retrieved August 11, 2014.
- ^ a b "PHP: API support for transactions - Manual". In2.php.net. Retrieved August 11, 2014.
- ^ a b "PHP: Metadata - Manual". In2.php.net. Retrieved August 11, 2014.