Microsoft Drivers for PHP for SQL Server 개요

PHP 드라이버 다운로드

SQL Server용 PHP Microsoft 드라이버에는 두 가지 PHP 확장 프로그램인 SQLSRV와 PDO_SQLSRV가 포함되어 있습니다. PDO_SQLSRV는 PHP 데이터 객체(PDO) 인터페이스를 구현합니다. 두 확장 프로그램 모두 Microsoft ODBC Driver for SQL Server를 사용하여 Microsoft SQL에 연결됩니다. 그들의 PHP API, 드라이버별 옵션, 기본 PHP 유형은 다릅니다. 예를 들어, SQLSRV는 기본적으로 날짜와 시간 값을 DateTime 객체로 반환하는 반면, PDO_SQLSRV는 기본적으로 문자열을 반환합니다. 시스템 요구사항에 대해서는 Microsoft Drivers for PHP for SQL Server의 시스템 요구 사항를 참조하세요.

SQLSRV 또는 PDO_SQLSRV를 선택하세요

만약 당신이... 사용
다른 곳에 PDO 코드가 전혀 없는 새 프로젝트를 시작하고 계신가요? 애플리케이션이 일관되게 사용할 인터페이스를 선택하세요. SQLSRV는 절차적 함수와 명시적인 매개변수 디스크립터를 노출합니다. PDO_SQLSRV는 PDO 및 PDOStatement 객체를 중심으로 구성된 코드에 적합합니다.
이미 PDO를 다른 데이터베이스(MySQL, PostgreSQL, SQLite)와 함께 사용하고 있습니다. PDO_SQLSRV를 사용하여 데이터 접근 계층이 데이터베이스 전반에서 일관되게 유지됩니다.
PDO 연결 객체를 기대하는 프레임워크나 라이브러리를 사용하세요 PDO_SQLSRV.
스트림 데이터가 전송되는 시기를 청크 단위로 수동으로 제어해야 합니다 SQLSRV, sqlsrv_send_stream_data() 사용. PDO_SQLSRV 또한 PHP 스트림 자원 PDO::PARAM_LOB을 에 바인딩하여 큰 값을 스트리밍하지만, 전체 스트림을 호출자가 제어하는 청크가 아닌 자동 전송 중에 execute() 전송합니다.
이미 sqlsrv_* 함수를 호출하는 애플리케이션을 유지하세요 PDO용으로 데이터 접근 코드를 다시 작성할 계획이 아니라면, SQLSRV.

확장 프로그램 중 하나 또는 둘 다 설치하세요. Windows 다운로드에는 별도의 확장 바이너리가 포함되어 있으며, Linux와 macOS에서는 pdo_sqlsrv 및 sqlsrv 패키지를 별도로 설치하세요. 두 가지 모두 같은 PHP 프로세스에서 로드할 수 있습니다. SQLSRV는 연결 및 명령문 리소스를 반환합니다; PDO_SQLSRV는 PDOStatement 및 PDO 객체를 반환합니다. 한 API에서 다른 API로 리소스를 전달하지 마세요.

PDO를 사용한다고 해서 Transact-SQL(T-SQL) 문법이 다른 데이터베이스로 이식되는 것은 아닙니다. PDO는 공통 PHP 인터페이스를 제공합니다; 쿼리, 스키마, 인증, 드라이버별 특성은 여전히 Microsoft SQL에 의존할 수 있습니다. 마찬가지로 절차적 확장 기능을 사용할 때 애플리케이션 전체를 절차적 방식으로 구성할 필요는 없습니다: 자신의 클래스에서 SQLSRV를 호출할 수 있습니다.

두 API에서 같은 결과를 비교해 보세요

애플리케이션이 기대하는 PHP 표현 방식을 선택하기 전에 이 프로그램들을 실행하세요. 그들은 동일한 정수, 날짜 및 SQL NULL를 선택하지만, 기본값은 동일하지 않습니다. 표나 샘플 데이터베이스는 필요하지 않습니다.

선택한 확장 프로그램을 설치하고 불러오세요. 기존 SQL Server 테스트 데이터베이스의 프로세스 환경에서 , , SQL_DATABASESQL_USERSQL_PASSWORD 를 설정합니다.SQL_SERVER 서버 인증서는 신뢰되어야 하며 설정된 엔드포인트와 일치해야 합니다. 설정 및 비밀번호 없는 Azure 대안에 대해서는 Connecting to the server를 참조하세요.

SQLSRV

이 완전한 프로그램을 compare-sqlsrv.php로 저장하고 php compare-sqlsrv.php를 실행한다.

<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $value = getenv($name);
    if ($value === false || $value === '') {
        throw new RuntimeException("Set $name before running this example.");
    }
    $config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$conn = sqlsrv_connect($config['SQL_SERVER'], [
    'Database' => $config['SQL_DATABASE'],
    'UID' => $config['SQL_USER'],
    'PWD' => $config['SQL_PASSWORD'],
    'Encrypt' => true,
    'TrustServerCertificate' => false,
    'LoginTimeout' => 30,
    'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
    throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$stmt = null;
try {
    $stmt = sqlsrv_query($conn, "SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    if ($stmt === false) {
        throw new RuntimeException(print_r(sqlsrv_errors(), true));
    }
    $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
    if ($row === false) {
        throw new RuntimeException(print_r(sqlsrv_errors(), true));
    }
    if (!is_array($row) || $row['CountValue'] !== 42
        || !($row['DayValue'] instanceof DateTime)
        || $row['DayValue']->format('Y-m-d') !== '2026-10-19'
        || $row['Missing'] !== null) {
        throw new RuntimeException('Unexpected SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

예상 출력:

int, DateTime, null

PDO_SQLSRV

이 별도의 프로그램을 compare-pdo.php로 저장하고 php compare-pdo.php실행하세요. 숫자와 날짜 찾기를 PDO_SQLSRV 기본값에 일부러 남겨둡니다.

<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $value = getenv($name);
    if ($value === false || $value === '') {
        throw new RuntimeException("Set $name before running this example.");
    }
    $config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$server = $config['SQL_SERVER'];
$database = $config['SQL_DATABASE'];
$pdo = new PDO(
    "sqlsrv:Server=$server;Database=$database;Encrypt=true;"
    . "TrustServerCertificate=false;LoginTimeout=30",
    $config['SQL_USER'],
    $config['SQL_PASSWORD'],
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
    ]
);
$stmt = null;
try {
    $stmt = $pdo->query("SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row !== ['CountValue' => '42', 'DayValue' => '2026-10-19', 'Missing' => null]) {
        throw new RuntimeException('Unexpected PDO_SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

예상 출력:

string, string, null

두 프로그램 모두 명시적으로 이름 붙여진 결과 키를 요청합니다. 이 PHP 배열은 0 기반 숫자 인덱스 대신 와 같은 CountValue열명을 사용합니다. 어느 API에서든 SQL NULL은 PHP null가 됩니다. 빈 문자열이나 결과 행이 빠진 것이 아닙니다.

두 프로그램 모두 실제 데이터베이스 이름, 사용자 이름, 비밀번호를 환경에서 읽습니다. 이 값들은 PHP 드라이버의 ODBC 스타일 연결 처리를 위해 한 번 이 값을 벗어납니다. 닫는 대괄호를 두 번 늘리고 값을 대괄호로 감싸면 특수 문자가 보존됩니다; 데이터베이스 이름을 바꾸거나 저장된 비밀번호를 변경하지 않습니다. 자세한 내용은 서버에 연결하기를 참조하세요.

예제들은 오류에서 멈추고 자원을 해제합니다 finally. SQLSRV는 와 sqlsrv_errors()를 통해 false 데이터베이스 실패를 보고합니다; PDO_SQLSRV 설정 오류 모드에서 연결 실패를 throw하고 쿼리 실패에 대해 예외를 사용합니다. 웹 애플리케이션에서는 요청을 처리하는 코드에서 이러한 예외를 포착합니다. 진단 세부사항을 브라우저로 반환하는 대신 보호된 로그에 기록하세요.

운동 후에는 삭제 compare-sqlsrv.php 하고 compare-pdo.php 더 이상 필요하지 않다면 테스트 프로세스를 마치면 자격 증명 환경 변수를 삭제하세요.

유형 선택, 인코딩, 오류 처리

애플리케이션이 어떤 PHP 유형을 기대하는지, 텍스트와 오류를 어떻게 처리하는지, 데이터베이스 리소스를 언제 해제하는지 결정하세요.

의사 결정 SQLSRV PDO_SQLSRV 애플리케이션 코드에 미치는 영향
정수 결과 유형 SQL 정규 열을 위한 네이티브 PHP 정수. 기본적으로 문자열; PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE 요청은 숫자 PHP 타입을 지원했습니다. 엄격한 비교와 직렬화된 출력은 다를 수 있습니다. 모든 SQL 수치 타입이 PHP 정수나 float에 꼭 맞는다고 가정하지 마세요.
날짜와 시간 결과 DateTime 기본적으로 객체; ReturnDatesAsStrings 문자열을 선택합니다. 기본값은 문자열이며 PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE는 객체를 선택합니다. 직렬화하거나 애플리케이션 코드에 전달하기 전에 표현을 정규화하세요.
문자 인코딩 명시적으로 설정합니다 CharacterSet => 'UTF-8' . 기본 설정은 UTF-8이며, PDO::SQLSRV_ATTR_ENCODING로 설정하세요. SQLSRV 옵션을 PDO DSN으로 옮기지 마세요.
오류 처리 즉시 전체 SQLSRV 오류 집합을 확인하고 false 캡처하세요. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION을(를) 구성합니다. 누락된 행과 실패한 쿼리는 다른 처리가 필요합니다.
매개변수 재사용 디스크립터에서 sqlsrv_prepare() 참조별로 변수를 바인딩하세요. 변수 bindValue() 나 현재 값에 사용 bindParam() 하세요. 변수 재할당은 이전 값 바인딩이 아니라 참조 바인딩에 영향을 줍니다.
Cleanup 무료 진술을 한 다음, 연결 리소스를 닫으세요. 릴리스 문장 참조를 한 다음, PDO 객체를 사용합니다. 문장은 다른 참조가 로 설정 null된 후에도 PDO 연결을 유지할 수 있습니다.

기존 애플리케이션을 마이그레이션할 경우, 데이터베이스 코드를 변경하기 전에 대표적인 값으로 이러한 동작을 테스트하세요. ASCII가 아닌 텍스트, SQL NULL, 날짜, 정확한 십진수 값, 저장된 프로시저 출력 매개변수를 포함하세요. 또한 프레임워크가 PDO 속성을 어떻게 구성하는지 비교해 보세요. 함수명만으로 오류 처리, 참조 바인딩, 반환된 PHP 타입을 이전하는 것은 아닙니다.

두 API에서 쓰기와 읽기 워크플로우가 모두 작동하려면 프로그래밍 가이드를 참고하세요. 반복 실행 및 입력한 값의 경우, Compare 쿼리 실행 함수를 사용하세요.

각 구성 요소가 무엇을 하는지 알아야 합니다

확장 프로그램 선택은 PHP API와 타입 변환을 변경합니다. 두 확장 프로그램 모두 ODBC를 사용하여 서버와 통신하고, 연결을 암호화하며, 인증을 수행합니다. 운영체제는 Windows 인증나 케르베로스와 같은 신뢰할 수 있는 인증서와 서비스를 제공합니다. SQL 타겟은 권한, 스키마, 지원되는 T-SQL 문장을 제어합니다.

비교 프로그램은 SQL Server에 대한 SQL 인증을 사용합니다. Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics, Fabric의 SQL 데이터베이스, 또는 Warehouse in Fabric의 경우, fetch 패턴을 재사용하기 전에 서비스 엔드포인트와 지원되는 인증을 설정하세요. 두 Fabric 제품 모두 Microsoft Entra ID 인증을 요구하며; Warehouse는 또한 다중 활성 결과 집합(MARS)을 비활성화해야 합니다. SQL Server에서 성공적인 타입 비교가 다른 타겟이 이 개요에 나열된 모든 기능을 지원한다는 것을 입증하지는 않습니다.

두 확장 모두 제공하는 점

  • 대상 지원에 따라 통합 인증, SQL 인증, Microsoft Entra ID 인증이 포함됩니다. 관리 신원은 애플리케이션 비밀번호를 사용하지 않습니다. ActiveDirectoryServicePrincipal 서비스 주체는 클라이언트 ID와 클라이언트 비밀을 사용합니다. 자세한 내용은 서버에 연결하기를 참조하세요.
  • 매개변수화된 쿼리, 준비된 문장, 그리고 방향성(입출력) 매개변수가 포함됩니다. 자세한 내용은 실행 함수 비교 와 방향 매개변수 사용을 참조하세요.
  • 트랜잭션, 큰 문자 및 이진 값에 대한 스트림 입력 매개변수, 그리고 테이블 값 매개변수입니다.
  • 항상 암호화되어 있으며, ODBC 드라이버와 SQL Server 타겟이 지원하는 보안 엔클레이브도 포함됩니다. 자세한 내용은 SQL Server용 Microsoft 드라이버 사용법을 참고하세요.
  • SQL Server, Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics, Microsoft Fabric의 SQL 데이터베이스, Microsoft Fabric의 Warehouse에 대한 연결. 인증과 SQL 기능은 타겟에 따라 다릅니다; Azure 및 Fabric 연결을 참조하세요.