[PHP] MySQLi

Seo Joonsoo·2022년 6월 25일
0

php

목록 보기
20/23

PHP에는 mysqlmysqli가 있습니다.

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

  • mysqli_prepare() - 실행을 위해 SQL 문을 준비합니다.
  • mysqli_stmt_result_metadata() - 준비된 명령문에서 결과 세트 메타데이터를 반환합니다.
  • mysqli_stmt_fetch() - 준비된 명령문에서 바인딩된 변수로 결과를 가져옵니다.
  • mysqli_fetch_array() - 결과 세트의 다음 행을 연관, 숫자 배열 또는 둘 다로 가져옵니다.
  • mysqli_stmt_store_result() - 결과 세트를 내부 버퍼에 저장

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 개선된 확장

이와 관련된 내용은 공식 자료를 살펴보시기 바라며 링크는 아래에 기록되어 있습니다.
Velog가 링크까지 복사를 못해오네요

https://paric.tistory.com/790

profile
여러분들 삶에 한 획을 더하고 싶습니다.

0개의 댓글