Русскоязычная документация находится тут
아카이브로 다운로드하거나, 이 사이트에서 복제하거나, 작곡가를 통해 다운로드할 수 있습니다(packagist.org 링크).
composer require krugozor/database
krugozor/database
란 무엇입니까? krugozor/database
PHP 확장 mysqli를 사용하여 MySql 데이터베이스에 대한 간단하고 편리하며 빠르고 안전한 작업을 위한 PHP >= 8.0 클래스 라이브러리입니다.
PHP에서 mysql 데이터베이스 작업 시 모든 라이브러리의 주요 단점은 다음과 같습니다.
int
및 float
으로 변환됩니다.krugozor/database
MySql 작업을 위한 클래스입니다.mysqli
및 mysqli_result
메커니즘을 모두 사용하여 작업에 필요한 메서드를 생성할 수 있습니다.krugozor/database
라이브러리가 아닌 것은 무엇입니까?다양한 데이터베이스 드라이버에 대한 대부분의 래퍼는 역겨운 아키텍처를 갖춘 쓸모없는 코드 묶음입니다. 래퍼 자체의 실제 목적을 이해하지 못한 작성자는 이를 일종의 빌더 쿼리(SQL 빌더), ActiveRecord 라이브러리 및 기타 ORM 솔루션으로 전환합니다.
krugozor/database
라이브러리는 위의 어느 것도 아닙니다. 이는 MySQL DBMS 프레임워크 내에서 일반 SQL 작업을 위한 편리한 도구일 뿐이며 그 이상은 아닙니다!
자리 표시자 — 명시적 값(쿼리 매개변수) 대신 SQL 쿼리 문자열에 기록되는 특수 유형의 마커입니다 . 그리고 값 자체는 SQL 쿼리를 실행하는 기본 메서드에 대한 후속 인수로 "나중에" 전달됩니다.
$ result = $ db -> query (
" SELECT * FROM `users` WHERE `name` = '?s' AND `age` = ?i " ,
" d'Artagnan " , 41
);
자리 표시자 시스템을 통해 전달된 SQL 쿼리 매개변수는 자리 표시자 유형에 따라 특수 이스케이프 메커니즘으로 처리됩니다. 저것들. 더 이상 이스케이프 함수 유형 mysqli_real_escape_string()
에서 변수를 래핑하거나 이전과 같이 숫자 유형으로 변환할 필요가 없습니다.
<?php
// Previously, before each request to the DBMS, we did
// something like this (and many people still don't do it):
$ id = ( int ) $ _POST [ ' id ' ];
$ value = mysqli_real_escape_string ( $ mysql , $ _POST [ ' value ' ]);
$ result = mysqli_query ( $ mysql , " SELECT * FROM `t` WHERE `f1` = ' $ value ' AND `f2` = $ id " );
이제 쿼리 작성이 쉽고 빠르며, 가장 중요한 것은 krugozor/database
라이브러리가 가능한 모든 SQL 주입을 완전히 방지한다는 것입니다.
필러의 종류와 목적은 다음과 같습니다. 필러 유형을 알아보기 전에 라이브러리 메커니즘이 어떻게 작동하는지 이해해야 합니다.
PHP는 약한 유형의 언어이므로 이 라이브러리를 개발할 때 이념적 딜레마가 발생했습니다. 다음과 같은 구조의 테이블이 있다고 가정해 보겠습니다.
` name ` varchar not null
` flag ` tinyint not null
라이브러리는 반드시(어떤 이유로든 개발자의 통제 범위를 넘어서) 다음 요청을 실행해야 합니다.
$ db -> query (
" INSERT INTO `t` SET `name` = '?s', `flag` = ?i " ,
null , false
);
이 예에서는 not null
텍스트 필드 name
에 null
값을 쓰고 flag
숫자 필드에 false
부울 유형을 쓰려고 시도합니다. 이런 상황에서 우리는 어떻게 해야 합니까?
tinyint
열의 false
값을 0
값으로 처리하고 null
name
열의 빈 문자열로 처리할 수 있습니까?제기된 질문을 고려하여 이 라이브러리에 두 가지 작동 모드를 구현하기로 결정했습니다.
Mysql::MODE_STRICT
모드에서 인수 유형은 자리 표시자 유형과 일치해야 합니다 . 예를 들어, 정수 자리 표시자 ?i
에 대한 인수로 값 55.5
또는 '55.5'
전달하려고 하면 예외가 발생합니다. // set strict mode
$ db -> setTypeMode (Mysql:: MODE_STRICT );
// this expression will not be executed, an exception will be thrown:
// attempt to specify a value of type "integer" for placeholder of type "double" in query template "SELECT ?i"
$ db -> query ( ' SELECT ?i ' , 55.5 );
Mysql::MODE_TRANSFORM
모드는 기본적으로 설정되어 있으며 "허용" 모드입니다. 자리 표시자 유형과 인수 유형이 일치하지 않으면 예외가 발생하지 않지만 다음을 사용하여 인수를 원하는 자리 표시자 유형으로 변환하려고 시도합니다. PHP 언어 자체 . 그건 그렇고, 나는 라이브러리 작성자로서 항상 이 특정 모드를 사용합니다. 실제 작업에서는 엄격 모드( Mysql::MODE_STRICT
)를 사용한 적이 없지만 아마도 특별히 필요할 것입니다. Mysql::MODE_TRANSFORM
에서는 다음 변환이 허용됩니다.
int
유형으로 캐스트(자리 표시자 ?i
)string
과 double
유형으로 표현되는 부동 소수점 숫자bool
TRUE는 int(1)
로 변환되고, FALSE는 int(0)
으로 변환됩니다.null
은 int(0)
으로 변환됩니다.double
유형으로 캐스트(자리 표시자 ?d
)string
및 int
유형으로 표현되는 정수bool
TRUE는 float(1)
이 되고, FALSE는 float(0)
이 됩니다.null
은 float(0)
으로 변환됩니다.string
로 캐스트(자리 표시자 ?s
)bool
TRUE는 string(1) "1"
로 변환되고, FALSE는 string(1) "0"
으로 변환됩니다. 이 동작은 PHP에서 bool
int
로 캐스팅하는 것과 다릅니다. 실제로 부울 유형은 MySql에서 숫자로 작성되는 경우가 많습니다.numeric
값은 PHP의 변환 규칙에 따라 문자열로 변환됩니다.null
은 string(0) ""
로 변환됩니다.null
유형으로 캐스트(자리 표시자 ?n
)krugozor/database
라이브러리에는 어떤 유형의 자리 표시자가 제공됩니까? ?i
— 정수 자리 표시자 $ db -> query (
' SELECT * FROM `users` WHERE `id` = ?i ' , 123
);
템플릿 변환 후 SQL 쿼리:
SELECT * FROM ` users ` WHERE ` id ` = 123
주목! PHP_INT_MAX
제한을 벗어난 숫자에 대해 작업을 수행하는 경우:
?s
(아래 참조)를 사용하세요. 요점은 PHP_INT_MAX
제한을 초과하는 숫자는 PHP가 부동 소수점 숫자로 해석한다는 것입니다. 라이브러리 파서는 매개변수를 int
유형으로 변환하려고 시도합니다. 결과적으로 " 결과는 정의되지 않습니다. 부동 소수점은 올바른 결과를 반환하기에 충분한 정밀도가 없기 때문입니다. 이 경우 경고나 설명도 표시되지 않습니다. ! ” — php.net. ?d
— 부동 소수점 자리 표시자 $ db -> query (
' SELECT * FROM `prices` WHERE `cost` IN (?d, ?d) ' ,
12.56 , ' 12.33 '
);
템플릿 변환 후 SQL 쿼리:
SELECT * FROM ` prices ` WHERE ` cost ` IN ( 12 . 56 , 12 . 33 )
주목! double
데이터 유형으로 작업하기 위해 라이브러리를 사용하는 경우 정수 부분과 소수 부분의 구분 기호가 PHP 수준과 DBMS 수준 모두에서 동일하도록 적절한 로케일을 설정하십시오.
?s
— 문자열 유형 자리 표시자 인수 값은 mysqli::real_escape_string()
메서드를 사용하여 이스케이프됩니다.
$ db -> query (
' SELECT "?s" ' ,
" You are all fools, and I am d'Artagnan! "
);
템플릿 변환 후 SQL 쿼리:
SELECT " You are all fools, and I am d'Artagnan! "
?S
— SQL LIKE 연산자의 대체를 위한 문자열 유형 자리 표시자 인수 값은 mysqli::real_escape_string()
메소드 + LIKE 연산자( %
및 _
)에 사용되는 특수 문자를 사용하여 이스케이프됩니다.
$ db -> query ( ' SELECT "?S" ' , ' % _ ' );
템플릿 변환 후 SQL 쿼리:
SELECT " % _ "
?n
— 자리 표시자 NULL
유형 모든 인수 값은 무시되고 자리 표시자는 SQL 쿼리에서 문자열 NULL
로 대체됩니다.
$ db -> query ( ' SELECT ?n ' , 123 );
템플릿 변환 후 SQL 쿼리:
SELECT NULL
?A*
— 연관 배열의 연관 집합 자리 표시자, key = value
형식의 쌍 시퀀스 생성 여기서 *
문자는 자리 표시자 중 하나입니다.
i
(정수 자리 표시자)d
(부동 자리 표시자)s
(문자열 유형 자리 표시자)변환 및 이스케이프 규칙은 위에서 설명한 단일 스칼라 유형과 동일합니다. 예:
$ db -> query (
' INSERT INTO `test` SET ?Ai ' ,
[ ' first ' => ' 123 ' , ' second ' => 456 ]
);
템플릿 변환 후 SQL 쿼리:
INSERT INTO ` test ` SET ` first ` = " 123 " , ` second ` = " 456 "
?a*
- 단순(또는 연관) 배열에서 자리 표시자를 설정하여 일련의 값을 생성합니다. 여기서 *
다음 유형 중 하나입니다.
i
(정수 자리 표시자)d
(부동 자리 표시자)s
(문자열 유형 자리 표시자)변환 및 이스케이프 규칙은 위에서 설명한 단일 스칼라 유형과 동일합니다. 예:
$ db -> query (
' SELECT * FROM `test` WHERE `id` IN (?ai) ' ,
[ 123 , 456 ]
);
템플릿 변환 후 SQL 쿼리:
SELECT * FROM ` test ` WHERE ` id ` IN ( " 123 " , " 456 " )
?A[?n, ?s, ?i, ...]
— 인수 유형 및 개수를 명시적으로 표시하는 연관 집합 자리 표시자, 일련의 key = value
쌍 생성예:
$ db -> query (
' INSERT INTO `users` SET ?A[?i, "?s"] ' ,
[ ' age ' => 41 , ' name ' => " d'Artagnan " ]
);
템플릿 변환 후 SQL 쿼리:
INSERT INTO ` users ` SET ` age ` = 41 , ` name ` = " d'Artagnan "
?a[?n, ?s, ?i, ...]
— 인수 유형 및 수를 명시적으로 표시하여 일련의 값을 생성하는 자리 표시자를 설정합니다.예:
$ db -> query (
' SELECT * FROM `users` WHERE `name` IN (?a["?s", "?s"]) ' ,
[ ' Daniel O"Neill ' , " d'Artagnan " ]
);
템플릿 변환 후 SQL 쿼리:
SELECT * FROM ` users ` WHERE ` name ` IN ( " Daniel O " Neill " , " d ' Artagnan")
?f
— 테이블 또는 필드 이름 자리 표시자이 자리 표시자는 테이블이나 필드의 이름이 쿼리에 매개 변수로 전달되는 경우를 위한 것입니다. 필드 및 테이블 이름은 아포스트로피로 표시됩니다.
$ db -> query (
' SELECT ?f FROM ?f ' ,
' name ' ,
' database.table_name '
);
템플릿 변환 후 SQL 쿼리:
SELECT ` name ` FROM ` database ` . ` table_name `
라이브러리에서는 프로그래머가 SQL 구문을 따라야 합니다. 이는 다음 쿼리가 작동하지 않음을 의미합니다.
$ db -> query (
' SELECT CONCAT("Hello, ", ?s, "!") ' ,
' world '
);
— 자리 표시자 ?s
작은따옴표나 큰따옴표로 묶어야 합니다.
$ db -> query (
' SELECT concat("Hello, ", "?s", "!") ' ,
' world '
);
템플릿 변환 후 SQL 쿼리:
SELECT concat( " Hello, " , " world " , " ! " )
PDO 작업에 익숙한 사람들에게는 이상하게 보일 수 있지만 어떤 경우에는 자리 표시자 값을 따옴표로 묶어야 하는지 여부를 결정하는 메커니즘을 구현하는 것은 전체 파서를 작성해야 하는 매우 중요하지 않은 작업입니다. .
./console/tests.php 파일을 참조하세요.