Instale os drivers Microsoft para PHP no Linux e macOS

Estas instruções instalam o PHP, o Microsoft ODBC Driver for SQL Server, e as extensões SQLSRV e PDO_SQLSRV. Cada separador utiliza o pacote PHP fornecido pelo repositório a partir do qual esse separador instala, pelo que a versão nos comandos difere de um separador para outro. Substitua-a por outra versão PHP listada na matriz de suporte se esse repositório oferecer uma diferente.

Os drivers SQLSRV e PDO_SQLSRV utilizam a mesma dependência ODBC e podem ser instalados de forma independente. Instala ambas as extensões se a tua aplicação usar ambos os drivers.

No 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 o exemplo de cada API deve devolver a versão do servidor de base 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 de lançamento do sistema operativo.

  2. Decida quais os runtimes PHP de que precisa:

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

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

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

O gestor de pacotes da plataforma instala PHP e pré-requisitos nativos. O PIE constrói e instala as extensões PHP. A configuração do PHP controla se cada runtime os carrega. O driver ODBC gere a comunicação e a encriptação da base de dados depois de a extensão ser carregada.

Instale os controladores com PIE

O PIE, o PHP Installer for Extensions, é o instalador de extensões suportado para as versões atuais dos drivers. Substitui o fluxo de trabalho obsoleto PHP Extension Community Library (PECL).

Cumpra os pré-requisitos da plataforma nas secções seguintes antes de instalar os drivers. Depois instale o PIE e cada controlador separadamente:

Instalar PIE

O PIE corre em PHP 8.1 e versões posteriores. Pode instalar uma extensão noutra instalação PHP quando seleciona as ferramentas de desenvolvimento dessa instalação.

Instale curl e a GitHub CLI antes de continuar. As secções da plataforma incluem curl onde uma instalação mínima pode não o incluir.

Descarregue o arquivo PIE PHP (PHAR) e verifique-o com a interface de linha de comandos (CLI) do GitHub antes de o instalar ou executar:

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 apenas 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 é exclusivo da sua conta. Se falhar o download ou verificação, não instale nem execute o PHAR. Remova o ficheiro e o diretório temporários antes de tentar novamente.

Confirma se o PHAR instalado corre com o executável PHP que pretendes usar:

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

Instale os controladores SQLSRV e PDO_SQLSRV

No Linux e macOS, o PIE verifica o compilador e as ferramentas de desenvolvimento PHP necessárias. Instale o pacote de desenvolvimento ODBC da plataforma e um compilador C++ antes de executar o PIE. Executa o PIE a partir de um terminal interativo. Pode pedir a tua sudo palavra-passe quando precisar de permissão para instalar ficheiros nos diretórios do sistema.

O PIE tem como alvo a instalação do PHP usada para o invocar. Para uma instalação versionada, adicione --with-php-config a cada comando de instalação para selecionar as 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 secção.

Executa um comando para cada extensão. Estes comandos utilizam a instalação PHP padrão do PIE:

pie install microsoft/sqlsrv
pie install microsoft/pdo_sqlsrv

O PIE tenta ativar cada extensão através das ferramentas de configuração PHP da plataforma ou de uma extension= entrada, e avisa se não conseguir. O PHP utiliza uma interface de programação de aplicações do servidor (SAPI) para cada ambiente de execução. No Debian, Ubuntu e SUSE, as configurações de linha de comandos, Apache e PHP FastCGI Process Manager (PHP-FPM) podem ser diferentes. Uma instalação bem-sucedida na linha de comandos não confirma que um servidor web carrega os drivers.

Verifica em php --ini a linha de comandos. Antes de criar uma página temporária phpinfo() para o servidor web, restrinja o acesso à página de diagnóstico. Verifique o Ficheiro de Configuração Carregado e os ficheiros digitalizados .ini para cada runtime. Se as entradas estiverem em falta, siga Carregar os drivers no Linux e macOS para os adicionar na ordem de carregamento correta. Reinicie o servidor web ou PHP-FPM após alterações de configuração. A Red Hat normalmente partilha php.ini entre SAPIs, mas verifica a configuração ativa antes de confiar numa execução de PIE.

Instale na sua plataforma

Selecione o seu sistema operativo e a configuração do servidor web. Complete os passos de instalação nesse separador e depois siga Testar a sua instalação.

Instalar no Ubuntu

Observação

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

Passo 1. Instalar 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

Passo 2. Pré-requisitos para instalação (Ubuntu)

Siga Install the Microsoft ODBC Driver for SQL Server em Linux e depois instale os cabeçalhos de desenvolvimento.

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

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

Siga as instruções em Instalar os drivers com PIE, adicionando --with-php-config=/usr/bin/php-config8.4 a ambos os comandos de instalação. Verifique os ficheiros de configuração da linha de comandos 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

Passo 4. Instalar o Apache e configurar o carregamento dos drivers (Ubuntu)

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

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

sudo systemctl restart apache2

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

Instalação legada do PECL

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

Teste a sua instalação

Verifique o runtime da linha de comandos. Em Alpine, substitua php por php84. Para uma instalação PHP versionada noutra distribuição, use o executável correspondente.

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

Ambos --ri os comandos devem imprimir informação do módulo que inclua ExtensionVer. A lista de módulos deve conter linhas separadas de sqlsrv e pdo_sqlsrv.

Antes de testar uma ligação, verifique ambas as interfaces da 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);

Produção esperada:

SQLSRV: loaded
PDO_SQLSRV: loaded

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

Para testar uma ligação em tempo real, crie um ficheiro chamado testsql.php na raiz de documentos do seu sistema. Este 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 defina as credenciais de forma fixa num ficheiro na raiz do documento.

Para um teste de linha de comandos, utilize os prompts interativos para definir as variáveis de ambiente sem introduzir uma palavra-passe no histórico do shell.

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

  1. Crie um ficheiro privado fora da raiz do documento. Utilize um nome de ficheiro não utilizado na pasta de configuração do Apache. Em Linux:

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

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

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

    Só o proprietário do ficheiro e o root podem ler estas definições. A conta que inicia o Apache deve ser capaz de ler o ficheiro.

  2. Edite o ficheiro privado num 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 aspas dupla literal. Mantenha os espaços de abertura e de final 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 teste de linha de comandos em vez disso. Para mais informações, veja aspas e escape na configuração do Apache.

  3. Dentro do alojamento virtual do site, adicione um bloco Files que inclua o ficheiro privado apenas para testsql.php. Se não houver um host virtual configurado, coloque o bloco na configuração do servidor principal. Substitua o marcador pelo caminho absoluto do ficheiro privado:

    <Files "testsql.php">
        Include "<absolute-path-to-private-file>"
    </Files>
    
  4. Reinicia o Apache. Depois de testar, remove o Files bloco que adicionaste, apaga o ficheiro privado e reinicia o Apache novamente. Mantenha as definições do site não relacionadas.

PHP-FPM elimina as variáveis de ambiente herdadas por defeito, e o nginx não passa o seu ambiente para o PHP-FPM. Utilize apenas o seguinte procedimento do Ubuntu ou Red Hat com um serviço PHP-FPM de teste isolado e o respetivo pool. Não adicione credenciais de teste a um serviço ou pool que execute outras aplicações: todos os scripts desse pool podem lê-las. Se usares alojamento partilhado, usa antes o teste de linha de comandos.

  1. Crie um ficheiro 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 definições de ligação ao ficheiro:

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

    Mantenha cada definição numa linha. Dentro das aspas duplas, escreva \\ para cada barra invertida literal e \" para cada aspas dupla literal. Os signos do dólar e os backticks não são avaliados como expressões do shell. Edita o ficheiro diretamente em vez de o executares ou fazeres source dele numa shell. Para mais informações, consulte a sintaxe systemd EnvironmentFile.

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

    [Service]
    EnvironmentFile=/etc/php-sql-driver-test.env
    
  3. Adicione estas 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. Recarregar o systemd e reiniciar o serviço de PHP-FPM aplicável:

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

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

Após o teste, remova o ficheiro temporário do ambiente, a EnvironmentFile= entrada que adicionou, as entradas do pool de testes, e testsql.php. Apaga o ficheiro de sobreposição do serviço apenas se o criaste para este teste e não tiver outras definições. Mantém todas as substituições e definições do conjunto já existentes. Recarregue o systemd e reinicie o PHP-FPM novamente depois de remover a configuração de teste.

Exemplo de SQLSRV

Mantenha os valores do ambiente inalterados. Cada exemplo rejeita definições em falta ou vazias antes de estabelecer ligação. Cada exemplo duplica então as chavetas de fecho e adiciona chavetas exteriores antes de passar o nome da base de dados, nome de utilizador e palavra-passe ao driver. Esta codificação preserva as chavetas literais e impede que os pontos e vírgulas separem as opções de ligaçã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);
?>

PDO_SQLSRV exemplo

<?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 o seu navegador para http://localhost/testsql.php (http://localhost:8080/testsql.php no macOS). Uma ligação bem-sucedida apresenta a string de versão do servidor de base de dados. Ambos os exemplos escrevem detalhes de erro no registo de erros do PHP. Se a página mostrar um erro, verifique esse log.

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

php testsql.php

Se executar a partir da linha de comandos resultar mas nada aparecer no seu navegador, verifique os ficheiros de registo do Apache. Para mais ajuda, consulte Recursos de Suporte para o driver PHP SQL.

Avalie os programas de ligação separadamente para SQL Server, Base de Dados SQL do Azure, Azure SQL Managed Instance, Azure Synapse Analytics, base de dados SQL no Microsoft Fabric e Warehouse no Microsoft Fabric. O método de autenticação selecionado, as opções de ligação e a consulta devem ser suportados pelo destino. A instalação é no cliente. Uma verificação de extensão bem-sucedida não prova que um destino aceita as credenciais, confia no cliente ou suporta todas as funcionalidades da base de dados.

Solucionar problemas de instalação

Symptom Camada proprietária Ação corretiva
O PIE não consegue encontrar phpize, php-config, nem cabeçalhos Pacotes de desenvolvimento PHP Instala o pacote de desenvolvimento para a versão PHP alvo e passa a opção correspondente --with-php-config
A compilação falha porque falta um compilador C++ Ferramentas de compilação do sistema operativo Instale o pacote compilador C++ da plataforma, como g++ ou gcc-c++
A compilação não consegue encontrar sql.h Caminhos do pacote de desenvolvimento ODBC ou do compilador Instale unixodbc-dev ou unixODBC-devel; no Apple silicon, defina as flags de include e de library 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 análise, adicione a entrada correta e reinicie o processo
O PDO comunica could not find driver Carregamento do PDO_SQLSRV ou ordem de carregamento do PDO Confirma que o PDO carrega primeiro e PDO_SQLSRV usa um ficheiro de configuração lido posteriormente
A CLI funciona, mas Apache, nginx ou PHP-FPM falham Configuração específica do SAPI Compare a saída da CLI com phpinfo(), configure o SAPI web e reinicie-o
O navegador devolve HTTP 502 via nginx encaminhamento do nginx para o PHP-FPM Verifique o fastcgi_pass socket com a versão PHP-FPM instalada e confirme que o serviço está a funcionar
O exemplo do navegador reporta valores de ambiente em falta Ambiente de servidor web ou PHP-FPM Configura as variáveis para o runtime web selecionado e depois reinicia-o
Extensões carregam mas uma conexão falha ODBC, rede, certificado, autenticação ou produto SQL Leia o SQLSTATE e o erro nativo do registo do servidor; não reconstrua a extensão a menos que o erro indique problemas de carregamento ou de compatibilidade binária

Remova a configuração temporária de teste

Após a verificação:

  1. Apague 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 reencaminhamento do ambiente.

  3. Recarrega o gestor de serviços quando mudares uma configuração de substituição do systemd, depois reinicia o PHP-FPM ou o servidor web.

  4. Mantém as entradas de extensão e os pacotes instalados que a aplicação exige.