Udostępnij za pośrednictwem


          

PHP i Windows - SQL Server Driver for PHP Udostępnij na: Facebook

Autor: Maciej Wilgucki

Opublikowano: 2011-07-12

Nieodłącznym towarzyszem PHP od zawsze był MySQL. Jest to relacyjna baza danych pozwalająca komfortowo rozwijać aplikacje bazodanowe. Wprawdzie MySQL jest dostępny na systemach operacyjnych z rodziny Windows, warto jednak poznać alternatywne rozwiązania. Rozwiązaniem takim jest SQL Server, dostępny także w darmowej wersji Express. Również darmowe jest narzędzie do zarządzania bazą danych – Microsoft SQL Server Management Studio Express.

Instalacja

Podobnie jak w przypadku PHP, SQL Server oraz wszystkie niezbędne dodatki możemy zainstalować za pomocą Web Platform Installera. Po uruchomieniu Web PI w górnym menu wybieramy Produkty, a z lewego podmenu Bazy danych (rys. 1). Następnie klikamy na przycisk Dodaj obok SQL Server Express 2008 R2, SQL Server 2008 R2 Management Studio Express oraz Sterownik programu Microsoft SQL w wersji 2.0 dla programu PHP w wersji 5.3 w usługach IIS. Ostatni produkt zależy od wersji PHP zainstalowanej na serwerze. Jeśli posiadacie PHP w wersji 5.2, należy wybrać wersję przeznaczoną dla tej wersji PHP.

Rys. 1. Instalacja wymaganego oprogramowania.

Po kliknięciu w przycisk Zainstaluj, postępujemy zgodnie ze wskazówkami instalatora. Na koniec pozostało nam pobrać przykładową bazę danych, z której będziemy korzystać. Idealnie do tego celu nadaje się baza danych AdventureWorks, którą pobierzemy pod adresem http://msftdbprodsamples.codeplex.com/. Instalacja bazy sprowadza się do uruchomienia pobranego pliku .exe i postępowaniu zgodnie ze wskazówkami instalatora.

Praca z bazą

Sterownik, który zainstalowaliśmy, pozwala nam pracować z SQL Server na dwa sposoby. Możemy korzystać ze standardowych funkcji rozpoczynających się przedrostkiem sqlsrv_ lub z PDO. Wybór sposobu zależy w głównej mierze od naszych przyzwyczajeń, ponieważ oba sposoby pozwalają dokładnie na to samo.

Łączenie się z serwerem

Pracę z bazą rozpoczynamy od połączenia się z serwerem bazy danych. W przypadku SQL Servera mamy dwie możliwości. Możemy połączyć się, korzystając z autentykacji systemu operacyjnego lub korzystając z autentykacji bazy danych. Zalecanym sposobem jest korzystanie z autentykacji systemu operacyjnego. Jako powody takiego wyboru wymieniane są między innymi: brak konieczności przekazywania loginu i hasła użytkownika przez sieć, brak osadzania w kodzie aplikacji danych dostępowych do bazy oraz uproszczenie procesu zarządzania użytkownikami.

Aby połączyć się z bazą korzystając z autentykacji systemu operacyjnego, wystarczy wskazać serwer, do jakiego się łączymy oraz nazwę bazy danych.

$serverName = '(local)\SQLEXPRESS';
$connectionInfo = array(
    'Database' => 'AdventureWorks'
);

$conn = sqlsrv_connect($serverName, $connectionInfo);

// PDO
$serverName = '(local)\SQLEXPRESS';
$conn = new PDO('sqlsrv:Server=' . $serverName . ';Database=AdventureWorks');

W przypadku autentykacji bazy danych musimy wskazać użytkownika oraz jego hasło.

// wykorzystanie funkcji
$serverName = '(local)\SQLEXPRESS';
$connectionInfo = array(
    'Database' => 'AdventureWorks',
    'UID' => 'jankowalski',
    'PWD' => 'haslo'
);

$conn = sqlsrv_connect($serverName, $connectionInfo);

// PDO
$serverName = '(local)\SQLEXPRESS';
$conn = new PDO('sqlsrv:Server=' . $serverName . ';Database=AdventureWorks', 'jankowalski', 'haslo');

Oprócz nazwy bazy danych, użytkownika oraz hasła, podczas łączenia się do bazy mamy możliwość określenia szeregu opcji konfiguracyjnych. Możemy określić na przykład, czy komunikacja z bazą jest szyfrowana lub wskazać zapasowy serwer bazodanowy. Pełna lista opcji znajduje się pod adresem https://msdn.microsoft.com/en-us/library/ff628167.aspx.

Pobieranie danych

Wiemy już, jak połączyć się z bazą danych, pora więc się dowiedzieć, w jaki sposób możemy pobrać z niej dane. Jest to tak samo proste, jak w przypadku bazy MySQL. Jeśli korzystamy z funkcji, wygląda to następująco:

$serverName = '(local)\SQLEXPRESS';
$connectionInfo = array(
    'Database' => 'AdventureWorks'
);

$conn = sqlsrv_connect($serverName, $connectionInfo);
$sql = "SELECT FirstName, LastName FROM Person.Contact WHERE LastName='Alan'";
$res = sqlsrv_query($conn, $sql);
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC)) {
    var_dump($row);
}

Warto zwrócić uwagę na funkcję sqlsrv_fetch_array, którą można wywołać bez drugiego parametru. W takim przypadku w zmiennej $row znajdzie się tablica zawierająca klucze numeryczne oraz tekstowe (odpowiadające nazwom kolumn). Jeśli chcemy w wyniku uzyskać tylko klucze tekstowe, musimy skorzystać ze stałej SQLSRV_FETCH_ASSOC. Dla kluczy tylko numerycznych powinniśmy użyć stałej SQLSRV_FETCH_NUMERIC.

Jeśli zamiast tablicy chcielibyśmy w wyniku uzyskać obiekt, powinniśmy zamienić funkcjęsqlsrv_fetch_array na sqlsrv_fetch_object. Funkcja ta przyjmuje tylko jeden argument i zwraca obiekt typu stdClass, gdzie nazwy właściwości odpowiadają nazwom kolumn w tabeli.

Korzystanie z PDO również nie odbiega od znanego z bazy MySQL sposobu. Mamy możliwość pobierania wszystkich wyników na raz lub iterowania przez kolejne wyniki w pętli.

Aby pobrać wszystkie wiersze od razu, skorzystamy z metody fetchAll:

$serverName = '(local)\SQLEXPRESS';
$conn = new PDO('sqlsrv:Server=' . $serverName . ';Database=AdventureWorks');

$sql = "SELECT FirstName, LastName FROM Person.Contact WHERE LastName='Alan'";
$stmt = $conn->query($sql);
$result = $stmt->fetchall(PDO::FETCH_BOTH);
var_dump($result);

Podobnie jak poprzednim razem, możemy również określić, w jakiej postaci zwrócone zostaną dane. Listę wszystkich dostępnych opcji znajdziemy w manualu PHP pod adresem http://www.php.net/manual/en/pdo.constants.php.

Iterowanie po kolejnych wynikach wygląda następująco:

$serverName = '(local)\SQLEXPRESS';
$conn = new PDO('sqlsrv:Server=' . $serverName . ';Database=AdventureWorks');

$sql = "SELECT FirstName, LastName FROM Person.Contact WHERE LastName='Alan'";
$stmt = $conn->query($sql);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    var_dump($row);
}

Tutaj również mamy możliwość skorzystania ze wspomnianych wcześniej opcji w celu ustawienia pożądanego typu zwracanych danych.

Zapisywanie danych

Podobnie jak w przypadku pobierania danych, zapisywanie ich (lub usuwanie) do bazy niczym nie różni się od przywoływanej wcześniej bazy MySQL.

$serverName = '(local)\SQLEXPRESS';
$connectionInfo = array(
    'Database' => 'AdventureWorks'
);
$conn = sqlsrv_connect($serverName, $connectionInfo);
$sql = "INSERT INTO Sales.SalesOrderDetail (
            SalesOrderID,
            OrderQty,
            ProductID,
            SpecialOfferID,
            UnitPrice,
            UnitPriceDiscount
        ) VALUES (
            75123, 5, 741, 1, 818.70, 0.00
        )";
$stmt = sqlsrv_query($conn, $sql);

Mamy również możliwość wykonywania tzw. prepared statements. Możemy to zrobić na dwa sposoby – przekazać dane do przygotowanego zapytania i od razu je wykonać lub przygotować zapytanie, a wykonanie odłożyć na później. W pierwszym przypadku zapytanie będzie miało następującą postać (pominąłem kod odpowiedzialny za łączenie się do bazy):

$sql = "INSERT INTO Sales.SalesOrderDetail (
            SalesOrderID,
            OrderQty,
            ProductID,
            SpecialOfferID,
            UnitPrice,
            UnitPriceDiscount
        ) VALUES (
            ?, ?, ?, ?, ?, ?
        )";
$params = array(75123, 5, 741, 1, 818.70, 0.00);
$stmt = sqlsrv_query($conn, $sql, $params);

Drugi sposób wygląda następująco:

$sql = "INSERT INTO Sales.SalesOrderDetail (
            SalesOrderID,
            OrderQty,
            ProductID,
            SpecialOfferID,
            UnitPrice,
            UnitPriceDiscount
        ) VALUES (
            ?, ?, ?, ?, ?, ?
        )";
$params = array(75123, 5, 741, 1, 818.70, 0.00);

// przygotowanie zapytania
$stmt = sqlsrv_prepare($conn, $sql, $params);

// wykonanie zapytania
sqlsrv_execute($stmt);

Te same operacje możemy wykonać przy użyciu PDO.

Bezpośrednie zapisanie danych do bazy:

$serverName = '(local)\SQLEXPRESS';
$conn = new PDO('sqlsrv:Server=' . $serverName . ';Database=AdventureWorks');
$sql = "INSERT INTO Sales.SalesOrderDetail (
            SalesOrderID,
            OrderQty,
            ProductID,
            SpecialOfferID,
            UnitPrice,
            UnitPriceDiscount
        ) VALUES (
            75123, 5, 741, 1, 818.70, 0.00
        )";
$conn->exec($sql);

Wykorzystanie prepared statements:

$serverName = '(local)\SQLEXPRESS';
$conn = new PDO('sqlsrv:Server=' . $serverName . ';Database=AdventureWorks');
$sql = "INSERT INTO Sales.SalesOrderDetail (
            SalesOrderID,
            OrderQty,
            ProductID,
            SpecialOfferID,
            UnitPrice,
            UnitPriceDiscount
        ) VALUES (
            ?, ?, ?, ?, ?, ?
        )";
$stmt = $conn->prepare($sql);
$params = array(75123, 5, 741, 1, 818.70, 0.00);
$stmt->execute($params);

Zapytania aktualizujące (update) oraz usuwające (delete) dane wykonuje się w analogiczny sposób.

Transakcje

SQL Server oferuje programistom możliwość korzystania z transakcji. Transakcja pozwala zgrupować zapytania w jeden blok, który zostanie wykonany, jeśli wszystkie zapytania zostaną poprawnie wykonane. W przypadku jakichkolwiek problemów z wykonaniem zapytań w transakcji, możemy wycofać zmiany wprowadzone w obrębie transakcji, dzięki czemu mamy pewność, iż nasze dane nie zostały niepoprawnie zapisane do bazy.

$serverName = '(local)\SQLEXPRESS';
$connectionInfo = array(
    'Database' => 'AdventureWorks'
);
$conn = sqlsrv_connect($serverName, $connectionInfo);

sqlsrv_begin_transaction($conn);

$wykonano_zapytania = true;

if(!sqlsrv_query($conn, 'zapytanie 1')) $wykonano_zapytania = false;
if(!sqlsrv_query($conn, 'zapytanie 2')) $wykonano_zapytania = false;
if(!sqlsrv_query($conn, 'zapytanie 3')) $wykonano_zapytania = false;

if($wykonano_zapytania) {
    sqlsrv_commit($conn);
}
else {
    sqlsrv_rollback($conn);
}

W wersji PDO transakcje wyglądają następująco:

$serverName = '(local)\SQLEXPRESS';
$conn = new PDO('sqlsrv:Server=' . $serverName . ';Database=AdventureWorks');
$conn->beginTransaction();
$wykonano_zapytania = true;
if(!$conn->exec("zapytanie 1")) $wykonano_zapytania = false;
if(!$conn->exec("zapytanie 2")) $wykonano_zapytania = false;
if(!$conn->exec("zapytanie 3")) $wykonano_zapytania = false;
if($zapytania_wykonano_poprawnie) {
    $conn->commit();
}
else {
    $conn->rollback();
}

Podsumowanie

Zapoznaliśmy się dzisiaj ze sterownikiem SQL Server dla PHP. Powyższy artykuł nie wyczerpuje całego tematu SQL Server Driver dla PHP, a jedynie stanowi do niego solidne wprowadzenie. Obowiązkową lekturą dla wszystkich zainteresowanych korzystaniem z bazy danych SQL Server jest przewodnik znajdujący się po adresem https://msdn.microsoft.com/en-us/library/ff928321%28v=SQL.10%29.aspx.