Microsoft Sql serverStuart 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:

  1. As PHP extension
  2. 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

ODBCMy 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).

Trackbacks/Pingbacks

  1. Juozas Kaziukenas’ Blog: SQL Native Client as MSSQL driver for Zend Framework | Cole Design Studios

Comments (4)

  1. Steve Cooney

    Good effort with the Zend Adapter. There is I discovered in actual fact today a mssqlnative driver for ADODB which utilises the SQL Server Driver for PHP. http://sourceforge.net/project/showfiles.php?group_id=42718

  2. Juozas (author)

    Hi Steve,

    yes, I know about adodb version (in this post: “To test PHP extension there are no classes at all (at least I haven’t found, only in Adodb)”). I have used some ideas from it and now my implementation is getting more and more stable.

    You can find it at http://zfmssql.codeplex.com/.

  3. Declan Butler

    Great work with the Sqlsrv adapter, I’m currently using it in a project I am working on. I’m connecting via Windows authentication and came across a possible issue
    You can read on my blog
    here

  4. Battulga

    Declan your site doesn’t work.
    I am using sql-server 2008 and zend server 5 CE.
    zend server extension does not support to enable and disable in the web admin.

    i just add one line in the php.ini.
    /php_sqlsrv.dll this dll if you don’t have this ddl, download add it is named windows microsoft sql server driver for php1.1/
    extension=php_sqlsrv.dll
    C:\Program Files\Zend\ZendServer\etc\php.ini

    But i don’t understand why zend couldn’t add this line. Then it is wasting time for me.

    I am happy for that IIS7 and sql 2008, zend server 5 are working faster than iis7 and sql 2005, zend server 4.3.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">