티스토리 뷰

오늘도 개발자/PHP

[PHP] MySQLi

오늘도공대생 2022. 1. 31. 01:28

PHP에는 mysql과 mysqli가 있습니다.

mysql은 오래전 사용되었고 현재에는 mysql을 개선한 mysqli가 있으므로 mysqli를 사용하시는게 좋습니다.

 

 

MySQL 서버에 대한 새 연결 열기

  • mysqli::__construct
  • mysqli::connect
  • mysqli_connect

 

객체지향 style

public mysqli::__construct(
    string $hostname = ini_get("mysqli.default_host"),
    string $username = ini_get("mysqli.default_user"),
    string $password = ini_get("mysqli.default_pw"),
    string $database = "",
    int $port = ini_get("mysqli.default_port"),
    string $socket = ini_get("mysqli.default_socket")
)
public mysqli::connect(
    string $hostname = ini_get("mysqli.default_host"),
    string $username = ini_get("mysqli.default_user"),
    string $password = ini_get("mysqli.default_pw"),
    string $database = "",
    int $port = ini_get("mysqli.default_port"),
    string $socket = ini_get("mysqli.default_socket")
): void
절차지향 style
mysqli_connect(
    string $hostname = ini_get("mysqli.default_host"),
    string $username = ini_get("mysqli.default_user"),
    string $password = ini_get("mysqli.default_pw"),
    string $database = "",
    int $port = ini_get("mysqli.default_port"),
    string $socket = ini_get("mysqli.default_socket")
): mysqli|false

 

 

 

데이터베이스에 대한 쿼리를 수행합니다. 

public mysqli::query(string $query, int $result_mode = MYSQLI_STORE_RESULT): mysqli_result|bool

mysqli_query(mysqli $mysql, string $query, int $result_mode = MYSQLI_STORE_RESULT): mysqli_result|bool

 

※ 쿼리에 변수 입력이 포함된 경우 매개변수화된 준비된 명령문 을 대신 사용해야 합니다. 또는 데이터 형식이 적절해야 하며 모든 문자열은 mysqli_real_escape_string() 함수를 사용하여 이스케이프되어야 합니다. 데이터베이스 관련 함수를 사용할 때는 언제나 SQL injection에 주의하여야 합니다.

 

객체 지향 스타일

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* Create table doesn't return a resultset */
$mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City");
printf("Table myCity successfully created.\n");

/* Select queries return a resultset */
$result = $mysqli->query("SELECT Name FROM City LIMIT 10");
printf("Select returned %d rows.\n", $result->num_rows);

$result = $mysqli->query("SELECT * FROM City", MYSQLI_USE_RESULT);

$mysqli->query("SET @a:='this will not work'");

절차적 스타일

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* Create table doesn't return a resultset */
mysqli_query($link, "CREATE TEMPORARY TABLE myCity LIKE City");
printf("Table myCity successfully created.\n");

/* Select queries return a resultset */
$result = mysqli_query($link, "SELECT Name FROM City LIMIT 10");
printf("Select returned %d rows.\n", mysqli_num_rows($result));

/* If we have to retrieve large amount of data we use MYSQLI_USE_RESULT */
$result = mysqli_query($link, "SELECT * FROM City", MYSQLI_USE_RESULT);

mysqli_query($link, "SET @a:='this will not work'");

 

 

실행을 위한 SQL 문 준비

  • mysqli::preparde
  • mysqli_prepare

public mysqli::prepare(string $query): mysqli_stmt|false

 

mysqli_prepare(mysqli $mysql, string $query): mysqli_stmt|false

 

SQL 쿼리를 준비하고 명령문에 대한 추가 작업에 사용할 명령문 핸들을 반환합니다. 쿼리는 단일 SQL 문으로 구성되어야 합니다.절차지향적 방식인 mysql_prepare()의 경우  mysqli_connect() 또는 mysqli_init( )에 의해 반환된 mysqli 객체를 $mysql로 넘겨 주여야 합니다.

명령문 템플릿에는 자리 표시자라고도 하는 0개 이상의 물음표( ?) 매개변수 마커가 포함될 수 있습니다. 매개변수 마커는 명령문을 실행하기 전에 mysqli_stmt_bind_param() 을 사용하여 애플리케이션 변수에 바인딩되어야 합니다. 일반적으로 매개변수는 DML(데이터 조작 언어) 문에서만 유효하고 DDL(데이터 정의어) 문에서는 유효하지 않습니다.

마커는 SQL 문의 특정 위치에서만 유효합니다. 예를 들어, 명령문의 VALUES() 목록 INSERT(행에 대한 열 값 지정)에서 또는 WHERE비교 값을 지정하기 위해 절의 열과의 비교에서 허용됩니다.
그러나 식별자(예: 테이블 또는 열 이름)에 대해 또는 =등호와 같은 이항 연산자의 두 피연산자를 모두 지정하는 데에는 허용되지 않습니다. 후자의 제한은 매개변수 유형을 결정하는 것이 불가능하기 때문에 필요합니다. 일반적으로 매개변수는 DML(데이터 조작 언어) 문에서만 유효하고 DDL(데이터 정의어) 문에서는 유효하지 않습니다.

 

 

예제 #1 mysqli::prepare() 예제

객체 지향 스타일

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$city = "Amersfoort";

/* create a prepared statement */
$stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?");

/* bind parameters for markers */
$stmt->bind_param("s", $city);

/* execute query */
$stmt->execute();

/* bind result variables */
$stmt->bind_result($district);

/* fetch value */
$stmt->fetch();

printf("%s is in district %s\n", $city, $district);

절차적 스타일

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

$city = "Amersfoort";

/* create a prepared statement */
$stmt = mysqli_prepare($link, "SELECT District FROM City WHERE Name=?");

/* bind parameters for markers */
mysqli_stmt_bind_param($stmt, "s", $city);

/* execute query */
mysqli_stmt_execute($stmt);

/* bind result variables */
mysqli_stmt_bind_result($stmt, $district);

/* fetch value */
mysqli_stmt_fetch($stmt);

printf("%s is in district %s\n", $city, $district);

 

 

 

 

public mysqli_stmt::get_result(): mysqli_result|false

mysqli_stmt_get_result(mysqli_stmt $statement): mysqli_result|false

준비된 명령문에서 결과 집합을 mysqli_result 객체 로 가져옵니다. 데이터는 MySQL 서버에서 PHP로 가져옵니다. 이 메서드는 결과 집합을 생성하는 쿼리에 대해서만 호출해야 합니다.

이 함수는 mysqli_stmt_store_result()와 함께 사용할 수 없습니다 . 이 두 함수는 모두 MySQL 서버에서 전체 결과 세트를 검색합니다.

 

 

 

트렌젝션

mysqli는 기본적으로 오토 커밋을 하게 된다. 커밋을 해야 실제 Database에 적용이 된다. 커밋전에 롤백하게 되면 그동안 작업한 내용들은 실제 Database에 적용되지 않는다.

mysqli::autocommit ,  mysqli_autocommit  데이터베이스 수정 자동 커밋을 켜거나 끕니다.

참고로 트렌젝션 중 일부 에러가 발생한다면 전체 트렌젝션이 적용되지 않습니다. (틀렸다면 댓글 남겨 주세요)

public mysqli::autocommit(bool $enable): bool
mysqli_autocommit(mysqli $mysql, bool $enable): bool
 
/* 오류가 발생하면 예외를 던지도록 mysqli에 지시 */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = mysqli_connect("localhost", "my_user", "my_password", "world");

/* 테이블 엔진이 트랜잭션을 지원해야 합니다 */
mysqli_query($mysqli, "CREATE TABLE IF NOT EXISTS language (
    Code text NOT NULL,
    Speakers int(11) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

/* 자동 커밋 끄기 */
mysqli_autocommit($mysqli, false);

$result = mysqli_query($mysqli, "SELECT @@autocommit");
$row = mysqli_fetch_row($result);
printf("Autocommit is %s\n", $row[0]);

try {
    /* Prepare insert */
    $stmt = mysqli_prepare($mysqli, 'INSERT INTO language(Code, Speakers) VALUES (?,?)');
    mysqli_stmt_bind_param($stmt, 'ss', $language_code, $native_speakers);

    /* Insert some values */
    $language_code = 'DE';
    $native_speakers = 50_123_456;
    mysqli_stmt_execute($stmt);
    $language_code = 'FR';
    $native_speakers = 40_546_321;
    mysqli_stmt_execute($stmt);

    /* 데이터베이스의 데이터를 커밋합니다. 이것은 autocommit=true로 설정되지 않습니다 */
    mysqli_commit($mysqli);
    print "Committed 2 rows in the database\n";

    $result = mysqli_query($mysqli, "SELECT @@autocommit");
    $row = mysqli_fetch_row($result);
    printf("Autocommit is %s\n", $row[0]);

    /* Try to insert more values */
    $language_code = 'PL';
    $native_speakers = 30_555_444;
    mysqli_stmt_execute($stmt);
    $language_code = 'DK';
    $native_speakers = 5_222_444;
    mysqli_stmt_execute($stmt);

    /* autocommit=true로 설정하면 커밋이 트리거됩니다. */
    mysqli_autocommit($mysqli, true);

    print "Committed 2 row in the database\n";
} catch (mysqli_sql_exception $exception) {
    mysqli_rollback($mysqli);

    throw $exception;
}

 

 

 

 


MySQL 개선된 확장

'오늘도 개발자 > PHP' 카테고리의 다른 글

[PHP] 파일(file)  (0) 2022.01.31
[PHP] 에러 리포팅(Error Reporting)  (0) 2022.01.31
[PHP]System program execution  (0) 2022.01.31
[PHP]Output Buffering Control  (0) 2022.01.30
[PHP] 스트림(Streams)  (0) 2022.01.30
댓글