Instale os drivers da Microsoft para PHP no Linux e macOS

Essas instruções instalam PHP, o Microsoft ODBC Driver para SQL Server e as extensões SQLSRV e PDO_SQLSRV. Cada guia usa o pacote PHP fornecido pelo repositório do qual essa guia instala, portanto, a versão dos comandos difere de uma guia para outra. Substitua por outra versão do PHP listada na matriz de suporte se esse repositório oferecer uma diferente.

Os drivers SQLSRV e PDO_SQLSRV usam a mesma dependência ODBC e podem ser instalados de forma independente. Instale ambas as extensões se seu aplicativo usar ambos os drivers.

Ao final do procedimento, a CLI e o runtime selecionado do servidor web devem carregar ambas as extensões, ambas as APIs PHP devem estar disponíveis, e a amostra de cada API deve retornar a versão do servidor de banco de dados.

Antes de começar

  1. Escolha uma versão PHP suportada pela versão atual do driver e disponível para a versão do seu sistema operacional.

  2. Decida quais runtimes PHP você precisa:

    • CLI para scripts, tarefas agendadas ou workers.
    • Módulo Apache para PHP hospedado em Apache.
    • PHP-FPM para nginx ou uma configuração Apache FastCGI.
  3. Confirme a arquitetura do sistema operacional. Arquivos Linux lançados contêm binários x64 e arquivos lançados do macOS contêm binários Arm64. O PIE cria compilações para a instalação do PHP no computador e é o caminho principal de instalação neste artigo.

  4. Instale o driver Microsoft ODBC e o pacote de desenvolvimento unixODBC. O pacote da Microsoft gerencia a comunicação com banco de dados. O pacote unixODBC fornece os cabeçalhos necessários para construir SQLSRV e PDO_SQLSRV.

  5. Planeje reiniciar todos os servidores web, o pool do PHP-FPM e os workers de longa duração após instalar ou alterar uma extensão.

O gerenciador de pacotes da plataforma instala PHP e pré-requisitos nativos. O PIE compila e instala as extensões PHP. A configuração do PHP controla se cada runtime os carrega. O driver ODBC cuida da comunicação e da criptografia do banco de dados depois que a extensão é carregada.

Instale os drivers com PIE

PIE, o PHP Installer for Extensions, é o instalador de extensões suportado para as versões atuais dos drivers. Ele substitui o fluxo de trabalho obsoleto Biblioteca da Comunidade de Extensões do PHP (PECL).

Complete os pré-requisitos da plataforma nas seções seguintes antes de instalar os drivers. Depois, instale o PIE e cada driver separadamente:

Instale PIE

O PIE roda em PHP 8.1 e versões posteriores. Ele pode instalar uma extensão em outra instalação PHP quando você seleciona as ferramentas de desenvolvimento dessa instalação.

Instale curl e a CLI do GitHub antes de continuar. As seções da plataforma incluem curl em que uma instalação mínima pode não fornecê-la.

Baixe o arquivo compactado PIE PHP (PHAR) e verifique-o com a interface de linha de comando (CLI) do GitHub antes de instalá-lo ou executá-lo:

pie_tmp=$(mktemp -d)
curl -fL --output "$pie_tmp/pie.phar" https://github.com/php/pie/releases/latest/download/pie.phar
gh attestation verify --owner php "$pie_tmp/pie.phar"

Continue somente se a verificação for bem-sucedida:

sudo install -m 755 "$pie_tmp/pie.phar" /usr/local/bin/pie
rm "$pie_tmp/pie.phar"
rmdir "$pie_tmp"
unset pie_tmp

O diretório temporário é privado para sua conta. Se o download ou a verificação falharem, não instale nem execute o PHAR. Remova o arquivo e o diretório temporários antes de tentar novamente.

Confirme que o PHAR instalado roda com o executável PHP que você pretende usar:

php /usr/local/bin/pie --version

Instale os drivers SQLSRV e PDO_SQLSRV

No Linux e macOS, o PIE verifica a presença do compilador e das ferramentas de desenvolvimento PHP de que ele precisa. Instale o pacote de desenvolvimento ODBC da plataforma e um compilador C++ antes de rodar o PIE. Rodar o PIE a partir de um terminal interativo. Ele pode solicitar sua sudo senha quando precisar de permissão para instalar arquivos nos diretórios do sistema.

O PIE visa a instalação do PHP usada para invocá-lo. Para uma instalação com controle de versão, adicione --with-php-config a cada comando de instalação para selecionar suas ferramentas de desenvolvimento. Por exemplo, use pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv quando a ferramenta pretendida é /usr/bin/php-config8.4. Aplique a mesma opção a microsoft/pdo_sqlsrv. O Alpine usa nomes executáveis versionados; siga os comandos Alpine em vez dos comandos não versionados nesta seção.

Execute um comando para cada extensão. Esses comandos usam a instalação padrão do PHP do PIE:

pie install microsoft/sqlsrv
pie install microsoft/pdo_sqlsrv

PIE tenta habilitar cada extensão por meio das ferramentas de configuração do PHP da plataforma ou por meio de uma entrada extension=, e emite um aviso caso não consiga. O PHP utiliza uma interface de programação de aplicações do servidor (SAPI) para cada ambiente de execução. No Debian, no Ubuntu e no SUSE, as configurações da linha de comando, do Apache e do PHP FastCGI Process Manager (PHP-FPM) podem variar. Uma instalação bem-sucedida pela linha de comando não garante que o servidor web carregue os drivers.

Verifique php --ini para a linha de comando. Antes de criar uma página temporária phpinfo() para o servidor web, restrinja o acesso à página de diagnóstico. Verifique o Arquivo de Configuração Carregado e os .ini arquivos escaneados de cada runtime. Se as entradas estiverem faltando, siga Carregar os drivers no Linux e macOS para adicioná-los na ordem correta de carregamento. Reinicie o servidor web ou PHP-FPM após alterações de configuração. A Red Hat geralmente compartilha php.ini entre SAPIs, mas verifique a configuração ativa antes de depender de uma execução de PIE.

Instale na sua plataforma

Selecione seu sistema operacional e a configuração do servidor web. Conclua as etapas de instalação nessa guia e siga Testando sua instalação.

Instalação no Ubuntu

Observação

Os comandos a seguir utilizam o repositório PHP packages.sury.org para que você possa selecionar uma versão PHP suportada. Use as instruções oficiais da Microsoft para instalar o driver ODBC para sua versão do Ubuntu.

Etapa 1. Instalar o PHP (Ubuntu)

sudo apt-get update
sudo apt-get install ca-certificates apt-transport-https curl gnupg2 lsb-release -y
sudo install -d -m 755 /etc/apt/keyrings
sudo curl -fsSL https://packages.sury.org/php/apt.gpg -o /etc/apt/keyrings/php.gpg
sudo chmod 644 /etc/apt/keyrings/php.gpg
echo "deb [signed-by=/etc/apt/keyrings/php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt-get update
sudo apt-get install php8.4 php8.4-dev php8.4-xml -y

Etapa 2. Instalar pré-requisitos (Ubuntu)

Siga as instruções em Instalar o Microsoft ODBC Driver for SQL Server no Linux e instale os cabeçalhos de desenvolvimento.

sudo apt-get install unixodbc-dev g++ make git -y

Etapa 3. Instale os drivers PHP para Microsoft SQL Server com PIE (Ubuntu)

Siga Instalar os drivers com PIE, adicionando --with-php-config=/usr/bin/php-config8.4 aos dois comandos de instalação. Verifique os arquivos de configuração da linha de comando com php8.4 --ini.

/usr/local/bin/pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv
/usr/local/bin/pie install --with-php-config=/usr/bin/php-config8.4 microsoft/pdo_sqlsrv

Etapa 4. Instalar o Apache e configurar o carregamento de driver (Ubuntu)

sudo apt-get install apache2 libapache2-mod-php8.4 -y
sudo a2enmod php8.4

Etapa 5. Reinicie o Apache e teste o script de exemplo (Ubuntu)

sudo systemctl restart apache2

Para testar sua instalação, consulte Testando sua instalação no final deste documento.

Instalação da PECL herdada

O PECL está descontinuado para as versões atuais dos drivers. Use o PIE para novas instalações e atualizações. Se uma implantação existente estiver fixada ao PECL, mantenha suas versões de pacotes alinhadas com o runtime do PHP e planeje uma transição para o PIE.

Teste sua instalação

Verifique o runtime de linha de comando. Em Alpine, substitua php por php84. Para uma instalação PHP versionada em outra distribuição, use seu executável correspondente.

php --ri sqlsrv
php --ri pdo_sqlsrv
php -m | grep -E "sqlsrv|pdo_sqlsrv"

Ambos --ri os comandos devem imprimir informações do módulo que incluam ExtensionVer. A lista de módulos deve conter linhas separadas para sqlsrv e pdo_sqlsrv.

Antes de testar uma conexão, verifique ambas as superfícies de API PHP com verify-php-drivers.php:

<?php
$checks = [
    'SQLSRV' => extension_loaded('sqlsrv') && function_exists('sqlsrv_connect'),
    'PDO_SQLSRV' => extension_loaded('pdo_sqlsrv')
        && in_array('sqlsrv', PDO::getAvailableDrivers(), true),
];

$failed = false;
foreach ($checks as $name => $loaded) {
    echo "$name: " . ($loaded ? 'loaded' : 'missing') . PHP_EOL;
    $failed = $failed || !$loaded;
}

exit($failed ? 1 : 0);

Resultado esperado:

SQLSRV: loaded
PDO_SQLSRV: loaded

Para PHP-FPM ou um servidor web, restrinja o acesso a páginas de diagnóstico antes de criar uma página temporária phpinfo() . Confirme o arquivo de configuração carregado, extension_dir e ambas as seções do driver. Reinicie PHP-FPM ou o servidor web após mudar a configuração ou substituir uma extensão. Exclua a página após a verificação.

Para testar uma conexão ativa, crie um arquivo chamado testsql.php na raiz do documento do seu sistema. Esse caminho está /var/www/html no Ubuntu, Debian e Red Hat, /srv/www/htdocs no SUSE, /var/www/localhost/htdocs no Alpine ou $(brew --prefix)/var/www no macOS. Defina as variáveis de ambiente SQL_SERVER_NAME, SQL_DATABASE, SQL_UID e SQL_PWD para o processo PHP antes de executar o script. Não inclua credenciais em código em um arquivo na raiz do documento.

Para um teste de linha de comando, use os prompts interativos para definir as variáveis de ambiente sem inserir uma senha no histórico do shell.

Para um teste de módulo Apache, mantenha credenciais fora do arquivo de configuração geralmente legível do site:

  1. Crie um arquivo privado fora da raiz do documento. Use um nome de arquivo não utilizado no diretório de configuração do Apache. No Linux:

    sudo install -o root -g root -m 600 /dev/null /etc/apache2/php-sql-driver-test.conf
    

    No Red Hat, substitua /etc/apache2 por /etc/httpd. No macOS, crie o arquivo como a conta que inicia o Apache do Homebrew:

    install -m 600 /dev/null "$(brew --prefix)/etc/httpd/php-sql-driver-test.conf"
    

    Apenas o proprietário do arquivo e root podem ler essas configurações. A conta que inicia o Apache deve ser capaz de ler o arquivo.

  2. Edite o arquivo privado em um editor de texto e adicione estas entradas:

    SetEnv SQL_SERVER_NAME "tcp:<server>,1433"
    SetEnv SQL_DATABASE "<database>"
    SetEnv SQL_UID "<user_id>"
    SetEnv SQL_PWD "<password>"
    

    Dentro dos argumentos com aspas duplas, escreva \\ para cada barra invertida literal e \" para cada aspa dupla literal. Mantenha os espaços iniciais e finais dentro das aspas. Apache também substitui as referências ${NAME}. Se um valor contiver essa sequência ou uma quebra de linha, use o comando de teste na linha de comando. Para mais informações, veja aspas e escape na configuração do Apache.

  3. Dentro do host virtual do site, adicione um Files bloco que inclua o arquivo privado apenas para testsql.php. Se nenhum host virtual estiver configurado, coloque o bloco na configuração do servidor principal. Substitua o placeholder pelo caminho absoluto do arquivo privado:

    <Files "testsql.php">
        Include "<absolute-path-to-private-file>"
    </Files>
    
  4. Reinicie o Apache. Depois de testar, remova o bloco Files que você adicionou, apague o arquivo privado e reinicie o Apache novamente. Mantenha configurações de site não relacionadas.

PHP-FPM elimina as variáveis de ambiente herdadas por padrão, e o nginx não passa seu ambiente para o PHP-FPM. Use o procedimento a seguir do Ubuntu ou do Red Hat somente com um serviço e pool de teste isolados do PHP-FPM. Não adicione credenciais de teste a um serviço ou pool que roda outras aplicações: todo script desse pool pode lê-las. Se você usar hospedagem compartilhada, use o teste de linha de comando em vez disso.

  1. Crie um arquivo de propriedade da raiz fora da raiz do documento, como /etc/php-sql-driver-test.env, e restrinja o acesso a ele:

    sudo touch /etc/php-sql-driver-test.env
    sudo chmod 600 /etc/php-sql-driver-test.env
    

    Adicione as configurações de conexão ao arquivo:

    SQL_SERVER_NAME="tcp:<server>,1433"
    SQL_DATABASE="<database>"
    SQL_UID="<user_id>"
    SQL_PWD="<password>"
    

    Mantenha cada configuração em uma linha só. Dentro das aspas duplas, escreva \\ para cada barra invertida literal e \" para cada aspa dupla literal. Cifrões e backticks não são avaliados como expressões do shell. Edite o arquivo diretamente em vez de executá-lo ou fornecê-lo em um shell. Para mais informações, veja a sintaxe systemd EnvironmentFile.

  2. Execute sudo systemctl edit php8.4-fpm no Ubuntu ou sudo systemctl edit php-fpm no Red Hat. Adicione esta override do systemd:

    [Service]
    EnvironmentFile=/etc/php-sql-driver-test.env
    
  3. Adicione essas entradas à configuração ativa do pool de PHP-FPM. Locais comuns são /etc/php/8.4/fpm/pool.d/www.conf no Ubuntu e /etc/php-fpm.d/www.conf no Red Hat:

    env[SQL_SERVER_NAME] = $SQL_SERVER_NAME
    env[SQL_DATABASE] = $SQL_DATABASE
    env[SQL_UID] = $SQL_UID
    env[SQL_PWD] = $SQL_PWD
    
  4. Recarregue o systemd e reinicie o serviço PHP-FPM aplicável:

    sudo systemctl daemon-reload
    sudo systemctl restart php8.4-fpm
    

    No Red Hat, substitua php8.4-fpm por php-fpm.

Após o teste, remova o arquivo temporário de ambiente, a EnvironmentFile= entrada que você adicionou, as entradas do pool de teste e testsql.php. Exclua o arquivo de override do serviço somente se você o criou para este teste e ele não tiver outras configurações. Mantenha todas as sobreposições e configurações de pool já existentes. Recarregue o systemd e reinicie PHP-FPM novamente após remover a configuração de teste.

Exemplo com SQLSRV

Mantenha os valores do ambiente inalterados. Cada exemplo rejeita configurações ausentes ou vazias antes de conectar. Cada exemplo então 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');
$databaseName = getenv('SQL_DATABASE');
$uid = getenv('SQL_UID');
$pwd = getenv('SQL_PWD');

if ($serverName === false || $serverName === ''
    || $databaseName === false || $databaseName === ''
    || $uid === false || $uid === ''
    || $pwd === false || $pwd === '') {
    handle_failure("Set SQL_SERVER_NAME, SQL_DATABASE, SQL_UID, and SQL_PWD.");
}

$databaseName = '{' . str_replace('}', '}}', $databaseName) . '}';
$uid = '{' . str_replace('}', '}}', $uid) . '}';
$pwd = '{' . str_replace('}', '}}', $pwd) . '}';
$connectionOptions = array(
    "Database" => $databaseName,
    "UID" => $uid,
    "PWD" => $pwd,
    "Encrypt" => 1,
    "TrustServerCertificate" => 0
);

function handle_failure($message) {
    error_log($message);
    http_response_code(500);
    echo "<h1>Failure</h1>";
    echo "An error occurred. Check the server error log for details.";
    exit(1);
}

function format_errors($errors) {
    $lines = [];
    foreach ($errors as $error) {
        $lines[] = "SQLSTATE: {$error['SQLSTATE']}, code: {$error['code']}, message: {$error['message']}";
    }
    return implode(PHP_EOL, $lines);
}

$conn = sqlsrv_connect($serverName, $connectionOptions);
if ($conn === false) {
    handle_failure(format_errors(sqlsrv_errors()));
}

$tsql = "SELECT @@Version AS SQL_VERSION";

$stmt = sqlsrv_query($conn, $tsql);
if ($stmt === false) {
    handle_failure(format_errors(sqlsrv_errors()));
}

$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if ($row === null || $row === false) {
    handle_failure("Query returned no rows.");
}

echo "<h1>Success</h1>";
echo htmlspecialchars($row['SQL_VERSION']);

sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>

Exemplo com PDO_SQLSRV

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

if ($serverName === false || $serverName === ''
    || $databaseName === false || $databaseName === ''
    || $uid === false || $uid === ''
    || $pwd === false || $pwd === '') {
    handle_failure(new RuntimeException("Set SQL_SERVER_NAME, SQL_DATABASE, SQL_UID, and SQL_PWD."));
}

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

function handle_failure($exception) {
    error_log($exception->getMessage());
    http_response_code(500);
    echo "<h1>Failure</h1>";
    echo "An error occurred. Check the server error log for details.";
    exit(1);
}

try {
    $conn = new PDO(
        "sqlsrv:server=$serverName;Database=$databaseName;Encrypt=1;TrustServerCertificate=0",
        $uid,
        $pwd
    );
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $tsql = "SELECT @@Version AS SQL_VERSION";

    $stmt = $conn->query($tsql);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row === false) {
        throw new RuntimeException("Query returned no rows.");
    }

    echo "<h1>Success</h1>";
    echo htmlspecialchars($row['SQL_VERSION']);
} catch (Throwable $exception) {
    handle_failure($exception);
}

unset($stmt);
unset($conn);
?>

Aponte seu navegador para http://localhost/testsql.php (http://localhost:8080/testsql.php no macOS). Uma conexão bem-sucedida exibe a string de versão do servidor de banco de dados. Ambos os exemplos escrevem detalhes de erro no registro de erros do PHP. Se a página mostrar uma falha, verifique esse log.

Para comparar o comportamento da linha de comando e do servidor web, defina as mesmas variáveis de ambiente para seu terminal e execute:

php testsql.php

Se executar pela linha de comando der certo, mas nada aparecer no seu navegador, verifique os arquivos de log do Apache. Para mais ajuda, veja Recursos de Suporte para o driver PHP SQL.

Avalie os programas conectores separadamente para SQL Server, Banco de Dados SQL do Azure, Instância Gerenciada de SQL do Azure, Azure Synapse Analytics, Banco de Dados SQL no Microsoft Fabric e Warehouse no Microsoft Fabric. O método de autenticação selecionado, as opções de conexão e a consulta devem ser suportados pelo destino de dados. A instalação é do lado do cliente. Uma verificação bem-sucedida de extensão não prova que um alvo aceita as credenciais, confia no cliente ou suporta todos os recursos do banco de dados.

Solucionar problemas de instalação

Sintoma Camada proprietária Ação corretiva
PIE não consegue encontrar phpize, php-config, ou cabeçalhos Pacotes de desenvolvimento PHP Instale o pacote de desenvolvimento para a versão PHP de destino e passe a opção correspondente --with-php-config
A compilação falha porque falta um compilador C++ Ferramentas de compilação do sistema operacional Instale o pacote compilador C++ da plataforma, como g++ ou gcc-c++
Compilação não consegue encontrar sql.h Caminhos do pacote de desenvolvimento ODBC ou do compilador Instalar unixodbc-dev ou unixODBC-devel; no Apple Silicon, definir as flags de include e de biblioteca do Homebrew
php --ri diz que a extensão não está presente Configuração PHP Inspecione o php.ini carregado e o diretório de verificação, adicione a entrada correta e reinicie o processo
PDO informa could not find driver Carregamento de PDO_SQLSRV ou ordem de carregamento do PDO Confirme que o PDO carrega primeiro e PDO_SQLSRV usa um arquivo de configuração escaneado posteriormente
CLI funciona, mas Apache, nginx ou PHP-FPM falham Configuração específica para SAPI Compare a saída da CLI com phpinfo(), configure o SAPI Web e reinicie-o
O navegador retorna HTTP 502 por meio do nginx roteamento do nginx para o PHP-FPM Verifique o socket fastcgi_pass com a versão PHP-FPM instalada e confirme se o serviço está em execução
O exemplo do navegador informa a ausência de valores de ambiente Servidor web ou ambiente PHP-FPM Configure as variáveis para o runtime web selecionado e depois reinicie-o
As extensões são carregadas, mas uma conexão tem falha ODBC, rede, certificado, autenticação ou produto SQL Leia o SQLSTATE e o erro nativo do log do servidor; não reconstrua a extensão a menos que o erro identifique carregamento ou compatibilidade binária

Remover configuração temporária de teste

Após a verificação:

  1. Exclua testsql.php, verify-php-drivers.php, e qualquer página temporária phpinfo() da raiz do documento.

  2. Remova credenciais temporárias e entradas de encaminhamento de ambiente.

  3. Recarregue o gerenciador de serviços quando você mudar uma override do systemd, depois reinicie PHP-FPM ou o servidor web.

  4. Mantenha as entradas de extensão e os pacotes instalados que o aplicativo exige.