PHP / 함수 / mysqli_connect() / MySQL server 또는 MariaDB Server에 연결하는 함수

mysqli_connect()는 PHP의 mysqli 확장으로 MySQL 또는 MariaDB 서버에 연결하는 함수입니다. 연결 후 반환된 mysqli 객체로 쿼리를 실행할 수 있으며, 오류 처리 모드에 따라 실패 시 false를 반환하거나 예외를 발생시킵니다. PHP 8.1 이상에서는 기본 오류 모드가 예외 처리 방식이므로 false 검사만 있는 오래된 예제를 그대로 사용하지 않도록 주의해야 합니다.

연결 전에 준비할 정보와 인수

이 글은 PHP와 데이터베이스 서버가 설치되어 있고, 접근 가능한 데이터베이스와 전용 계정이 이미 준비된 상황을 다룹니다. 예제의 learning 데이터베이스와 learning_user는 설명용 이름이므로 실제로 준비한 값으로 바꾸세요. 함수 호출이 서버나 계정·데이터베이스를 새로 만드는 것은 아닙니다.

  • PHP에서 mysqli 확장이 로드되어 있어야 합니다. 명령줄에서는 php -m으로 확인하고, 웹에서는 실제 웹 요청의 PHP 환경도 확인합니다.
  • 서버 주소·포트, 계정 이름·비밀번호, 사용할 데이터베이스 이름을 준비합니다. 계정에는 작업에 필요한 최소 권한만 부여합니다.
  • 다음 로컬 실습은 TCP 연결을 사용합니다. 원격 서버에 접속할 때는 접근 허용과 전송 암호화 설정도 해당 운영 환경에 맞게 구성해야 합니다.
인수 순서 의미 주의할 점
hostname 호스트 이름 또는 IP 주소 localhost와 127.0.0.1의 연결 방식이 다를 수 있습니다.
username 접속 계정 계정의 허용 접속 호스트도 확인합니다.
password 계정 비밀번호 공개 저장소나 응답 화면에 노출하지 않습니다.
database 기본으로 사용할 데이터베이스 실제로 존재하고 계정에 접근 권한이 있어야 합니다.
port 접속할 서버 포트 설명용 기본값 3306과 실제 설정을 비교합니다.
socket 소켓 또는 이름 있는 파이프 사용 여부는 호스트와 플랫폼의 연결 방식에 영향을 받습니다.

선택 인수와 반환형은 mysqli_connect() 공식 정의를 참고하세요. mysqli는 MySQL Improved의 약자로, PHP의 MySQL 계열 데이터베이스 접근 확장입니다. 확장 설치 방식은 운영체제와 PHP 패키지에 따라 다르므로 mysqli 설치 문서에서 해당 환경을 확인합니다.

설정 파일과 연결 코드 만들기

실습 폴더 아래에 database-config.php와 public/connect.php를 만드세요. 웹에 공개하는 루트는 public 폴더이고, 비밀번호가 있는 설정 파일은 그 한 단계 밖에 둡니다. 먼저 database-config.php에 다음 내용을 저장하고 계정 정보와 포트를 실제 값으로 바꿉니다. 비밀번호 자리표시자를 그대로 쓰면 연결되지 않습니다.

<?php
return [
    'host' => '127.0.0.1',
    'username' => 'learning_user',
    'password' => 'REPLACE_WITH_YOUR_PRIVATE_PASSWORD',
    'database' => 'learning',
    'port' => 3306,
];

설정 파일에는 PHP 실행 계정이 읽을 수 있는 필요한 권한만 부여하고 버전 관리와 공개 배포 대상에서 제외하세요. 환경 변수나 비밀정보 관리 시스템을 사용하는 서비스라면 기존의 안전한 설정 방식을 유지해도 됩니다. 다음 코드는 public/connect.php의 전체 내용입니다.

<?php
header('Content-Type: text/plain; charset=UTF-8');
if (!extension_loaded('mysqli')) {
    http_response_code(500);
    exit("mysqli 확장이 필요합니다.");
}
$config = require dirname(__DIR__) . '/database-config.php';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = null;

try {
    $link = mysqli_connect(
        $config['host'],
        $config['username'],
        $config['password'],
        $config['database'],
        $config['port']
    );
    mysqli_set_charset($link, 'utf8mb4');
    $result = mysqli_query($link, "SELECT '연결 확인' AS message");
    $row = mysqli_fetch_assoc($result);
    echo $row['message'], PHP_EOL;
    echo 'charset: ', mysqli_character_set_name($link), PHP_EOL;
    mysqli_free_result($result);
} catch (mysqli_sql_exception $e) {
    http_response_code(500);
    error_log('Database check failed. Error code: ' . $e->getCode());
    echo "데이터베이스 연결 또는 쿼리 처리에 실패했습니다.", PHP_EOL;
} finally {
    if ($link instanceof mysqli) {
        mysqli_close($link);
    }
}

실습 폴더에서 php -S 127.0.0.1:8000 -t public을 실행하고 http://127.0.0.1:8000/connect.php를 엽니다. 성공하면 연결 확인과 charset: utf8mb4가 두 줄로 표시됩니다. 내장 서버는 로컬 개발 확인용으로 사용하고 운영 서비스에는 적절한 웹서버 구성을 사용하세요. 확인이 끝나면 서버를 종료하고 불필요한 진단 파일을 정리합니다.

이 쿼리는 테이블 없이 문자열 하나를 읽으므로 실제 테이블 데이터는 변경하지 않습니다. 설정 파일 경로는 connect.php의 상위 폴더인 public에서 다시 한 단계 올라가 찾습니다. 파일을 다른 위치로 옮겼다면 경로도 함께 맞춰야 합니다. CLI에서는 php public/connect.php로 같은 메시지를 확인할 수 있지만 HTTP 상태 코드는 웹 요청에서 확인해야 합니다.

예외 처리와 문자셋을 명시하는 이유

예제는 mysqli_report()로 오류 모드를 명시한 뒤 연결합니다. 연결뿐 아니라 문자셋 설정과 쿼리 처리 중의 mysqli_sql_exception도 catch에서 처리합니다. 실패 응답에는 일반적인 문장만 표시하고, 제한된 서버 로그에는 오류 코드를 남깁니다. 운영 환경에서는 PHP의 display_errors를 끄고 로그 접근 권한도 관리해야 상세 오류가 별도로 노출되지 않습니다.

PHP 8.1 이전의 기본 모드는 MYSQLI_REPORT_OFF였지만 이후에는 MYSQLI_REPORT_ERROR와 MYSQLI_REPORT_STRICT의 조합입니다. 따라서 연결 뒤 if ($link === false)가 있어도 그 전에 예외가 발생할 수 있습니다. 현재 예제처럼 모드와 예외 처리를 일관되게 맞추는 이유입니다. 변경 사항은 mysqli_report() 문서를 참고하세요.

mysqli_set_charset($link, "utf8mb4")는 연결에서 데이터를 주고받을 문자셋을 설정합니다. PHP 파일을 UTF-8로 저장하는 것과 별개이며, 기존 테이블의 문자셋을 변환하거나 손상된 데이터를 복구하는 명령도 아닙니다. mysqli_set_charset() 문서에서 권장 방식을 확인할 수 있습니다. 작업이 끝난 연결은 finally에서 닫습니다.

이 예제는 고정된 SQL 문자열만 사용합니다. 이후 검색어나 폼 입력을 쿼리에 넣을 때는 문자열을 그대로 이어 붙이지 말고 준비된 문장과 매개변수 바인딩을 사용해야 합니다. 연결 성공과 입력값의 안전한 쿼리 처리는 서로 다른 문제입니다.

연결 실패 시 확인할 순서

상황 확인할 내용
mysqli 함수가 없다는 오류 현재 실행 중인 PHP에 mysqli가 로드되었는지, CLI와 웹이 같은 설정인지 확인합니다.
연결 거부 또는 시간 초과 서버 실행 상태, 주소·포트와 방화벽·접근 허용 범위를 확인합니다.
Access denied 계정·비밀번호뿐 아니라 해당 접속 호스트에서 사용할 수 있는 계정인지 확인합니다.
Unknown database 설정한 데이터베이스가 존재하는지와 이름을 확인합니다.
소켓 파일 관련 오류 localhost의 소켓 경로와 TCP 연결을 혼동하지 않았는지 확인합니다.
연결 후 한글이 깨짐 연결 문자셋, 파일·응답 인코딩과 테이블의 저장 문자셋을 각각 확인합니다.

Unix 계열의 localhost는 보통 로컬 소켓을 선택하므로 포트만 바꿔도 원하는 TCP 서버로 가지 않을 수 있습니다. 이 예제는 127.0.0.1과 명시한 포트를 사용합니다. Windows의 이름 있는 파이프 등 플랫폼 차이도 있으므로 PHP 연결 방식 안내를 함께 확인하세요.

실패 원인을 확인하려고 비밀번호나 연결 객체 전체를 웹 화면에 출력하지 마세요. 정상 설정을 별도로 보관한 로컬 환경에서 비밀번호를 잠시 틀리게 바꾸어 실패 응답을 확인한 뒤 되돌릴 수 있습니다. 서버 로그·HTTP 500 응답을 함께 확인하고, 공유 운영 계정의 비밀번호나 방화벽을 무작정 바꾸는 방식으로 해결하지 않아야 합니다.