Stuart Herbert in his blog more than a year ago pointed some key Microsoft Sql extension for PHP pros:
What’s Wrong With The Existing MSSQL Extension For PHP?
… or, why do we need an improved SQL Server extension for PHP? :)
The existing MSSQL extension works well, but has a few practical limitations that have to be worked around.
- Limited to varchar(255) support
- No support for unicode columns like nvarchar
- No PDO drivers
- Poor error reporting
Now some of these issues are fixed, however Microsoft native Sql driver is still not used. As I’ve mentioned before, there are to ways to use native driver in PHP now:
- As PHP extension
- Through ODBC
However, none of these is available in Zend Framwork. So my task now (because of Winphp competition) is to come up with something what can be used to connect to Microsft Sql database with the new driver. To start with, lets look how standard DB config looks like:
;application/config/application.ini, ZF 1.8 resources.db.adapter = PDO_MYSQL resources.db.params.host = localhost resources.db.params.username = usr resources.db.params.password = psw resources.db.params.dbname = zf-tutorial
My goal is to change it as minimal as possible to allow easy db’s migration. To test ODBC connector I downloaded this class and renamed it to Add_Db_Adapter_Pdo_Odbc (because it’s not a good idea to change something in actual Zend Framework library). To use it in your code you need to change config file to something like this:
resources.db.adapter = PDO_ODBC resources.db.params.adapterNamespace = App_Db_Adapter resources.db.params.username = usr resources.db.params.password = psw resources.db.params.dbname = "Driver={SQL Native Client}; Server=localhost\SQLEXPRESS;Database=zf-tutorial;"
Note dbname string – now it has not only database name, but also driver information and host. I guess such format is chosen because dns’ for ODBC are very different for different providers, so to make things easier you just supply whole string, not it’s parts (driver, server/file, etc.). Don’t forget to use correct server host – for some strange reasons 127.0.0.1 refused to work for me.
Problem with ODBC is that it’s too general: ODBC supports a lot databases, hence they each can have something different (correct me if I’m wrong). That’s why I’m thinking about refactoring this class to App_Db_Adapter_Pdo_Odbc_Abstract abstract class and separate classes for different drivers. Although this class works fine for MSSQL, so can be used as is.
To test PHP extension there are no classes at all (at least I haven’t found, only in Adodb). So I decided to implement one myself – with a help of SqlSrv API Reference and Zend_Db_Adapter_Abstract abstract class I quite quickly came up with a working solution App_Db_Adapter_Mssql. Connection configuration looks the same:
resources.db.adapter = MSSQL resources.db.params.adapterNamespace = App_Db_Adapter resources.db.params.host = localhost\SQLEXPRESS resources.db.params.username = usr resources.db.params.password = psw resources.db.params.dbname = zf-tutorial
I’ve tested both classes with the same application from previous post and benchmark results surprised me. They were equal! With a small variations page generation times were about 140 ms (all default settings, IIS7, MSSQL Express). Why? SQL server driver for PHP is open source, so if you look at it’s source you would find (C++):
SQLRETURN build_connection_string_and_set_conn_attr( sqlsrv_conn const* conn, const char* server, zval const* options, __inout std::string& connection_string TSRMLS_DC ) { ... connection_string = "Driver={SQL Native Client};Server="; connection_string += server; connection_string += ";"; ... for( zend_hash_internal_pointer_reset( oht ); zend_hash_has_more_elements( oht ) == SUCCESS; zend_hash_move_forward( oht )) { ... if( NO_ATTRIBUTE == ret.attr ) { if( ret.add ) { connection_string += key; connection_string += "={"; connection_string += ret.str_value; connection_string += "};"; } } ... } ... return SQL_SUCCESS; }
If you are familiar with C++ you can look at full source at codeplex.com. What this function does is it creates ODBC connection string, so basically it’s the same thing as using PDO_ODBC (no?). Both are implemented as extensions (not as PHP code) so there are no performance differences, test proves that.
After today’s analysis I can’t say which driver is better to use: ODBC or native driver. However, since Pdo driver is already being used in Zend Framework it’s easier and faster to use ODBC. Also, ODBC doesn’t require Sql PHP extension to be installed, so as long as you have Sql server and native client it will work without php.ini modifications.
In conclusion, if you want to use SQL Native driver with Zend Framework solutions are almost here. I can promise, that something stable and proven to be working by actual application will be released before middle of June. I would love to hear comments from Microsoft people or ODBC users – I’m confused a little bit, because I didn’t have a lot of experience with Microsoft’s Sql and ODBC (you can share find me in twitter also @juokaz).







