Microsoft Azure SQL Database에 연결

PHP 드라이버 다운로드

SQLSRV와 PDO_SQLSRV 드라이버는 완전히 정규화된 서버 이름과 Connection options의 연결 옵션과 함께 다음 Azure 및 Fabric SQL 대상에 연결됩니다. SQLSRV는 옵션 배열을 받으며, PDO_SQLSRV는 데이터 소스 이름(DSN), 필요 시 별도의 자격 증명 인수 및 PDO 속성을 받습니다.

목표/타겟 서버 이름 양식 Notes
Azure SQL 데이터베이스 <server>.database.windows.net
Azure SQL Managed Instance(애저 SQL 매니지드 인스턴스) 인스턴스의 공개 또는 개인 엔드포인트 가상 네트워크, 가상 사설망(VPN), 또는 공용 엔드포인트를 통한 네트워크 연결이 필요합니다.
Azure Synapse Analytics (workspace 내 전용 SQL 풀) <workspace>.sql.azuresynapse.net 지원되는 Transact-SQL(T-SQL) 문은 SQL Server와 다릅니다. 지원되는 문법에 대해서는 Synapse SQL 문서를 참조하세요.
Microsoft Fabric의 SQL 데이터베이스 서버와 데이터베이스를 데이터베이스 항목의 설정>연결 문자열에서 복사하세요 SQL 데이터베이스 연결을 사용하세요, SQL 분석 엔드포인트가 아니라요. Microsoft Entra 인증이 필요합니다. 자세한 내용은 Fabric의 SQL 데이터베이스에 연결을 참조 하세요.
Microsoft Fabric의 창고 웨어하우스의 SQL 연결 문자열을 Fabric 포털에서 복사하세요 Database을 창고 이름으로 설정하고 MultipleActiveResultSets을 false로 설정합니다. Microsoft Entra 인증이 필요합니다. 자세한 내용은 웨어하우스 연결을 참조하세요.

두 PHP 확장 모두 기본적으로 다중 활성 결과 집합(MARS)이 사용하도록 설정됩니다. Warehouse는 MARS를 지원하지 않으니 SQLSRV 옵션 배열이나 PDO_SQLSRV DSN에서 명시적으로 비활성화합니다. Fabric과 Warehouse의 SQL 데이터베이스는 별개의 제품입니다; 한쪽에서 지원하는 기능이 다른 쪽에서도 지원된다고 가정하지 마세요.

엔드포인트, 아이덴티티, PHP 호스트를 준비하세요

PHP 프로세스는 SQL 엔드포인트에 대한 네트워크 접근, 지원되는 로그인 방법, 그리고 선택한 데이터베이스를 열 수 있는 권한이 필요합니다. 각 요구사항을 따로 확인하세요. 예를 들어, 방화벽 포트를 열어도 데이터베이스 접근이 주어지지 않습니다.

  1. PHP를 실행하는 기기나 컨테이너에 PHP 확장 프로그램과 Microsoft ODBC 드라이버를 설치하세요. 확장 기능을 개발 터미널뿐만 아니라 해당 프로세스에서도 검증하세요. 자세한 내용은 드라이버 로드하기를 참조하세요.
  2. 대상의 연결 정보에서 서버와 데이터베이스를 복사하세요. HTTPS URL 스킴은 포함하지 마세요. 서비스에서 제공한 호스트 이름을 사용해 인증서 검증이 의도한 엔드포인트를 검증하도록 합니다. Azure SQL Managed Instance 공개 엔드포인트는 비기본 포트를 포함할 수 있으며; 제공된 포트를 유지하세요.
  3. PHP 호스트에 대한 서비스의 네트워크 액세스를 설정하세요. 프라이빗 엔드포인트의 경우, 프라이빗 네임 해석과 애플리케이션 네트워크로부터의 경로를 확인하세요. 공용 방화벽 규칙은 사설 IP 주소로 가는 경로를 제공하지 않습니다.
  4. PHP 프로세스에서 사용하는 계정을 선택합니다. Azure 호스팅 애플리케이션의 경우, 관리 신원을 활성화하고 시스템 할당인지 사용자 할당인지 식별하세요. 개발자의 Azure CLI 로그인은 애플리케이션의 관리 신원이 아닙니다.
  5. 데이터베이스 관리자가 해당 신원에 선택한 데이터베이스와 애플리케이션이 요구하는 최소 권한에 대한 접근 권한을 부여하게 하세요. Warehouse의 경우, Fabric 아이템/작업 공간 접근 권한도 확인해 보세요. Azure 리소스 관리 권한 그 자체만으로는 애플리케이션 테이블에 쿼리 권한을 부여하지 않습니다.
  6. 애플리케이션 구성에서 SQL_SERVER 및 SQL_DATABASE을 설정합니다. 관리 신원 예시에서는 비밀번호를 저장하지 마세요.

예제들은 테이블을 만들지 않고도 연결을 검증합니다. 이 검사를 통과한다고 해서 그 아이덴티가 애플리케이션 스키마를 읽거나 쓸 수 있다는 증거는 아닙니다. 실제 연산은 같은 신분으로 따로 테스트하세요.

비밀번호 없는 Microsoft Entra 인증 사용

호스팅 환경이 관리형 아이덴티티 엔드포인트를 노출하고 SQL 타겟이 그 아이덴티티 접근 권한을 부여할 때 관리 신원을 사용하세요. 다음 완전한 프로그램들은 시스템에 할당된 관리 신원을 사용합니다. 이것들은 워크스테이션 예시가 아닙니다. 설정된 Azure 호스트에서 실행하세요. 해당 PHP 프로세스에서 SQL_SERVER 및 SQL_DATABASE를 사용할 수 있습니다.

두 프로그램 모두 MARS를 비활성화하므로, Warehouse를 선택할 때도 연결 설정이 적합합니다. 그들은 한 번에 하나의 활성 명령문을 사용합니다. 신원 설정 및 기타 인증 방식에 대해서는 Microsoft Entra 인증을 사용하여 연결 문서를 참조하세요.

SQL_DATABASE을 실제 데이터베이스 이름으로 설정하세요. 각 프로그램은 닫는 중괄호를 두 배로 늘리고 이름을 중괄호로 감싸서 연결에 대해 별도의 이스케이프 값을 생성합니다. 이스케이핑은 데이터베이스 이름의 특수 문자가 드라이버가 연결 설정을 읽는 방식을 바꾸지 못하게 합니다. 프로그램들은 DB_NAME()의 결과를 확인하기 위해 원래의 이름을 유지합니다.

SQLSRV

이 프로그램을 connect-azure-sqlsrv.php로 저장하고 설정된 호스트에서 php connect-azure-sqlsrv.php를 실행하세요.

<?php
$server = getenv('SQL_SERVER');
$database = getenv('SQL_DATABASE');
if ($server === false || $server === '' || $database === false || $database === '') {
    throw new RuntimeException('Set SQL_SERVER and SQL_DATABASE.');
}
$databaseValue = '{' . str_replace('}', '}}', $database) . '}';

$conn = sqlsrv_connect($server, [
    'Database' => $databaseValue,
    'Authentication' => 'ActiveDirectoryMsi',
    'Encrypt' => true,
    'TrustServerCertificate' => false,
    'LoginTimeout' => 30,
    'MultipleActiveResultSets' => false,
    'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
    throw new RuntimeException(print_r(sqlsrv_errors(), true));
}

$stmt = null;
try {
    $stmt = sqlsrv_query(
        $conn,
        'SELECT DB_NAME() AS DatabaseName, CAST(1 AS int) AS Connected',
        [],
        ['QueryTimeout' => 30]
    );
    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 ($row !== ['DatabaseName' => $database, 'Connected' => 1]) {
        throw new RuntimeException('Unexpected database or connection result.');
    }
    echo 'Connected to ', $row['DatabaseName'], '.', PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

PDO_SQLSRV

이 별도의 프로그램을 connect-azure-pdo.php로 저장하고, 구성된 호스트에서 php connect-azure-pdo.php를 실행하세요. 이는 를 설정하여 int 결과가 PHP PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE가 되도록 합니다. 이 기능이 없으면 PDO_SQLSRV 기본적으로 이 열을 문자열로 반환합니다. PDO 인코딩은 속성이지 SQLSRV CharacterSet 옵션이 아닙니다.

<?php
$server = getenv('SQL_SERVER');
$database = getenv('SQL_DATABASE');
if ($server === false || $server === '' || $database === false || $database === '') {
    throw new RuntimeException('Set SQL_SERVER and SQL_DATABASE.');
}
$databaseValue = '{' . str_replace('}', '}}', $database) . '}';
$pdo = new PDO(
    "sqlsrv:Server=$server;Database=$databaseValue;Authentication=ActiveDirectoryMsi;"
    . "Encrypt=true;TrustServerCertificate=false;LoginTimeout=30;"
    . "MultipleActiveResultSets=false",
    null,
    null,
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
        PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true,
    ]
);

$stmt = null;
try {
    $stmt = $pdo->prepare(
        'SELECT DB_NAME() AS DatabaseName, CAST(1 AS int) AS Connected',
        [PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 30]
    );
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row !== ['DatabaseName' => $database, 'Connected' => 1]) {
        throw new RuntimeException('Unexpected database or connection result.');
    }
    echo 'Connected to ', $row['DatabaseName'], '.', PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

appdb이 SQL_DATABASE이면, 각 프로그램은 다음을 출력합니다:

Connected to appdb.

ActiveDirectoryMsi는 로컬 Azure CLI 로그인을 사용하지 않습니다. 로컬 개발 또는 지속적 통합(CI)의 경우, PHP 확장 기능과 ODBC 드라이버가 지원하는 인증 방식을 선택하세요. Microsoft Entra 액세스 토큰은 신원 라이브러리를 통해 얻을 수 있으며, AccessToken를 통해 제공할 수 있습니다. 토큰을 사용할 때는 사용자 이름과 비밀번호 및 Authentication 설정은 제외하세요. AccessToken를 SQLSRV 연결 옵션 배열 또는 PDO_SQLSRV DSN에 설정하세요. 토큰은 소스 코드와 로그에 포함시키지 마세요. 자세한 내용은 Microsoft Entra 인증을 사용하여 연결 참조하세요.

ActiveDirectoryServicePrincipal 클라이언트 ID와 클라이언트 시크릿을 사용합니다; 비밀번호 없는 인증이 아닙니다. 만약 사용한다면, 보호된 애플리케이션 구성에서 비밀을 읽으세요. SQL 인증은 이를 지원하는 대상에만 대안으로 사용됩니다; Fabric의 SQL 데이터베이스나 웨어하우스는 SQL 인증을 지원하지 않습니다.

인증을 환경에 맞게 조정

각 연결마다 하나의 인증 메커니즘을 사용하세요. AccessToken로 전환할 때 이전 사용자 이름, 비밀번호 또는 Authentication 설정을 그대로 두지 마세요.

Environment Configuration 책임
시스템 할당 관리 ID가 있는 Azure 호스트 Authentication을 ActiveDirectoryMsi로 설정합니다. 사용자 이름이나 비밀번호는 제공하지 마세요. ODBC는 호스트의 아이덴티티 엔드포인트로부터 토큰을 획득합니다.
사용자 할당 관리 ID가 있는 Azure 호스트 Authentication을 ActiveDirectoryMsi로 설정합니다. SQLSRV의 UID 옵션이나 PDO의 사용자 이름 인수를 통해 아이덴티티 ID를 지정합니다. 비밀번호를 입력하지 마세요. 필요한 ID는 호스팅 서비스에 따라 다릅니다. App Service와 Container Instances는 클라이언트 ID를 사용하며, 다른 호스트에 대해서는 ODBC 신원 지침을 확인하세요.
외부 토큰 제공자가 있는 워크스테이션 또는 CI SQL 서비스용 토큰을 얻은 후 AccessToken를 설정합니다. 사용자 이름, 비밀번호, Authentication 설정은 빼세요. 애플리케이션이나 ID 라이브러리가 토큰을 획득하고 갱신합니다. 두 PHP 확장 프로그램 모두 Azure CLI 로그인을 자동으로 사용하지 않습니다.
고객 비밀을 가진 서비스 책임자 Authentication을 ActiveDirectoryServicePrincipal로 설정합니다. SQLSRV의 경우, PWD를 클라이언트 ID로, UID를 비밀 값으로 설정하세요. PDO의 경우, 클라이언트 ID와 secret을 생성자의 사용자 이름과 비밀번호 인자로 전달합니다. 비밀을 보호하고 교체하세요. 이 방법은 비밀번호 없이 사용할 수 없습니다.
이를 지원하는 대상에서 SQL로 로그인 SQLSRV는 UID/PWD를 사용합니다. PDO는 생성자 인수 2와 3을 사용합니다. 타겟은 SQL 자격 증명을 검증합니다. 이 옵션은 두 Fabric 제품 모두에는 적용되지 않습니다.

Azure 리소스 관리용이 아니라 SQL 서비스에 토큰을 요청하세요. 토큰의 대상 은 이를 수락하는 서비스를 식별합니다. Azure 퍼블릭 클라우드의 경우, 아이덴티티 라이브러리를 통해 범위 https://database.windows.net/.default를 요청하세요. 다른 클라우드에 적합한 자원을 확인하세요. 토큰을 PHP 확장에 문자열로 전달하세요; 수동으로 ODBC 액세스 토큰 구조로 변환하지 마세요.

작업자가 계속 실행되는 동안 토큰은 만료될 수 있습니다. 다른 연결을 열기 전에 유효한 토큰을 확보하고, 장기 실행 작업자의 경우 필요에 따라 토큰을 새로고침하세요. 접근 토큰이 포함된 DSN은 절대 기록하지 마세요. ODBC 인증에 대한 자세한 내용은 'ODBC 드라이버와 함께 Microsoft Entra ID 사용하기'를 참조하세요.

암호화와 신원 확인은 분리하세요

Encrypt=true 암호화된 전송을 요청합니다. TrustServerCertificate=false는 서버 인증서의 신원을 포함해 검증해야 합니다. Microsoft Entra 인증은 애플리케이션의 신원을 확인하며, 서버 인증서 검증을 대체하지 않습니다.

SQL 서비스가 제공하는 엔드포인트를 사용하고 클라이언트 운영체제의 인증서 신뢰 저장소를 유지하세요. 이름 확인 문제를 우회하려고 호스트 이름을 IP 주소로 바꾸지 마세요. 사설 엔드포인트의 경우, 서비스의 예상 연결 이름을 유지하면서 이름 해석과 라우팅을 수정하세요.

LoginTimeout 연결 설정을 제한합니다. QueryTimeout는 SQLSRV에, PDO::SQLSRV_ATTR_QUERY_TIMEOUT는 PDO_SQLSRV에 대해 문 실행에 적용됩니다. 쿼리 타임아웃을 올려도 누락된 관리 식별 엔드포인트나 잘못된 데이터베이스 사용자를 해결하지 못합니다.

고장 단계별 문제 해결

실패 단계 확인할 사항
PHP가 확장 프로그램을 로드할 수 없습니다 런타임 버전, 아키텍처, 확장 빌드, ODBC 설치, 그리고 애플리케이션 프로세스에서 사용하는 php.ini 드라이버를 확인하세요.
전송 제어 프로토콜(TCP) 연결 시간이 초과됨 PHP 호스트에서 복사된 엔드포인트와 포트, 이름 해석, 방화벽 규칙, 가상 네트워크 라우팅, 프라이빗 엔드포인트 구성을 검증하세요.
인증서 유효성 검사에 실패함 엔드포인트 이름, 인증서 체인, 클라이언트 신뢰 저장소를 확인하세요. 인증서 검증은 계속 활성화해 두세요.
관리 ID는 토큰을 획득할 수 없습니다 이 호스트에서 신원이 활성화되어 있고, 그 신원 엔드포인트가 사용 가능한지 확인하세요. 일반 노트북에서 ActiveDirectoryMsi를 테스트하고 Azure CLI 로그인이 이를 충족할 것으로 기대하지 마세요.
토큰 인증에 실패합니다 토큰의 의도된 서비스, 만료일, 테넌트, 신원을 확인하세요. 해당 신원에 대한 데이터베이스 접근 권한을 확인하세요. 모든 사용자 이름, 비밀번호, Authentication 설정을 삭제하세요.
로그인은 성공하지만 선택한 데이터베이스가 열리지 않습니다 데이터베이스 이름과 관리자가 대상 ID에 대한 액세스 권한을 생성했거나 부여했는지 확인하세요.
연결이 열렸지만 애플리케이션 쿼리가 실패합니다 객체 권한을 확인하고 대상이 지원하는 T-SQL 기능을 확인하세요. 연결 테스트는 애플리케이션 스키마 액세스를 설정하지 않습니다.
창고에서 연결 설정을 거부함 SQLSRV 옵션 배열이나 PDO DSN에서 MultipleActiveResultSets를 false로 설정하고, Microsoft Entra 인증을 사용하세요.

SQLSRV는 .을 통해 sqlsrv_errors()오류 집합을 반환 false 하고 노출합니다. PDO 구성은 PDOException 예외를 발생시킵니다. 예시들은 구문 실행 실패에 대한 예외도 활성화합니다. 진단 결과를 제한 로그에 즉시 캡처하고 SQLSRV 경고를 오류와 구분하세요. 브라우저에 원시 진단, 토큰, 연결 정보를 반환하지 마세요.

중단된 연결에 대한 계획

서비스는 유휴 세션을 끊거나 유지보수 또는 장애 조치 중 작업을 중단할 수 있습니다. ODBC 유휴 연결 복원력과 애플리케이션 재시도는 다양한 문제를 해결합니다. 재시도 키워드와 제어 끊김 테스트에 대해서는 Idle connection resiliency를 참조하세요.

클라이언트가 연결이 끊겼다고 해서 쓰기 작업을 다시 실행하지 마세요. 서버가 응답이 사라지기 전에 커밋했을 수도 있습니다. 애플리케이션별 재시도 정책과 중복 작업을 감지하는 방법을 사용하세요. 요청이나 작업이 완료되면 오류 경로를 포함하여 문과 연결 핸들을 해제하십시오. 라이프사이클과 풀링 동작에 대해서는 서버에 연결하기(Connecting to the Server)를 참조하세요.