Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Użyj tego przewodnika, aby nawiązać połączenie, zweryfikować wartości otrzymane przez PHP i zwolnić połączenie po zakończeniu pracy. Programy wykorzystują uwierzytelnianie SQL Server dla lokalnej lub zdalnej bazy testowej SQL Server. Dla połączeń Azure i Fabric bez hasła użyj Connect to Azure SQL and Fabric SQL.
SQLSRV akceptuje nazwę serwera oraz tablicę asocjacyjną opcji połączenia. PDO_SQLSRV implementuje PHP Data Objects (PDO) i akceptuje ciąg nazwy źródła danych (DSN), oddzielne argumenty poświadczenia oraz tablicę atrybutów PDO. Oba korzystają z sterownika Microsoft ODBC dla SQL Server. Połączenie działające z jednym API nie sprawia, że nazwy opcji lub typy PHP w drugim API są wymienne.
Zanim się połączysz
- Zainstaluj obsługiwany runtime PHP i sterownik Microsoft ODBC, a następnie załaduj rozszerzenie PHP, którego zamierzasz używać.
- Sprawdź proces PHP, który obsługuje Twoją aplikację. Uruchom,
php --iniaby znaleźć konfigurację wiersza poleceń iphp -mwyświetlić jej załadowane rozszerzenia. SQLSRV wymagasqlsrv. PDO_SQLSRV wymagaPDOipdo_sqlsrv. Serwer WWW może używać innegophp.ini, runtime i konta niż twój terminal. - Uzyskaj adres serwera, nazwę bazy danych oraz tożsamość z uprawnieniami do połączenia. Logowanie do bazy danych nie przyznaje automatycznie uprawnień do wszystkich tabel.
- Konfiguruj dostęp do sieci i certyfikat zaufanego serwera. Programy te żądają szyfrowania i walidacji certyfikatów wprost. Połącz się za pomocą nazwy hosta widniejącej w certyfikacie, zamiast podmieniać adres IP, którego certyfikat nie obejmuje.
Ustaw te zmienne w środowisku procesu PHP, używając powłoki, narzędzia deweloperskiego lub konfiguracji hostingu. Nie zatwierdzaj pliku haseł ani nie wypisuj zmiennych środowiskowych.
| Variable | Value |
|---|---|
SQL_SERVER |
Nazwa hosta serwera, opcjonalnie poprzedzona przez tcp: i zakończona przez ,<port>. |
SQL_DATABASE |
Istniejąca baza danych, do której dostęp ma Twoje konto. |
SQL_USER |
Login SQL Server. |
SQL_PASSWORD |
Hasło tego logowania jest podawane przez chronioną konfigurację. |
Odczytuj ustawienia serwera i bazy danych z zaufanej konfiguracji aplikacji, a nie parametrów zapytania webowego. Przykład PDO umieszcza te ustawienia w DSN. Zachowaj jego słowa kluczowe połączenia pod kontrolą aplikacji.
Zapisz faktyczną nazwę bazy danych, nazwę użytkownika i hasło w zmiennych środowiskowych, bez dodawania ani podwajania nawiasów klamrowych. Oba rozszerzenia PHP wymagają escapingu w stylu ODBC nawet dla opcji tablicy SQLSRV i argumentów konstruktora PDO: podwój każdą zamykającą klamrę i umieść wartość w nawiasach klamrowych. Każdy program robi to jeden raz przed przekazaniem tych wartości sterownikowi. Zewnętrzne nawiasy zachowują dosłowne nawiasy na początku i końcu wartości oraz zapobiegają oddzielaniu ustawień PDO DSN przez średniki w nazwie bazy danych. To eskapowanie jest oddzielne od wiązania parametrów Transact-SQL (T-SQL).
Otwieraj, zapytuj i zamykaj za pomocą SQLSRV
Zapisz ten program jako connect-sqlsrv.php, i uruchom php connect-sqlsrv.php. Wykonuje zapytanie T-SQL bez tworzenia tabel czy zmiany danych.
CharacterSet wybiera UTF-8 dla danych znaków; nie zmienia typów kolumn ani sortacji bazy danych.
<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Set $name before running this example.");
}
$config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$conn = sqlsrv_connect($config['SQL_SERVER'], [
'Database' => $config['SQL_DATABASE'],
'UID' => $config['SQL_USER'],
'PWD' => $config['SQL_PASSWORD'],
'Encrypt' => true,
'TrustServerCertificate' => false,
'LoginTimeout' => 30,
'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$stmt = null;
try {
$sql = "SELECT CAST(42 AS int) AS Value, N'caf' + NCHAR(233) AS Label, "
. "CAST(NULL AS int) AS Missing";
$stmt = sqlsrv_query($conn, $sql, [], ['QueryTimeout' => 30]);
if ($stmt === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if ($row === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
if ($row !== ['Value' => 42, 'Label' => "caf\u{00e9}", 'Missing' => null]) {
throw new RuntimeException('Unexpected SQLSRV values or PHP types.');
}
echo json_encode($row, JSON_THROW_ON_ERROR), PHP_EOL;
} finally {
if (is_resource($stmt)) {
sqlsrv_free_stmt($stmt);
}
sqlsrv_close($conn);
}
Oczekiwane dane wyjściowe:
{"Value":42,"Label":"caf\u00e9","Missing":null}
Połączenie i instrukcja to zasoby PHP, które przekażesz funkcjom sqlsrv_* . Sprawdź, czy jest false przed użyciem któregokolwiek z uchwytów. Pobierz sqlsrv_errors() natychmiast po awarii, ponieważ późniejsze wywołanie SQLSRV może zastąpić kolekcję błędów.
SQLSRV_FETCH_ASSOC zwraca tablicę asocjatywną z nazwami kolumn jako kluczami.
SQLSRV_FETCH_NUMERIC zwraca klucze numeryczne oparte na zerze; domyślnie SQLSRV_FETCH_BOTH obejmują obie formy. Dla sqlsrv_fetch_array(), null oznacza brak wierszy i false oznacza błąd. SQL NULL w wierszu to PHP null; to nie znaczy, że wiersz jest brakujący. Używaj === przy rozróżnianiu tych wartości.
Otwórz, zapytaj i zamknij PDO_SQLSRV
Zapisz ten osobny program jako connect-pdo.php, i uruchom php connect-pdo.php w tym samym środowisku.
sqlsrv: wybiera PDO_SQLSRV, a nie ogólny sterownik PDO_ODBC PHP.
<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Set $name before running this example.");
}
$config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$server = $config['SQL_SERVER'];
$database = $config['SQL_DATABASE'];
$pdo = new PDO(
"sqlsrv:Server=$server;Database=$database;Encrypt=true;"
. "TrustServerCertificate=false;LoginTimeout=30",
$config['SQL_USER'],
$config['SQL_PASSWORD'],
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
]
);
$stmt = null;
try {
$sql = "SELECT CAST(42 AS int) AS Value, N'caf' + NCHAR(233) AS Label, "
. "CAST(NULL AS int) AS Missing";
$stmt = $pdo->prepare($sql, [PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 30]);
$stmt->execute();
$row = $stmt->fetch();
if ($row !== ['Value' => '42', 'Label' => "caf\u{00e9}", 'Missing' => null]) {
throw new RuntimeException('Unexpected PDO_SQLSRV values or PHP types.');
}
echo json_encode($row, JSON_THROW_ON_ERROR), PHP_EOL;
} finally {
$stmt = null;
$pdo = null;
}
Oczekiwane dane wyjściowe:
{"Value":"42","Label":"caf\u00e9","Missing":null}
PDO_SQLSRV domyślnie zwraca tę kolumnę int jako ciąg PHP. Aby zażądać typów numerycznych PHP dla obsługiwanych kolumn liczbowych, ustaw PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE na true. Nie używaj bez zastanowienia rzutowania PHP dla wartości decimal; konwersja zmiennoprzecinkowa może spowodować utratę precyzji.
Atrybuty PDO to ustawienia dotyczące obiektu połączenia lub obiektu instrukcji. Użycie PDO::ATTR_ERRMODE z PDO::ERRMODE_EXCEPTION powoduje, że niepowodzenia operacji bazy danych skutkują zgłoszeniem wyjątku PDOException. Konstrukcja połączenia zgłasza wyjątek w przypadku niepowodzenia niezależnie od tego ustawienia.
PDO::FETCH_ASSOC daje klucze nazwane, PDO::FETCH_NUM daje klucze liczbowe oparte na zerze oraz PDO::FETCH_BOTH daje oba te elementy.
fetch() zwraca false na końcu wyniku; wartości SQL NULL w wierszu pozostają wartościami PHP null.
Te programy wiersza poleceń powodują zatrzymanie wykonywania w przypadku niepowodzeń. W aplikacji webowej wychwytuj wyjątki w kodzie, który obsługuje żądanie. Zapisz szczegóły diagnostyczne w chronionych logach i zwróć ogólną odpowiedź na błąd. Nie wysyłaj sqlsrv_errors(), śladów wyjątków, łańcuchów połączeń ani tokenów do przeglądarki.
Wybieranie trybu uwierzytelniania
| Mode | Użyj dla | Zobacz |
|---|---|---|
| Uwierzytelnianie programu SQL Server | On-premises SQL Server, kontenery i Azure SQL, gdy Microsoft Entra ID nie jest dostępny | Połącz się za pomocą uwierzytelniania SQL Server |
| Uwierzytelnianie zintegrowane (bez nazwy użytkownika ani hasła w ustawieniach połączenia) | Tożsamości Windows lub klienci Linux/macOS skonfigurowani dla Kerberos | Połącz się za pomocą Windows authentication |
Microsoft Entra ID (słowo kluczowe Authentication lub AccessToken) |
Obiekty docelowe Azure SQL i Fabric SQL skonfigurowane dla Microsoft Entra ID | Połączenie przy użyciu uwierzytelniania Microsoft Entra |
Do uwierzytelniania SQL SQLSRV przyjmuje UID i PWD w swojej tablicy opcji połączenia. PDO_SQLSRV przyjmuje nazwę użytkownika i hasło jako drugi i trzeci argument do new PDO(), a nie jako słowa kluczowe DSN. W przypadku tokena dostępu SQLSRV przyjmuje AccessToken w tablicy opcji, a PDO_SQLSRV przyjmuje go w DSN.
Jeśli pominiesz nazwę użytkownika, hasło, Authentication, i AccessToken, oba sterowniki żądają uwierzytelniania zintegrowanego od ODBC za pomocą Trusted_Connection=Yes. W systemach Linux i macOS takie żądanie wymaga ważnego biletu Kerberos oraz konfiguracji uwierzytelniania zintegrowanego ODBC. Nie daje dowolnemu lokalnemu kontu dostępu do zdalnego serwera.
Skonfiguruj połączenie i jego instrukcje SQL
Ustawienia połączenia dotyczą sesji, którą otwierasz. Ustawienia instrukcji SQL dotyczą konkretnego zapytania. Ustaw limity czasu i typy wyników wyraźnie wtedy, gdy aplikacja potrzebuje innych wartości niż domyślne.
| Purpose | SQLSRV | PDO_SQLSRV | Właściciel Behavior |
|---|---|---|---|
| Endpoint i baza danych | Argument serwera i opcja Database. |
Server oraz Database słowa kluczowe DSN. |
ODBC i cel SQL. |
| Poświadczenia SQL |
UID i PWD opcje. |
Argumenty nazwy użytkownika i hasła konstruktora. | Obsługa poświadczeń rozszerzeń i uwierzytelnianie serwera. |
| Uwierzytelnianie usługi Microsoft Entra |
Authentication opcja albo osobna AccessToken opcja. |
Authentication lub AccessToken słowo kluczowe DSN, z pominiętymi poświadczeniami dla zewnętrznego tokena. |
uwierzytelnianie ODBC; aplikacja pozyskuje zewnętrzne tokeny. |
| Encryption |
Encrypt => true. |
Encrypt=true w DSN. |
Bezpieczeństwo transportu ODBC. |
| Walidacja certyfikatu |
TrustServerCertificate => false. |
TrustServerCertificate=false w DSN. |
ODBC oraz konfiguracja zaufanych certyfikatów systemu operacyjnego. |
| Limit czasu na nawiązanie połączenia |
LoginTimeout Opcja połączenia, w sekundach. |
LoginTimeout Słowo kluczowe DSN, w sekundach. |
ODBC. To nie jest limit czasu wykonania instrukcji. |
| Przekroczenie limitu czasu zapytania |
QueryTimeout opcja instrukcji, w sekundach. |
PDO::SQLSRV_ATTR_QUERY_TIMEOUT, na połączeniu lub instrukcji. |
Obsługa rozszerzeń i instrukcji ODBC. |
| Kodowanie znaków |
CharacterSet => 'UTF-8' Opcja połączenia. |
PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8. |
Konwersja rozszerzenia PHP. PDO_SQLSRV domyślnie przyjmuje UTF-8; SQLSRV domyślnie stosuje kodowanie systemowe. |
| Obiekty daty i czasu |
ReturnDatesAsStrings jest domyślnie false , więc kolumny daty i czasu zwracają DateTime obiekty. |
Domyślnie ciągi znaków; używają PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE do żądania obiektów. |
Konwersja typów w rozszerzeniu PHP. |
| Wiele aktywnych zestawów wyników (MARS) |
MultipleActiveResultSets Opcja połączenia. |
MultipleActiveResultSets Słowo kluczowe DSN. |
ODBC i wsparcie docelowe. Oba rozszerzenia domyślnie ją włączają; wyłączają ją dla Warehouse w Fabric. |
| Odzyskiwanie na biegu jałowym |
ConnectRetryCount oraz ConnectRetryInterval opcje połączenia. |
Te same słowa kluczowe DSN. | ODBC. Nie próbują ponownie dowolnych operacji aplikacji. |
Pełną listę słów kluczowych, dozwolonych wartości i domyślnych wartości można znaleźć w sekcji Opcje połączenia. Nie umieszczaj CharacterSet, QueryTimeout, ani PDO:: stałych nazw w DSN PDO.
Zarządzaj czasem życia połączenia
Otwórz połączenie, gdy żądanie lub zadanie wymaga operacji na bazie danych. Używaj go ponownie przez cały ten proces lub zadanie, a potem zwolnij po ukończeniu. Nie łącz i nie rozłączaj się w każdym rzędzie. W przypadku długoletniego pracownika wydawaj oświadczenia i dokończaj każdą transakcję przed przyjęciem kolejnego zlecenia.
SQLSRV zamyka powiązane instrukcje po zamknięciu połączenia. Jawne wcześniejsze zwalnianie instrukcji zwalnia zasoby bez przerywania połączenia. Dla PDO przypisanie $pdo = null usuwa jedynie odniesienie do tej zmiennej.
PDOStatement lub inna zmienna może nadal zachować połączenie. Udostępnij też te odniesienia.
closeCursor() Udostępnia oczekujące wyniki, aby oświadczenie mogło być ponownie użyte; nie jest to metoda zamykania połączenia.
Oba API uruchamiają się w trybie automatycznego zatwierdzania: pomyślne polecenie jest zatwierdzane bez osobnego zatwierdzania aplikacji, chyba że rozpoczniesz transakcję. Dla grupy zapisów, które muszą zakończyć się sukcesem lub niepowodzeniem razem, użyj sqlsrv_begin_transaction() lub $pdo->beginTransaction(), a następnie commituj lub cofnij to wyraźnie. Zamknięcie połączenia z oczekującą transakcją powoduje próbę wycofania transakcji, a nie jej zatwierdzenia. Nie polegaj na czyszczeniu przy zamykaniu przy wdrażaniu polityki transakcji. Pełne przykłady można znaleźć w artykule Wykonaj transakcje.
Zwolnienie uchwytu połączenia PHP niekoniecznie zamyka fizyczne połączenie sieciowe. Pooling ODBC może zachować go do ponownego użycia. Pooling nie jest powodem, by przechowywać zasoby PHP na czas nieokreślony, a PDO_SQLSRV nie obsługuje PDO::ATTR_PERSISTENT => true. Aby poznać konfigurację puli połączeń specyficzną dla platformy, zobacz Pula połączeń.
Zastosuj wskazówki do docelowej bazy SQL
Wzorce handle, fetch i cleanup dotyczą obu rozszerzeń na wspieranych celach SQL. Punkty końcowe połączenia, uwierzytelnianie, dostęp do sieci i możliwości SQL są różne.
| Target | Adaptacja |
|---|---|
| SQL Server | Programy korzystają z loginu SQL. Zintegrowana autyzacja to kolejna opcja, gdy konfigurujesz tożsamość procesu PHP. |
| Azure SQL Database | Użyj nazwy hosta serwera logicznego i bazy danych o jawie. Preferuj uwierzytelnianie Microsoft Entra zamiast poświadczeń SQL w tych programach. |
| Azure SQL Managed Instance | Użyj punktu końcowego instancji i jego wymagań dotyczących dostępu do sieci. Nie zakładaj, że prywatny punkt końcowy jest dostępny z twojej stacji roboczej. |
| Azure Synapse Analytics | Użyj punktu końcowego puli SQL i sprawdź jego wsparcie dla T-SQL przed adaptacją zapytań tworzących lub modyfikujących obiekty. |
| Baza danych SQL w usłudze Microsoft Fabric | Wykorzystaj szczegóły połączenia z bazą danych oraz uwierzytelnianie Microsoft Entra. Nie zastępuj punktu końcowego analizy SQL. |
| Magazyn w usłudze Microsoft Fabric | Korzystaj z jego punktu końcowego magazynu i bazy danych, uwierzytelniania Microsoft Entra oraz MultipleActiveResultSets=false. |
Dla konfiguracji specyficznej dla usługi, zobacz połączenia Azure i Fabric.
Rozwiązywanie problemów z połączeniem
Zacznij od kroku, który się nie powiódł. Pomyślna weryfikacja protokołu sterowania transmisją (TCP) nie dowodzi, że uwierzytelnienie lub walidacja certyfikatów zakończyła się sukcesem.
| Objaw | Sprawdzanie |
|---|---|
Call to undefined function sqlsrv_connect() |
Wykonujący się proces PHP nie załadował się sqlsrv. Sprawdź jego php.ini i ostrzeżenia podczas uruchamiania. |
Raporty PDO could not find driver |
Potwierdź, że pdo_sqlsrv jest załadowane w tym procesie i sqlsrv pojawia się w PDO::getAvailableDrivers(). |
| Nie można znaleźć sterownika ODBC | Zainstaluj sterownik Microsoft ODBC i sprawdź jego rejestrację oraz architekturę. Zainstalowanie rozszerzenia PHP nie instaluje ODBC. |
| Upłynął limit czasu połączenia lub nie znaleziono serwera | Sprawdź nazwę serwera, port, rozwiązywanie nazw, routing, reguły zapory oraz czy SQL Server nasłuchuje na TCP. |
| Weryfikacja łańcucha certyfikatów lub nazwy hosta kończy się niepowodzeniem | Zainstaluj właściwy łańcuch zaufania i użyj nazwy hosta certyfikatu. Nie traktuj TrustServerCertificate=true jako naprawy produkcyjnej. |
| Logowanie się nie powiodło lub baza danych nie może zostać otwarta | Sprawdź tryb uwierzytelniania, nazwę bazy danych, logowanie/mapowanie użytkownika oraz uprawnienia. Pomijanie poświadczeń wymaga zintegrowanego uwierzytelniania; nie wybiera uwierzytelniania SQL. |
| Terminal działa, ale żądania internetowe nie powiodły się | Porównaj runtime PHP, załadowane rozszerzenia, tożsamość procesu, zmienne środowiskowe oraz dostęp do sieci. Nie udostępniaj publicznej phpinfo() strony zawierającej szczegóły konfiguracji. |
| Późniejsza operacja kończy się niepowodzeniem na zamkniętym uchwycie | Utrzymuj połączenie podczas całej pracy z instrukcjami. Utwórz nowe połączenie po zamknięciu jednogo; stary uchwyt sam się nie otwiera. |
Inne artykuły o połączeniach
- Połącz się na określonym porcie
- Opcje połączenia
- Buforowanie połączeń
- Wyłącz wiele aktywnych zestawów wyników (MARS)
- Obsługa bazy danych LocalDB
- Wsparcie dla wysokiej dostępności i odzyskiwania po awarii
- Nawiązywanie połączenia z usługą Microsoft Azure SQL Database
- Odporność na połączenie bezczynne