Bemærk
Adgang til denne side kræver godkendelse. Du kan prøve at logge på eller ændre mapper.
Adgang til denne side kræver godkendelse. Du kan prøve at ændre mapper.
These instructions install PHP, the Microsoft ODBC Driver for SQL Server, and the SQLSRV and PDO_SQLSRV extensions. Each tab uses the PHP package provided by the repository that tab installs from, so the version in the commands differs from one tab to the next. Replace it with another PHP version listed in the support matrix if that repository offers a different one.
The SQLSRV and PDO_SQLSRV drivers use the same ODBC dependency and can be installed independently. Install both extensions if your application uses both drivers.
At the end of the procedure, the CLI and selected web-server runtime should load both extensions, both PHP APIs should be available, and the sample for each API should return the database server version.
Before you start
Choose a PHP version supported by the current driver release and available for your operating-system release.
Decide which PHP runtimes you need:
- CLI for scripts, scheduled tasks, or workers.
- Apache module for Apache-hosted PHP.
- PHP-FPM for nginx or an Apache FastCGI configuration.
Confirm the operating-system architecture. Released Linux archives contain x64 binaries and released macOS archives contain Arm64 binaries. PIE builds for the PHP installation on the computer and is the primary installation path in this article.
Install the Microsoft ODBC Driver and the unixODBC development package. The Microsoft package handles database communication. The unixODBC package supplies headers required to build SQLSRV and PDO_SQLSRV.
Plan to restart every web server, PHP-FPM pool, and long-running worker after installing or changing an extension.
The platform package manager installs PHP and native prerequisites. PIE builds and installs the PHP extensions. PHP configuration controls whether each runtime loads them. The ODBC driver handles database communication and encryption after the extension loads.
Install the drivers with PIE
PIE, the PHP Installer for Extensions, is the supported extension installer for current driver releases. It replaces the deprecated PHP Extension Community Library (PECL) workflow.
Complete the platform prerequisites in the following sections before installing the drivers. Then install PIE and each driver separately:
Install PIE
PIE runs on PHP 8.1 and later versions. It can install an extension into another PHP installation when you select that installation's development tools.
Install curl and the GitHub CLI before continuing. The platform sections include curl where a minimal installation might not provide it.
Download the PIE PHP archive (PHAR), and verify it with the GitHub command-line interface (CLI) before installing or running it:
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 only if verification succeeds:
sudo install -m 755 "$pie_tmp/pie.phar" /usr/local/bin/pie
rm "$pie_tmp/pie.phar"
rmdir "$pie_tmp"
unset pie_tmp
The temporary directory is private to your account. If download or verification fails, don't install or run the PHAR. Remove the temporary file and directory before retrying.
Confirm that the installed PHAR runs with the PHP executable you intend to use:
php /usr/local/bin/pie --version
Install the SQLSRV and PDO_SQLSRV drivers
On Linux and macOS, PIE checks for the compiler and PHP development tools it needs. Install the platform ODBC development package and a C++ compiler before running PIE. Run PIE from an interactive terminal. It can request your sudo password when it needs permission to install files into system directories.
PIE targets the PHP installation used to invoke it. For a versioned installation, add --with-php-config to each install command to select its development tools. For example, use pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv when the intended tool is /usr/bin/php-config8.4. Apply the same option to microsoft/pdo_sqlsrv. Alpine uses versioned executable names; follow the Alpine commands instead of the unversioned commands in this section.
Run one command for each extension. These commands use PIE's default PHP installation:
pie install microsoft/sqlsrv
pie install microsoft/pdo_sqlsrv
PIE attempts to enable each extension through the platform's PHP configuration tools or an extension= entry, and warns if it can't. PHP uses a server application programming interface (SAPI) for each execution environment. On Debian, Ubuntu, and SUSE, the command-line, Apache, and PHP FastCGI Process Manager (PHP-FPM) configurations can differ. A successful command-line installation doesn't confirm that a web server loads the drivers.
Check php --ini for the command line. Before creating a temporary phpinfo() page for the web server, restrict diagnostic-page access. Check the Loaded Configuration File and scanned .ini files for each runtime. If the entries are missing, follow Load the drivers on Linux and macOS to add them in the correct load order. Restart the web server or PHP-FPM after configuration changes. Red Hat commonly shares php.ini across SAPIs, but verify the active configuration before relying on one PIE run.
Install on your platform
Select your operating system and web server configuration. Complete the installation steps in that tab, then follow Testing your installation.
Install on Ubuntu
Note
The following commands use the packages.sury.org PHP repository so that you can select a supported PHP version. Use the official Microsoft instructions to install the ODBC driver for your Ubuntu release.
Step 1. Install 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
Step 2. Install prerequisites (Ubuntu)
Follow Install the Microsoft ODBC Driver for SQL Server on Linux, then install the development headers.
sudo apt-get install unixodbc-dev g++ make git -y
Step 3. Install the PHP drivers for Microsoft SQL Server with PIE (Ubuntu)
Follow Install the drivers with PIE, adding --with-php-config=/usr/bin/php-config8.4 to both install commands. Check the command-line configuration files with 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
Step 4. Install Apache and configure driver loading (Ubuntu)
sudo apt-get install apache2 libapache2-mod-php8.4 -y
sudo a2enmod php8.4
Step 5. Restart Apache and test the sample script (Ubuntu)
sudo systemctl restart apache2
To test your installation, see Testing your installation at the end of this document.
Legacy PECL installation
PECL is deprecated for current driver releases. Use PIE for new installations and upgrades. If an existing deployment is pinned to PECL, keep its package versions aligned with the PHP runtime and plan a move to PIE.
Test your installation
Verify the command-line runtime. On Alpine, replace php with php84. For a versioned PHP installation on another distribution, use its corresponding executable.
php --ri sqlsrv
php --ri pdo_sqlsrv
php -m | grep -E "sqlsrv|pdo_sqlsrv"
Both --ri commands should print module information that includes ExtensionVer. The module list should contain separate sqlsrv and pdo_sqlsrv lines.
Before testing a connection, verify both PHP API surfaces with 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);
Expected output:
SQLSRV: loaded
PDO_SQLSRV: loaded
For PHP-FPM or a web server, restrict diagnostic-page access before creating a temporary phpinfo() page. Confirm the Loaded Configuration File, extension_dir, and both driver sections. Restart PHP-FPM or the web server after changing configuration or replacing an extension. Remove the page after verification.
To test a live connection, create a file called testsql.php in your system's document root. This path is /var/www/html on Ubuntu, Debian, and Red Hat, /srv/www/htdocs on SUSE, /var/www/localhost/htdocs on Alpine, or $(brew --prefix)/var/www on macOS. Set the SQL_SERVER_NAME, SQL_DATABASE, SQL_UID, and SQL_PWD environment variables for the PHP process before running the script. Don't hardcode credentials in a file under the document root.
For a command-line test, use the interactive prompts to set the environment variables without entering a password in shell history.
For an Apache module test, keep credentials out of the site's generally readable configuration file:
Create a private file outside the document root. Use an unused file name in Apache's configuration directory. On Linux:
sudo install -o root -g root -m 600 /dev/null /etc/apache2/php-sql-driver-test.confOn Red Hat, replace
/etc/apache2with/etc/httpd. On macOS, create the file as the account that starts Homebrew's Apache:install -m 600 /dev/null "$(brew --prefix)/etc/httpd/php-sql-driver-test.conf"Only the file owner and root can read these settings. The account that starts Apache must be able to read the file.
Edit the private file in a text editor, and add these entries:
SetEnv SQL_SERVER_NAME "tcp:<server>,1433" SetEnv SQL_DATABASE "<database>" SetEnv SQL_UID "<user_id>" SetEnv SQL_PWD "<password>"Within the double-quoted arguments, write
\\for each literal backslash and\"for each literal double quote. Preserve leading and trailing spaces inside the quotes. Apache also substitutes${NAME}references. If a value contains that sequence or a line break, use the command-line test instead. For more information, see Apache configuration quoting and escaping.Inside the site's virtual host, add a
Filesblock that includes the private file only fortestsql.php. If no virtual host is configured, place the block in the main server configuration. Replace the placeholder with the private file's absolute path:<Files "testsql.php"> Include "<absolute-path-to-private-file>" </Files>Restart Apache. After testing, remove the
Filesblock you added, delete the private file, and restart Apache again. Keep unrelated site settings.
PHP-FPM clears inherited environment variables by default, and nginx doesn't pass its environment to PHP-FPM. Use the following Ubuntu or Red Hat procedure only with an isolated test PHP-FPM service and pool. Don't add test credentials to a service or pool that runs other applications: every script in that pool can read them. If you use shared hosting, use the command-line test instead.
Create a root-owned file outside the document root, such as
/etc/php-sql-driver-test.env, and restrict access to it:sudo touch /etc/php-sql-driver-test.env sudo chmod 600 /etc/php-sql-driver-test.envAdd the connection settings to the file:
SQL_SERVER_NAME="tcp:<server>,1433" SQL_DATABASE="<database>" SQL_UID="<user_id>" SQL_PWD="<password>"Keep each setting on one line. Within the double quotes, write
\\for each literal backslash and\"for each literal double quote. Dollar signs and backticks aren't evaluated as shell expressions. Edit the file directly rather than running or sourcing it in a shell. For more information, see systemd EnvironmentFile syntax.Run
sudo systemctl edit php8.4-fpmon Ubuntu orsudo systemctl edit php-fpmon Red Hat. Add this systemd override:[Service] EnvironmentFile=/etc/php-sql-driver-test.envAdd these entries to the active PHP-FPM pool configuration. Common locations are
/etc/php/8.4/fpm/pool.d/www.confon Ubuntu and/etc/php-fpm.d/www.confon Red Hat:env[SQL_SERVER_NAME] = $SQL_SERVER_NAME env[SQL_DATABASE] = $SQL_DATABASE env[SQL_UID] = $SQL_UID env[SQL_PWD] = $SQL_PWDReload systemd and restart the applicable PHP-FPM service:
sudo systemctl daemon-reload sudo systemctl restart php8.4-fpmOn Red Hat, replace
php8.4-fpmwithphp-fpm.
After testing, remove the temporary environment file, the EnvironmentFile= entry you added, the test pool entries, and testsql.php. Delete the service override file only if you created it for this test and it contains no other settings. Keep all preexisting overrides and pool settings. Reload systemd and restart PHP-FPM again after removing the test configuration.
SQLSRV example
Keep the environment values unchanged. Each example rejects missing or empty settings before connecting. Each example then doubles closing braces and adds outer braces before passing the database name, user name, and password to the driver. This encoding preserves literal braces and prevents semicolons from separating connection options.
<?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 example
<?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);
?>
Point your browser to http://localhost/testsql.php (http://localhost:8080/testsql.php on macOS). A successful connection displays the database server's version string. Both examples write error details to the PHP error log. If the page displays a failure, check that log.
To compare command-line and web-server behavior, set the same environment variables for your terminal and run:
php testsql.php
If running from the command line succeeds but nothing appears in your browser, check the Apache log files. For more help, see Support resources for the PHP SQL driver.
Evaluate the connection programs separately for SQL Server, Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics, SQL database in Microsoft Fabric, and Warehouse in Microsoft Fabric. The selected authentication method, connection options, and query must be supported by the target. Installation is client-side. A successful extension check doesn't prove that a target accepts the credentials, trusts the client, or supports every database feature.
Troubleshoot installation
| Symptom | Owning layer | Corrective action |
|---|---|---|
PIE can't find phpize, php-config, or headers |
PHP development packages | Install the development package for the target PHP version and pass the matching --with-php-config option |
| Compilation fails because a C++ compiler is missing | Operating-system build tools | Install the platform C++ compiler package, such as g++ or gcc-c++ |
Compilation can't find sql.h |
ODBC development package or compiler paths | Install unixodbc-dev or unixODBC-devel; on Apple silicon, set the Homebrew include and library flags |
php --ri says the extension isn't present |
PHP configuration | Inspect the loaded php.ini and scan directory, add the correct entry, and restart the process |
PDO reports could not find driver |
PDO_SQLSRV loading or PDO load order | Confirm PDO loads first and PDO_SQLSRV uses a later scanned configuration file |
| CLI works but Apache, nginx, or PHP-FPM fails | SAPI-specific configuration | Compare CLI output with phpinfo(), configure the web SAPI, and restart it |
| The browser returns HTTP 502 through nginx | nginx to PHP-FPM routing | Check the fastcgi_pass socket against the installed PHP-FPM version and confirm the service is running |
| The browser sample reports missing environment values | Web-server or PHP-FPM environment | Configure the variables for the selected web runtime, then restart it |
| Extensions load but a connection fails | ODBC, network, certificate, authentication, or SQL product | Read the SQLSTATE and native error from the server log; don't rebuild the extension unless the error identifies loading or binary compatibility |
Remove temporary test configuration
After verification:
Delete
testsql.php,verify-php-drivers.php, and any temporaryphpinfo()page from the document root.Remove temporary credentials and environment-forwarding entries.
Reload the service manager when you change a systemd override, then restart PHP-FPM or the web server.
Keep the extension entries and installed packages that the application requires.