SQL Server için PHP sürücülerini yükseltin

SQLSRV'yi ve PDO_SQLSRV'yi birlikte yükseltin ki her iki uzantı aynı sürüm ailesini kullansın. PHP sürücüleri Microsoft ODBC Driver for SQL Server'ı kullanır, bu yüzden yükseltmeden önce sistem gereksinimlerini kontrol edin.

Bir yükseltme, PHP süreçlerine yüklenen yerel kodu değiştirir. Karma bir dağıtım, önceki sürümü çalıştırmaya devam edebilir, PHP başlangıcında başarısız olabilir veya CLI ve web uygulamasına farklı sürücü sürümleri sunabilir. Her PHP çalışma zamanının envanterini çıkarın ve doğrulama tamamlanana kadar önceki dosyaları ve yapılandırmayı koruyun.

Yükseltme yolunu seçin

Mevcut kurulum Hedef kurulumu Procedure
PIE PIE PIE'yi aynı PHP çalıştırılabilir dosyasıyla veya açıkça belirtilen php-config ile çalıştırın, sonra her SAPI'yi doğrulayın
Windows ZIP’i çıkardı Windows için ZIP Her iki versiyonlu DLL'yi değiştirin ve her iki yapılandırma girişini birlikte güncelleyin
Windows tarafından çıkarılan ZIP PIE Her iki PIE paketini kur, sürümlü DLL girişlerini PIE girişleriyle değiştir ve tekrarları kaldır
Linux veya macOS için yayımlanan arşiv PIE Her iki PIE paketini kurun, arşiv-dosya-adı girdilerini pdo_sqlsrv.so ve sqlsrv.so ile değiştirin ve PDO yükleme sırasını koruyun
Linux veya macOS PIE Yeni PHP minör versiyonu Yeni PHP geliştirme araçlarını yükleyin, o PHP kurulumu için her iki uzantıyı oluşturun ve her SAPI'yi ayrı ayrı yapılandırın

Geri dönüş kopyanız olana kadar önceki ikili dosyaların üzerine yazmayın. Uygulama her iki API'yi kullandığında sadece bir uzantıyı yükseltmeyin.

Yükseltmeden önce

  1. PHP çalıştırılabilir dosyasını, yapılandırma dosyasını, mimariyi, iş parçacığı güvenlik modu ve güncel sürücü sürümlerini kaydedin.

    php --version
    php --ini
    php --ri sqlsrv
    php --ri pdo_sqlsrv
    
  2. php.ini dosyasını ve sqlsrv veya pdo_sqlsrv yükleyen uzantıya özgü .ini dosyalarını yedekleyin.

  3. Hedef PHP sürümü ve işletim sistemi için destek matrisini kontrol edin.

  4. Sistem gereksinimlerinde ODBC uyumluluk tablosunu kontrol edin. Hedef sürücü sürümü gerektirdiğinde, PHP sürücü yükseltmesinden önce veya sırasında desteklenen bir ODBC sürümünü kurun.

  5. Web sunucusu, PHP FastCGI Process Manager (PHP-FPM), kuyruk çalışanları ve uzun süredir çalışan komut satırı çalışanları dahil olmak üzere PHP'yi çalıştıran her sürecin yeniden başlatılmasını planlayın.

  6. Her çalışma zamanından bir baz çizgisi kaydedin:

    • php --ri sqlsrv ve php --ri pdo_sqlsrv tarafından gösterilen ExtensionVer.
    • Yüklenen yapılandırma dosyası ve taranan .ini dizini
    • Uzantı dizini ve aktif sürücü dosya adları.
    • Uygulamanızın bağımlı olduğu her API'yi kullanan başarılı bir uygulama duman testi.
  7. Geri alma hazırlayın:

    • PHP minör versiyonunu değiştirirseniz önceki PHP çalışma zamanını erişilebilir tutun. Her web sunucusu ve worker için yapılandırılmış çalıştırılabilir dosyayı kaydedin.
    • Önceki SQLSRV ve PDO_SQLSRV dosyalarının kopyalarını saklayın.
    • Her değiştirilen php.ini veya uzantıya özel .ini dosyanın kopyalarını sakla.
    • Yükseltme bunu değiştirirse önceki ODBC paket sürümünü kaydedin.
    • Yerel uzantı dosyaları değiştirilirken trafiği veya worker süreçlerini nasıl durduracağınızı tanımlayın.

Windows'ta PIE ile yükseltme

Uygulamaya hizmet veren PHP yürütülebilir dosyasıyla birlikte PHP Eklenti Yükleyicisi'ni (PIE) kullanın. Öncelikle, PIE'yi indirip doğrulayın. Kurulum komutlarından birini çalıştırmadan önce, uygulama trafiğini boşaltın ve web sunucusını, FastCGI işlemlerini ve bu PHP kurulumunu kullanan çalışanları durdurun. Her iki uzantı ve yapılandırmaları hazır olana kadar otomatik olarak yeniden başlatmalarını engelleyin. PIE için ayrı bir komut satırı oturumu tutun.

PIE'nin kullandığı CLI yapılandırmasında mevcut SQLSRV ve PDO_SQLSRV uzantı girişlerini geçici olarak yorum satırı haline getirin. Aksi takdirde, PIE çalıştıran PHP işlemi eski DLL'leri yüklü tutabilir ve değiştirilmesini engelleyebilir. PIE'nin önkoşul eklentilerini etkin tutun.

İçinde pie.pharbulunan dizinden, her iki paketi ayrı ayrı yükleyin:

php .\pie.phar install microsoft/sqlsrv
php .\pie.phar install microsoft/pdo_sqlsrv

PIE, php_sqlsrv.dll ve php_pdo_sqlsrv.dll kurar. Her aktif yapılandırmada, extension=php_sqlsrv_85_ts_x64.dll ve extension=php_pdo_sqlsrv_85_ts_x64.dll gibi sürümlü ZIP girdilerini şu şekilde değiştirin:

extension=php_sqlsrv.dll
extension=php_pdo_sqlsrv.dll

Her iki girişi de etkinleştirin ve PIE otomatik etkinleştirmenin başarılı olduğunu bildirse bile tekrarlanan SQLSRV ve PDO_SQLSRV girişlerini kaldırın. Web sunucusu farklı bir PHP kurulumu kullanıyorsa, o kurulum için yükseltme ve yapılandırma değişikliklerini tekrarlayın.

Her PHP sürecini yeniden başlatın, sonra php --ri sqlsrv ve php --ri pdo_sqlsrv komutlarını ilgili yürütülebilir dosyayla çalıştırın. ExtensionVer öğesinin her iki sürücü için hedef sürümü rapor ettiğini onaylayın. Bir web uygulaması için, phpinfo() geçici bir sayfa oluşturmadan önce. Her iki değeri de doğrulayın, sonra sayfayı kaldırın.

Windows ZIP kurulumunu güncelleyin

  1. Hedef sürümün Windows ZIP'ini Microsoft Drivers for PHP for SQL Server sürümleri sayfasından indirin.

  2. Yeni dinamik bağlantı kütüphanesi (DLL) isimlerinin PHP minör sürümü, mimarisi ve iş parçacığı güvenlik modu ile eşleştiğini doğrulayın. Dosyaları değiştirmeden önce PHP web sunucusu veya işçi işlemlerini durdurun.

  3. PHP uzantı dizinindeki php_sqlsrv_*.dll ve php_pdo_sqlsrv_*.dll dosyalarının ikisini de değiştirin. Dosya adları hâlâ uyuyorsa mevcut extension= girişleri koruyun. Aksi halde, onları birlikte güncelleyin.

  4. Hedef PHP sürücüsü daha yeni desteklenen bir sürüm gerektiriyorsa SQL Server için Microsoft ODBC Sürücüsü'nü yükleyin veya yükseltin.

  5. Değiştirilen DLL'leri kullanan her PHP sürecini yeniden başlatın. Çalışan bir süreç, çıkana kadar eski yerel uzantıyı yüklü tutar.

Linux veya macOS'ta PIE ile yükseltme yapın

  1. PIE kurulu değilse, PIE kurulumu ve platform ön koşullarını takip edin. PHP geliştirme araçlarının ve ODBC geliştirme paketinin kurulduğunu doğrulayın. Etkileşimli bir oturumda, PIE platform paket yöneticisi aracılığıyla eksik derleme araçlarını yükleme istemi gösterebilir. Etkileşimsiz bir oturumda, PIE'yi çalıştırmadan önce onları kurun.

  2. Yükseltmeden önce PHP kurulumunu seçin. Sürümlü bir kurulum için, her iki kurulum komutuna da PIE'nin --with-php-config seçeneğini ekleyin. Örneğin, amaçlanan yapılandırma aracı pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv olduğunda /usr/bin/php-config8.4 kullanın. Aynı seçeneği uygulayın.microsoft/pdo_sqlsrv Alpine'ın sürümlü çalıştırılabilir dosyaları için Alpine kurulum komutlarını kullanın.

  3. Uygulama trafiğini tahliye edin ve bu PHP kurulumunu kullanan web sunucusunu, PHP-FPM süreçlerini ve çalışanları durdurun. Her iki uzantı ve yapılandırmaları hazır olana kadar otomatik olarak yeniden başlatmalarını engelleyin. PIE için ayrı bir komut satırı oturumu tutun.

    PIE'nin kullandığı CLI yapılandırmasında mevcut SQLSRV ve PDO_SQLSRV uzantı girişlerini geçici olarak yorum satırı haline getirin. PIE'nin önkoşul eklentilerini etkin tutun.

  4. Her iki paketi ayrı ayrı yükseltin. Bu komutlar PIE'nin varsayılan PHP kurulumunu kullanır:

    pie install microsoft/sqlsrv
    pie install microsoft/pdo_sqlsrv
    
  5. Uygulamanızın kullandığı PHP kurulumu için her aktif yapılandırmayı kontrol edin. Önceki manuel kurulumda, extension=PDO_SQLSRV_8.4_NTS.so ve extension=SQLSRV_8.4_NTS.so gibi arşiv dosya adları kullanılıyorsa, bu girişleri PIE tarafından yüklenen dosya adlarıyla değiştirin:

    extension=sqlsrv.so
    extension=pdo_sqlsrv.so
    

    Her iki sürücü girişini yeniden etkinleştirin ve tekrarları kaldırın. PDO_SQLSRV PDO'dan sonra yüklenen taranmış bir yapılandırma dosyasında tutun; Linux ve macOS'ta sürücüleri yükle bölümünde belirtildiği gibi. Bu yapılandırma değişikliğini uygulamanızın kullandığı komut satırı, PHP-FPM, web sunucusu ve işçi yapılandırmaları için tekrarlayın.

  6. Hedef sürüm gerektirdiğinde SQL Server için Microsoft ODBC Sürücüsü'nü güncelleyin.

  7. Yükseltilmiş PHP kurulumunu kullanan her CLI çalışanını, kuyruk çalışanını, web sunucusunu ve PHP-FPM hizmetini yeniden başlatın.

Yeniden başlat ve doğrula

Bir uzantı dosyasını değiştirmek, eski ikili dosyayı zaten yükleyen bir PHP sürecini güncellemez. Yükseltmeyi doğrulamadan önce web sunucusunu, PHP-FPM'yi ve uzun süredir çalışan tüm PHP çalışanlarını yeniden başlatın.

  1. Komut satırı çalışma zamanını doğrulayın:

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

    Linux veya macOS'ta, son komutu php -m | grep -E 'sqlsrv|pdo_sqlsrv' ile değiştirin.

  2. Bir web uygulaması için, geçici sayfa oluşturmadan önce phpinfo(). Yüklenmiş yapılandırma dosyasını, uzantı dizinini ve ExtensionVer öğesini her iki sürücü için de doğrulayın. ExtensionVer öğesinin hedef sürümü bildirdiğini doğrulayın, ardından sayfayı kaldırın.

  3. Uygulamanız her ikisini de kullanıyorsa hem SQLSRV hem de PDO_SQLSRV’yi kullanan mevcut bir uygulama duman testi çalıştırın. Bu kontrol sırasında bağlantı yapılandırmasını değiştirmeden tutun ki yükseltme testi ilgisiz bir bağlantı değişikliğini de test etmesin.

Bir sürücü yüklenmezse, PHP minör sürümü, mimarisi, iş parçacığı güvenlik modu, uzantı dizini ve ODBC kurulumunu yükseltmeden önce kaydedilen değerlerle karşılaştırın.

Hem API'leri hem de sürümleri doğrulayın

Bu programı verify-driver-upgrade.php olarak kaydedin:

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

$failed = false;
foreach ($results as $name => $result) {
    $version = $result['version'] === false ? 'unknown' : $result['version'];
    echo "$name: " . ($result['loaded'] ? 'loaded' : 'missing') . ", version $version" . PHP_EOL;
    $failed = $failed || !$result['loaded'] || $result['version'] === false;
}

exit($failed ? 1 : 0);

Programı CLI çalıştırılabilir dosya ile ve geçici olarak her bir web çalışma zamanı aracılığıyla çalıştırın. Bildirilen iki sürümün de yüklediğiniz sürümle eşleşip eşleşmediğini doğrulayın. Doğrulamadan sonra web kopyasını kaldırın.

Bu program PHP uzantı katmanını doğrular. Sonrasında ODBC yüklemesini, bağlantı seçeneklerini, kimlik doğrulamasını, veritabanına erişimi, geri dönen PHP tiplerini ve temizleme davranışını doğrulamak için değişmemiş uygulama duman testini çalıştırın.

Yükseltme öncesi ve sonrası veritabanı davranışını doğrulayın

Yükseltmeden önce ve sonra aynı program ve bağlantı ayarlarını kullanın. Testi değiştirmemek, sürücü değişikliklerini uygulama veya bağlantı yapılandırma değişikliklerinden ayırır.

Sorguları yanıtlayarak bir test hesabı için SQL_SERVER_NAME, SQL_DATABASE, SQL_UID ve SQL_PWD ortam değişkenlerini ayarlayın. Ham değerleri, kabuk tırnakları veya sürücü kodlaması olmadan girin. Kimlik bilgilerini komut satırına veya kayıtlı terminal oturumuna dahil etmeyin.

Windows PowerShell'de sunucu adını ve veritabanı adını girin, ardından test hesabı için kimlik bilgisi diyalogunu veya promptunu kullanın:

$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

Linux veya macOS'ta Bash kullanın. Herhangi bir değeri okumadan önce komut izlemeyi devre dışı bırakın. Parola istemi girdinizi göstermez:

set +x
IFS= read -r -p 'Server name (tcp:<server>,1433): ' SQL_SERVER_NAME
IFS= read -r -p 'Database name: ' SQL_DATABASE
IFS= read -r -p 'User name: ' SQL_UID
IFS= read -r -s -p 'Password: ' SQL_PWD
printf '\n'
export SQL_SERVER_NAME SQL_DATABASE SQL_UID SQL_PWD

Ortam, PHP'nin okuyabilmesi için düz metin parolayı içerir. Bu değişkenleri sadece test oturumunda kullanın, yazdırmayın ve test sonrası temizleyin.

Bu programı test-driver-upgrade.php olarak kaydedin. Çevre değerlerini değiştirmeden tutun. Program, kapanış süslü parantezlerini iki kez ekler ve dış süslü parantezler ekler, ardından veritabanı adı, kullanıcı adı ve şifreyi sürücüye iletir. Bu kodlama, literal süslü parantezleri korur ve noktalı virgüllerin bağlantı seçeneklerini ayırmasını engeller.

<?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);

Programı yükseltmeden önce çalıştırın ve başarıyla alınan çıktıyı kaydedin. Her PHP sürecini yeniden başlattıktan sonra değişmemiş dosyayı tekrar çalıştırın:

php test-driver-upgrade.php

Her iki çalıştırma da şunları üretmelidir:

SQLSRV query: 1
PDO_SQLSRV query: 1

Yükseltme sonrası çalışma başarısız olursa, tam SQLSTATE'i veya istisnayı koruyun. Sonra arızayı temel sistem, uzantı sürümleri, aktif yapılandırma, ODBC sürümü ve süreç yeniden başlatma durumu ile karşılaştırın. Dağıtım penceresinde uyumsuzluğu düzeltemediğinizde her iki PHP uzantısını birlikte geri alın.

Doğrulamadan sonra test dosyasını silin ve geçici ortam değişkenlerini temizleyin. PowerShell'de şunu çalıştırın:

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

Linux veya macOS'ta şunu çalıştırın:

rm verify-driver-upgrade.php test-driver-upgrade.php
unset SQL_SERVER_NAME SQL_DATABASE SQL_UID SQL_PWD

Başarısız bir yükseltmeyi geri almak

  1. Etkilenen web sunucularını, PHP-FPM havuzlarını ve uzun süre çalışan worker süreçlerini durdurun.

  2. PHP minör sürümünü değiştirdiyseniz, önceki PHP çalışma zamanını geri getirin ve her web sunucusu ile çalışanı tekrar o kuruluma yönlendirin.

  3. Her iki önceki sürücü dosyasını da geri getirin. Önceki SQLSRV ve PDO_SQLSRV yapılandırma girişlerini birlikte geri getirin.

  4. Önceki ODBC paketini ancak yeni sürüm hataya neden olduysa ve eski paket geri getirdiğiniz PHP sürücü sürümü tarafından desteklenmeye devam ediyorsa geri getirin.

  5. Süreçleri yeniden başlatın ve temel sürüm kontrollerini ve uygulama smoke testlerini tekrar çalıştırın.

  6. Başarısız yükseltme kayıtlarını ve tam PHP başlatma veya bağlantı hatasını sakla. Hatanın PHP yüklemesinden, işletim sistemi yükleyicisinden, ODBC'den veya veritabanı bağlantısından kaynaklanıp kaynaklanmadığını belirlemeye yardımcı olurlar.

Yükseltme sorunlarını giderme

Belirti Olası neden Düzeltici eylem
PIE başarılı ama ExtensionVer değişmez Eski sürümlü bir giriş hâlâ önceki dosyayı yükler Eski girişi değiştirin, tekrarları kaldırın ve tüm PHP işlemlerini yeniden başlatın
SQLSRV ve PDO_SQLSRV farklı sürümleri bildirir Yalnızca bir eklenti değiştirildi ya da bir SAPI'nin yapılandırması güncel değildi Her çalışma zamanında iki uzantıyı birlikte yükseltin ve yapılandırın
CLI hedef sürümü bildiriyor ama web sitesi bunu yapmıyor Web SAPI başka bir PHP kurulumu kullanıyor ya da yeniden başlatılmadı Yapılandırma ve uzantı dizinlerini karşılaştırın, sonra doğru işlemi yeniden başlatın
PHP başlangıç, bir mimari veya sembol hatası bildiriyor Uzantı PHP derlemesiyle eşleşmiyor Önceki dosyaları geri yükleyin, ardından doğru PHP minör sürümü, mimarisi ve iş parçacığı güvenliği modu için dosyaları yeniden oluşturun veya seçin
Uzantılar yüklenir ama ODBC değişikliğinden sonra bağlantılar başarısız olur ODBC yapılandırması, sertifika davranışı, kimlik doğrulama veya ağ erişimi değişti Bağlantı ayarlarını geri alma işlemi yapmadan veya değiştirmeden önce SQLSTATE ve yerel hataları yakalayın
Worker süreçleri başarısız olurken yeni web talepleri başarılıdır Uzun süredir çalışan işleyiciler hâlâ önceki eklentiyi veya yapılandırmayı elinde bulundururlar Her worker işlemini drain edip yeniden başlatın