FreeTDS: Pracujte s MS SQL serverem z PHP

Nejběžnější kombinací pro běh webových serverů je dnes pravděpodobně LAMP (Linux, Apache, MySQL a PHP). PHP ale není omezeno jen na MySQL, může se připojit k různým databázím, např. i k MS SQL serveru. V článku si ukážeme prakticky, jak se z PHP lze připojit k MS SQL serveru.
Nálepky:
Apache, PHP a MySQL je asi nejpoužívanější kombinace pro běžné www prezentace a aplikace. Většinou bývá hostována na Linux nebo Unix systémech. Chtěl bych ukázat způsob, jak se na stejném hostingovém serveru připojit k MS SQL serveru. Pro někoho možná věc běžná, ale při prvních pokusech o rozběhání vás může potrápit. A proto jsem se rozhodl napsat krátký článek s praktickými ukázkami.
Nejprve se podíváme na prostředí, konfigurace hosting serveru:
- FreeBSD 7.1
- apache-2.0.63
- php 5.2.9 (zkompilované s podporou mssql)
- freetds-0.82.1
Proč FreeTDS knihovna? A co to vlastně je?
FreeTDS jsou knihovny pro Linux/Unix, které umožní programům komunikovat s Microsoft SQL serverem a Sybase databázemi. PHP modul php5-mssql také používá balík freetds-msdblib. Tato knihovna je řešení, které se mi nejlépe osvědčilo, mnoho lidí jej používá a třeba i v diskuzích na php.net se o něm dočtete. Používejte vždy aktuální verze, starší mohou způsobovat problémy. To jsem si osobně vyzkoušel. Momentálně používám verzi 0.82 od doby, kdy se jako devel objevila, a funguje bez nejmenších problémů.
Co budeme potřebovat?
Připojovat se budeme na Microsoft SQL server verze 2000 a 2005, řešení se neliší. Patrně by neměl být problém připojit se i na MS SQL 2005 express edition.
Takže nejprve instalace, předpokládáme nainstalované PHP5 a Apache. Pokud nemáte v php podporu mssql, musíte ji doinstalovat, v BSD nejlépe z „čerstvých“ portů:
$ cd /usr/ports/lang/php5-extension $ make config (zaškrtnout mssql) $ make install clean
A restart apache: /usr/local/etc/rc.d/apache restart
I s tímto už budete schopni se minimálně k SQL serveru 2000 připojit. U proměnné mssql_host
se zadává IP adresa a port, na ten nezapomeňte. Malá ukázka:
$mssql_user = "sa"; $mssql_pass = "heslo"; $mssql_db = "Helios013"; $mssql_host = "192.168.222.25:1433"; $spojeni = mssql_pconnect ($mssql_host,$mssql_user,$mssql_pass); if($spojeni) { if (mssql_select_db($mssql_db,$spojeni)) return($spojeni); else die ("Nejde zmenit databazi na $mssql_db"); } else die("Nelze se pripojit k MS SQL serveru");
Ještě je tu jedno možné úskalí – správná konfigurace na straně SQL serveru. Zkontrolujte si v SQL Server Configuration manageru
konfiguraci TCP/IP. U některých verzí je ve výchozím stavu vypnuté.
FreeTDS
Mluvil jsem o FreeTDS knihovně, teď to zkusíme s ní. Dle mých zkušeností je na práci, debugování, složitější operace lepší. Takže instalace:
$ cd /usr/ports/database/freetds-devel $ make install clean (v menu nezaškrtávejte nic)
Je nutné ještě upravit konfigurační soubor /usr/local/etc/freetds.conf
. Soubor má sekci global, kde nastavíme výchozí hodnoty a nějaké obecné vlastnosti. Dále si můžeme nadefinovat vlastní servery s rozdílnými parametry. Já mám v sekci global:
[global] # TDS protocol version tds version = 8.0 client charset = UTF-8 initial block size = 512 text size = 64512
Svůj SQL server 2005 mám zadaný takto:
[pokus] host = 192.168.222.25 port = 1433
Po nakonfigurování nezapomeňte na restart Apache.
Pro servery 2000 a 2005 používám tds verzi 8.0 a kódování UTF-8. Pokud chcete použít FreeTDS, kód zůstane téměř stejný. Pouze změňte proměnou $mssql_host
na $mssql_host = "pokus";
„Pokus“ je název serveru definovaný ve freetds.conf.
Připojení k databázi
Teď si vyzkoušíme první spojení:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta http-equiv="content-language" content="cs" /> </head> <body> <?php $mssql_user = "sa"; $mssql_pass = "heslo"; $mssql_db = "Helios013"; $mssql_host = "pokus"; $spojeni = mssql_pconnect ($mssql_host,$mssql_user,$mssql_pass); if($spojeni) { if (mssql_select_db($mssql_db,$spojeni)) return($spojeni); else die ("Nejde zmenit databazi na $mssql_db"); } else die("Nelze se pripojit k MS SQL serveru"); $result = mssql_query("SELECT top 20 ID,Nazev,Misto FROM tabcisorg "); if ( mssql_num_rows ($result) > 0) { while ($record = mssql_fetch_assoc($result)) { echo "<br/>$record[Nazev] - $record[Misto]"; } } ?> </body> </html>
Pozor na velikost písmen v názvech proměnných, knihovna rozlišuje velikost znaků.
Když dojde k chybám, je možno použít debug, stačí do freetds.conf přidat:
dump file = /tmp/freetds.log dump file append = yes
A po restartu Apache už bude vše velmi detailně logováno.
Serverové procedury
Pokud předchozí příklad funguje, můžeme přistoupit k serverovým procedurám. Ty samy o sobě až tak jednoduché nejsou, ale pokud víme co chceme spustit, co je vstup a co výstup, následující kód nebude problém. Procedura na serveru vypadá a funguje následovně:
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON GO ALTER procedure [dbo].[_kx_navratova_hodnota] @vst_hodn_1 int = 0 as begin set nocount on; -- Tato procedura nedela nic jineho nez ze vraci text 'xxx vstupni_hodnotu' ; -- a jako navratovou hodnotu vstupni hodnotu zvysenou o 100 select 'xxx ' + str(@vst_hodn_1) vystup_selectem return @vst_hodn_1 + 100; end
PHP kód:
<?php ... ... //inicializace procedury $stmt = mssql_init('_kx_navratova_hodnota', $spojeni); // deklarace promenných, do výstupni hodnoty dávám libovolné číslo, // ověříme tím správné předání návratové hodnoty $vst_hodn_1 = 30; $vystup = -55; // přidáme vstupní a výstupní parametry, jejich jméno, typ, zda je // vstupní nebo výstupní, jestli může být null a případně délku mssql_bind ($stmt, "@vst_hodn_1",$vst_hodn_1,SQLINT1); mssql_bind ($stmt, "RETVAL", $vystup, SQLVARCHAR, true, false, 50); // spustíme proceduru $result = mssql_execute ($stmt); // načteme si výstupní řádek do proměnné $row = mssql_fetch_assoc($result); // vypíšeme si výstup z procedury print_r($row); // next result je dulezity, navratova hodnota je až ve druhém result setu // v prvním byl pouze výstup procedury mssql_next_result($result); echo "<br/>Navratova hodnota: $vystup"; // uvolníme paměť mssql_free_statement ($stmt); ?>
Tolik tedy stručný úvod do problematiky spolupráce databáze MS SQL a PHP. Pro někoho možná běžně používaná věc, ale když jsem s touto problematikou začínal, našel jsem několik dost nefunkčních nebo neúplných příkladů.
Pokud plánujete nasazení PHP v kombinaci s MS-SQL databází, a webový server Vám běží nad Windowsí platformou, doporučil bych poohlédnout se rovněž po alternativní knihovně, kterou vyrábí sám Microsoft.
Microsoft SQL Server Driver for PHP
je knihovna vyvíjená přímo Microsoftem, umožňující připojení do MS-SQL serveru. Sama interně využívá Microsoft Native Client knihovnu, takže v Linuxu na ni můžete bohužel zapomenout.
V aktuální verzi přidali podporu pro UTF-8, takže odpadají problémy s překódováním dat, jako u původní MS-SQL knihovny. Stejně tak je oproti původní knihovně odstraněn problém s limitem přečtených znaků z varcharu na 4096. (Porovnání s původním MS-SQL rozšířením, ne FreeTDS!) Knihovna podporuje PHP 5.3 a rozhodně stojí za zvážení.