A good proportion of the projects my company undertakes end up on Windows servers with IIS and SQL Server and hence we use the SqlSrv PHP extension from Microsoft. We don’t host any of these projects ourselves and leave it up to the client’s IT department. This is the main reason that we use a database abstraction layer, Zend_Db, in our case as we can swap the underlying database out with less hassle.
A couple of weeks ago, I came across a problem when installing our app onto the client’s server.
It didn’t work.
This was a surprise as we have a few Windows Server VMWare installations on which we had tested and they had worked fine. The most obvious differences were that this server was 32bit and that it was using v2 of the SqlSrv extension. As there were a number of differences from our usual fare to the client’s install, so it took me a while to (a) build a install that exhibited the problem and (b) reduce the problem to something simple.
The error I was getting is this:
exception 'Zend_Db_Statement_Sqlsrv_Exception' with message
'[Microsoft][SQL Server Native Client 10.0]String data, right truncation'
Googling failed me completely!
I eventually narrowed down the SQL statement that caused the problem:
SELECT email_user_include_form_details FROM "forms"
That’s not especially complicated :)
At the point, I yelled for help which came in the form of Brian Swan of Microsoft. There’s quite a few helpful MS guys around nowadays if you keep your ear close to the PHP community, which is really handy. Brian helped prove that I wasn’t going mad and that there really was a problem.
We determined the problem to be that with v2 of the sqlsrv driver, you cannot have a fieldname longer than 30 characters.
Brian assured me that the team are aware of this and it will be fixed in a subsequent update of the driver. Also, it only affects the sqlsrv driver and not the pdo_sqlsrv driver. Hence, there are two workarounds:
1. Shorten your fieldnames to 30 characters or less
2. Use pdo_sqlsrv
Smart readers will already be commenting that there isn’t a Zend_Db_Adapter_Pdo_Sqlsrv and they’d be right, but it isn’t hard to write one :)
I cobbled together an adapter that works for me and have put it on github. As it’s not in the Zend_ namespace, we have to use an additional key in the application.ini file so that it is loaded:
resources.db.adapter = "Pdo_SqlSrv"
resources.db.params.adapterNamespace = "Akrabat_Db_Adapter"
resources.db.params.host = localhostSQLEXPRESS
resources.db.params.username = testuser
resources.db.params.password = testpassword
resources.db.params.dbname = testdatabase
The key difference from a standard Zend_Db adapter is the use of the resources.db.params.adapterNamespace key which tells the system the full name of the class to load.
My limited testing shows that this adapter works with v2 of pdo_sqlsrv which solves my problem with fieldnames that are longer than 30 characters!
Unfortunately, I found out about this too late for Zend Framework 1.11, so I’ll have to look at getting it into Zend Framework 2.0.