Instale os drivers PHP para SQL Server no Windows

Use este artigo para instalar o SQLSRV e PDO_SQLSRV drivers para PHP no Windows. Os drivers são extensões PHP que utilizam o Microsoft ODBC Driver for SQL Server.

Antes de começar, confirme se sua versão do PHP, arquitetura e modo de thread safety são suportados na matriz de suporte. O ambiente de execução PHP usado por um processo de linha de comando e o ambiente de execução usado por um servidor web podem usar arquivos php.ini diferentes. Configure e verifique cada runtime separadamente.

Ao final do procedimento, tanto sqlsrv_connect() quanto o driver PDO sqlsrv devem estar disponíveis para a CLI ou aplicação web pretendida, e cada API deve completar uma consulta de teste. Uma cópia bem-sucedida de arquivo sozinha não é uma instalação concluída.

Escolher um método de instalação

Método Use-o quando O que é instalado
Instalador PHP para Extensões (PIE) Você quer que o instalador selecione a build do driver para o executável PHP Não versionados php_sqlsrv.dll e php_pdo_sqlsrv.dll, com configuração automática tentada
Pacote ZIP publicado Você precisa escolher, inspecionar ou implantar arquivos pré-compilados específicos você mesmo DLLs versionadas selecionadas por versão secundária do PHP, modo de segurança de threads e arquitetura

Use um método para ambas as extensões. Não mantenha as entradas de configuração PIE e ZIP ativas ao mesmo tempo.

Instalar os pré-requisitos

  1. Instale uma build PHP suportada a partir do site PHP for Windows. Adicione o diretório PHP a PATH.

  2. Instale o Visual C++ Redistributable exigido pela sua build em PHP. Faça a arquitetura x64 ou x86 corresponder ao PHP, conforme descrito nos requisitos do PHP para Windows.

  3. Instale o driver Microsoft ODBC mais recente para SQL Server.

  4. Execute os seguintes comandos para confirmar o ambiente de execução e o arquivo de configuração do PHP:

    php --version
    php --ini
    

    Se o Arquivo de Configuração Carregado for (none), copie php.ini-development para php.ini no diretório PHP.

  5. Em php.ini, defina o diretório de extensões e ative as extensões exigidas pelo PHP Installer for Extensions (PIE):

    extension_dir = "ext"
    extension=openssl
    extension=zip
    
  6. Confirme se o PHP consegue localizar as extensões pré-requisitas:

    php --ri openssl
    php --ri zip
    

    Corrija esses pré-requisitos antes de baixar o PIE.

Instale com PIE

O PIE instala o driver pré-compilado correspondente para o runtime do PHP. Isso não requer um compilador C no Windows.

  1. Mude para um diretório onde você tenha permissão de escrita e baixe o arquivo PHP PIE mais recente (PHAR):

    curl.exe -fL --output pie.phar https://github.com/php/pie/releases/latest/download/pie.phar
    

    Os comandos PIE restantes se referem ao arquivo como .\pie.phar, então execute-os a partir desse mesmo diretório.

    Antes de rodar o PHAR, verifique com a interface de linha de comando (CLI) do GitHub:

    gh attestation verify --owner php .\pie.phar
    

    Confirme o download antes de continuar:

    dir pie.phar
    php .\pie.phar --version
    
  2. Instale cada driver separadamente:

    php .\pie.phar install microsoft/sqlsrv
    php .\pie.phar install microsoft/pdo_sqlsrv
    
  3. Verifique o runtime de linha de comando:

    php --ri sqlsrv
    php --ri pdo_sqlsrv
    php -m | findstr /I "sqlsrv pdo_sqlsrv"
    

O PIE tenta habilitar as extensões na configuração usada pelo executável de linha de comando. Se o PIE informar que não conseguiu habilitar uma extensão, adicione as entradas específicas da extensão PIE.

Se seu servidor web usar outra instalação PHP, instale ambos os drivers para a versão do PHP dessa instalação, arquitetura e modo thread-safe antes de configurá-la. Se a mesma instalação do PHP usar um php.ini diferente para o servidor web, ative os drivers instalados nesse arquivo. Verifique o runtime da web separadamente e reinicie o servidor web após alterar sua configuração.

O PIE altera a instalação PHP selecionada. Ele não configura o IIS, não seleciona um site IIS nem reinicia processos PHP existentes.

Instalar manualmente um pacote ZIP publicado

Use este método quando precisar selecionar os arquivos de driver você mesmo ou quando o PIE não for adequado.

  1. Baixe o Windows ZIP da versão lançada do driver na página de lançamentos do Microsoft Drivers for PHP for SQL Server.

  2. Execute php -i | findstr /I "PHP Version Thread Safety Architecture extension_dir" e grave a versão PHP, o modo de segurança de threads, a arquitetura e o diretório de extensões.

  3. Do arquivo ZIP, copie ambas as bibliotecas de enlace dinâmico (DLLs) correspondentes para o diretório de extensão:

    php_sqlsrv_<php-version>_<ts-or-nts>_<x86-or-x64>.dll
    php_pdo_sqlsrv_<php-version>_<ts-or-nts>_<x86-or-x64>.dll
    

    Por exemplo, um tempo de execução PHP 8.5 x64 thread-safe usa php_sqlsrv_85_ts_x64.dll e php_pdo_sqlsrv_85_ts_x64.dll.

  4. Adicione os nomes das extensões compatíveis ao php.ini usado pelo runtime:

    extension=php_sqlsrv_85_ts_x64.dll
    extension=php_pdo_sqlsrv_85_ts_x64.dll
    

    Substitua 85, ts, e x64 pelos valores do seu tempo de execução PHP. Não misture arquivos thread-safe e non-thread-safe, arquivos de 32 bits e 64 bits, ou arquivos compilados para outra versão secundária do PHP.

  5. Verifique o tempo de execução com php --ri sqlsrv, php --ri pdo_sqlsrv, e php -m. Para um servidor web, restrinja o acesso à página de diagnóstico antes de criar uma página temporária phpinfo() . Verifique o Arquivo de Configuração Carregado e ambas as seções do driver, depois remova a página.

Configure um servidor web

Para IIS, configure o php-cgi.exe pretendido como um aplicativo FastCGI seguindo as orientações de instalação do PHP no IIS. Confirme que o aplicativo FastCGI usa o mesmo diretório e arquitetura PHP que você usou para instalar os drivers.

Para qualquer servidor web Windows:

  1. Restringa o acesso à página de diagnóstico antes de criar uma phpinfo() página temporária. Identifique o executável PHP do servidor web e a configuração ativa php.ini.

  2. Certifique-se de que ambos os drivers estejam instalados para o Web Runtime. Para uma instalação PHP separada, use PIE com o executável PHP dessa instalação, ou copie ambas as DLLs correspondentes do ZIP lançado para seu diretório de extensão. Adicione as entradas do driver à configuração do runtime web, inclusive quando apenas seu php.ini difere da CLI.

  3. Reinicie o servidor web ou os processos do FastCGI.

  4. Confirme se a página contém seções separadas sqlsrv e pdo_sqlsrv separadas.

  5. Remova a phpinfo() página.

Teste ambas as APIs PHP

Salve este programa como verify-php-drivers.php:

<?php
$failures = [];

if (!extension_loaded('sqlsrv') || !function_exists('sqlsrv_connect')) {
    $failures[] = 'SQLSRV is not available.';
}

if (!extension_loaded('pdo_sqlsrv') || !in_array('sqlsrv', PDO::getAvailableDrivers(), true)) {
    $failures[] = 'PDO_SQLSRV is not available.';
}

echo $failures === []
    ? "SQLSRV and PDO_SQLSRV are available." . PHP_EOL
    : implode(PHP_EOL, $failures) . PHP_EOL;

exit($failures === [] ? 0 : 1);

Execute primeiro pela linha de comando:

php verify-php-drivers.php

Resultado esperado:

SQLSRV and PDO_SQLSRV are available.

Se precisar verificar um runtime web, coloque o arquivo temporariamente na raiz do documento do site e acesse-o em um navegador. Remova-o após o teste. Este programa verifica as APIs PHP sem exigir ou expor credenciais de banco de dados.

Teste uma conexão com banco de dados

O carregamento da extensão é apenas a primeira verificação de instalação. Teste ambas as APIs contra o alvo do banco de dados que a aplicação usa, de modo que o teste também cubra o driver ODBC, caminho de rede, criptografia, autenticação, execução de consultas, valores retornados e limpeza.

Defina variáveis temporárias de ambiente no PowerShell respondendo prompts. Insira os nomes do servidor e do banco de dados como valores brutos, sem aspas ou codificação do driver. Use a caixa de diálogo ou o prompt de credenciais para uma conta de teste que possa se conectar ao banco de dados. Não inclua credenciais em uma linha de comando ou em uma sessão de terminal gravada:

$env:SQL_SERVER_NAME = Read-Host "Server name (tcp:<server>,1433)"
$env:SQL_DATABASE = Read-Host "Database name"
$credential = Get-Credential -Message "Enter the database test account"
if ($null -eq $credential) {
    throw "Database test credentials are required."
}
$env:SQL_UID = $credential.UserName
$env:SQL_PWD = $credential.GetNetworkCredential().Password
Remove-Variable credential

A janela de credenciais oculta a senha. O ambiente contém a senha em texto simples para que o PHP possa lê-la. Use essas variáveis apenas na sessão de teste, não as imprima e limpe-as após o teste.

Salve este programa como test-php-drivers.php. Mantenha os valores do ambiente inalterados. O programa dobra as chaves de fechamento e adiciona chaves externas antes de passar o nome do banco de dados, nome de usuário e senha para o driver. Essa codificação preserva as chaves literais e impede que pontos e vírgula separem as opções de conexão.

<?php
$serverName = getenv('SQL_SERVER_NAME');
$database = getenv('SQL_DATABASE');
$uid = getenv('SQL_UID');
$pwd = getenv('SQL_PWD');

if ($serverName === false || $serverName === ''
    || $database === false || $database === ''
    || $uid === false || $uid === ''
    || $pwd === false || $pwd === '') {
    fwrite(STDERR, "Set SQL_SERVER_NAME, SQL_DATABASE, SQL_UID, and SQL_PWD." . PHP_EOL);
    exit(1);
}

$database = '{' . str_replace('}', '}}', $database) . '}';
$uid = '{' . str_replace('}', '}}', $uid) . '}';
$pwd = '{' . str_replace('}', '}}', $pwd) . '}';

$connectionOptions = [
    "Database" => $database,
    "UID" => $uid,
    "PWD" => $pwd,
    "Encrypt" => 1,
    "TrustServerCertificate" => 0,
];

$sqlsrvConnection = sqlsrv_connect($serverName, $connectionOptions);
if ($sqlsrvConnection === false) {
    foreach (sqlsrv_errors() as $error) {
        fwrite(
            STDERR,
            "SQLSRV {$error['SQLSTATE']} ({$error['code']}): {$error['message']}" . PHP_EOL
        );
    }
    exit(1);
}

$sqlsrvStatement = sqlsrv_query($sqlsrvConnection, "SELECT 1 AS TEST_VALUE");
if ($sqlsrvStatement === false) {
    foreach (sqlsrv_errors() as $error) {
        fwrite(
            STDERR,
            "SQLSRV {$error['SQLSTATE']} ({$error['code']}): {$error['message']}" . PHP_EOL
        );
    }
    sqlsrv_close($sqlsrvConnection);
    exit(1);
}

$sqlsrvRow = sqlsrv_fetch_array($sqlsrvStatement, SQLSRV_FETCH_ASSOC);
if ($sqlsrvRow === false || $sqlsrvRow === null || (int) $sqlsrvRow['TEST_VALUE'] !== 1) {
    fwrite(STDERR, "SQLSRV returned an unexpected result." . PHP_EOL);
    sqlsrv_free_stmt($sqlsrvStatement);
    sqlsrv_close($sqlsrvConnection);
    exit(1);
}

echo "SQLSRV query: 1" . PHP_EOL;
sqlsrv_free_stmt($sqlsrvStatement);
sqlsrv_close($sqlsrvConnection);

$failed = false;
try {
    $pdoConnection = new PDO(
        "sqlsrv:server=$serverName;Database=$database;Encrypt=1;TrustServerCertificate=0",
        $uid,
        $pwd,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
    $pdoStatement = $pdoConnection->query("SELECT 1 AS TEST_VALUE");
    $pdoRow = $pdoStatement->fetch(PDO::FETCH_ASSOC);
    if ($pdoRow === false || (int) $pdoRow['TEST_VALUE'] !== 1) {
        throw new RuntimeException("PDO_SQLSRV returned an unexpected result.");
    }

    echo "PDO_SQLSRV query: 1" . PHP_EOL;
} catch (Throwable $exception) {
    fwrite(STDERR, $exception->getMessage() . PHP_EOL);
    $failed = true;
} finally {
    unset($pdoStatement);
    unset($pdoConnection);
}

exit($failed ? 1 : 0);

Execute o programa com o mesmo executável PHP que você verificou:

php test-php-drivers.php

Resultado esperado:

SQLSRV query: 1
PDO_SQLSRV query: 1

Se a verificação de extensão for aprovada, mas esse programa falhar, use o SQLSTATE e o erro nativo para identificar a camada responsável. Não reinstale as extensões PHP em caso de erro de rede, certificado, autenticação ou permissão no banco de dados.

Remova o script e as variáveis temporárias após o teste:

Remove-Item .\verify-php-drivers.php, .\test-php-drivers.php
Remove-Item Env:\SQL_SERVER_NAME, Env:\SQL_DATABASE, Env:\SQL_UID, Env:\SQL_PWD

Troubleshooting

Sintoma O que verificar Corrigir
Could not open input file: .\pie.phar Diretório atual e local de download Volte ao diretório que contém o PHAR verificado, ou baixe e verifique novamente
Unable to load dynamic library extension_dir, nome exato da DLL, versão secundária do PHP, arquitetura e modo de segurança de threads Selecione a DLL correspondente ou execute novamente o PIE com o executável PHP pretendido
The specified module could not be found Dependências de DLL do driver Confirme a existência da DLL de extensão, instale o Visual C++ Redistributable correspondente e inspecione qualquer dependência de DLL ausente restante
O CLI carrega ambos os drivers, mas o IIS não Executável PHP diferente ou php.ini Compare php --ini com phpinfo(), configure o tempo de execução do IIS e reinicie o FastCGI.
Module "sqlsrv" is already loaded Tanto entradas PIE quanto ZIP, ou entradas repetidas Mantenha uma entrada SQLSRV e uma PDO_SQLSRV entrada
PDO informa could not find driver configuração do PDO_SQLSRV Execute php --ri pdo_sqlsrv e verifique PDO::getAvailableDrivers()
O PIE indica sucesso, mas uma versão antiga permanece Entradas ZIP versionadas ainda ativas Substitua entradas antigas pelas entradas DLL não versionadas do PIE e reinicie todos os processos PHP

Se ambas as extensões carregarem, o PHP pode chamar suas APIs. Capture os erros SQLSRV ou a exceção PDO antes de trocar os arquivos do driver. Erros de rede, autenticação, criptografia, certificado e permissão de banco de dados não são corrigidos reinstalando a extensão PHP.