At the Intersection of PHP and Microsoft
In my last post, I promised a comparison of the APIs for the MSSQL and SQLSRV extensions of PHP, so here it is. I constructed the table below assuming some familiarity with the MSSQL extension. I’m aiming to provide a high-level comparison that you might use if you were considering moving to the SQLSRV extension, but I think there is also some interesting information if you are just curious about the differences. (For a detailed comparison, I will point you to the MSSQL API documentation and the SQLSRV API documentation.) In cases where a short note wasn’t enough (and there were several of these), I’ve provided relevant links to topics in the SQLSRV documentation.
As I constructed the table below, a few major differences between the APIs stood out for me. I think they are worth noting before looking at the function-to-function comparison:
$sql = "{call StoredProcedureName(?, ?)}";
The question marks are place holders for stored procedure parameters (if there are any). This query is then executed like any other query (with sqlsrv_query or sqlsrv_prepare/sqlsrv_execute). For more information and examples, see How to: Retrieve Output Parameters, How to: Retrieve Input/Output Parameters, and sqlsrv_next_result.
If you have used both API’s (or if you’ve just read the comparison), I’d be interested in which API you like better and why. Do you think one is more elegant than the other? Is one more practical than the other? I think this could be an interesting discussion.
MSSQL Function
SQLSRV Equivalent Function(s)
Notes
mssql_bind
sqlsrv_query
mssql_close
sqlsrv_close
mssql_connect
sqlsrv_connect
mssql_data_seek
sqlsrv_fetch
or
sqlsrv_fetch_array
mssql_execute
mssql_fetch_array
mssql_fetch_assoc
mssql_fetch_batch
No equivalent function.
mssql_fetch_field
sqlsrv_field_metadata
mssql_fetch_object
sqlsrv_fetch_object
mssql_fetch_row
mssql_field_length
mssql_field_name
mssql_field_seek
mssql_field_type
mssql_free_result
sqlsrv_cancel
mssql_free_statement
sqlsrv_free_stmt
mssql_get_last_message
sqlsrv_errors
mssql_guid_string
mssql_init
mssql_min_error_severity
mssql_min_message_severity
mssql_next_result
sqlsrv_next_result
mssql_num_fields
sqlsrv_num_fields
mssql_num_rows
sqlsrv_num_rows
mssql_pconnect
mssql_query
mssql_result
sqlsrv_fetch/sqlsrv_get_field
mssql_rows_affected
sqlsrv_rows_affected
mssql_select_db
That’s all for today folks…thanks!
-Brian
Share this on Twitter
SQLSRV's prepared statement API (passing in bound variables byref at the creation of the prepared statement instead of at execution) is not only piss poor design, makes SQLSRV all but useless to me given that it makes it inordinately complex and fragile to write PDO-style wrappers for a SQLSRV-driver for Doctrine
Daniel-
Can you narrow the problem? Is it passing variables by reference? Or is it that you want to pass the variables at execution? (or both?)
BTW, it looks like the SQL Server Driver for PHP team is considering a PDO driver: http://social.msdn.microsoft.com/Forums/en-US/sqldriverforphp/thread/4614212e-9193-46d5-babc-5517bd494553
Thanks.
My problem is both I guess you could say.
The whole goal of a prepared statement is my ability to send my query, sans values, to the DB so it can spool up and start compiling the query and prepping indexes while I gather the parameter values. I then loop over the gathered parameter values, feeding a new set per transaction to have the DB re-use the query it's already compiled and analyzed.
So on one hand, being forced to push in my parameters at query creation is stupid because in a normal code flow, I haven't even gathered my parameters yet (granted I know what they will be).
Secondly, using variables by reference forces me to pollute my methods with ByRef variables that ad an extra layer of ambiguity to my debugging.
And finally it almost all but destroys the ability to easily pass the prepared statement resource between methods as you can't just pass the resource, you have to pass the parameters ByRef array along with it.
While I can work around these problems, it's unnecessary complexity being introduced into my application that I don't need or want to spend my time on, and given the mssql and PDO_mssql drivers still function I will continue to use them until Microsoft at least tries to follow common PHP conventions (e.g. the avoidance of passing variables by reference, and prepared statement behavior).
If the SQLSRV team is serious about developing a PDO driver then they have answered all of my frustrations. We can chalk the sqlsrv driver up as a learning experience if they do finish the PDO driver.
Then all I'll have to yell at them about is poor Linux server support :P
Hopefully this isn't too late too late to help you out: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=df4d9cc9-459c-4d75-a503-ae3fceb85860
thanks
www.freedownloadpond.com
Hi Brian, I hope you can help me. I`m developing one project with sqlsrv but I have one problem when I want to run a stored procedure with OUTPUT parameter guid format. I have predefined format of const EMPTY_GUID = '00000000-0000-0000-0000-000000000000'; Everythin works fine, but retrieved GIUD from the database is broken with question mark in last character like "4C532F26-126E-4ADD-84F0-B7059E5E032?" I checked all setting in PHP, APACHE, MS SQL and everything seems fine. Charset, collation, everything is the same on all sides. DO you have any idea what could be wrong please? thank you!
Milan-
Without looking at your code, I can't really say what the problem might be. I think the best thing to do in this case is to start a thread in the forum (social.msdn.microsoft.com/.../threads) that includes the code that is causing the issue. (I'm assuming you are using the sqlsrv driver and not the mssql driver.) Once I can reproduce the problem, we can figure out how to fix it.
Brian,
Thanks for the great summary of the APIs. I have a couple of suggestions for improvement. If you use to use: mssql_query followed by mssql_fetch_array, you can't just use sqlsrv_query and sqlsrv_fetch_array functions as they are not quite equivalent. The fetch will fail unless you change the Scrollable to static. The query also has different returns if there are zero rows. mssql returns a true instead of a resource.
Paul
Thanks, Paul. That looks like useful information that I should add to the post...I'll confirm and add it!
Cheers,
Brian
What I said may have been incorrect. I mentioned the wrong function! It is num_rows, not fetch_array that caused the problem. Here is mssql code and how to rewrite it to work with sqlsrv when using num_rows:
$res = mssql_query($sql, $conn);
$num = mssql_num_rows($res);
Should be rewritten as:
$res = sqlsrv_query($conn, $sql, array(), array("Scrollable" => SQLSRV_CURSOR_STATIC));
$num = sqlsrv_num_rows($res);
hello.
thank for this article. meybe you forget to compare with mysql?
@faca5 - You are right! I will right that post soon...thanks.
Hello. SQLSrv for PHP has worked well for me and I must say I like it.
But, there's this one doubt that is puzzling me: when we pass a parametrized query (with the “?” marker) to sqlsrv_query what does it really do?
Does it simply insert the values at the markers and passes a plain (non- parametrized) query to SQL Server?
Or does it prepare and execute the SQL? In theory, this should not be the most efficient way, because it's a one-time query. Right?
I'd very much like to take this out of my mind. Thanks.
I have a problem when I run php.exe
Php startup: sqlsrv: unable to initialize module
Module compiled with module API=20060613
PHP compiled with module API=20090626
These options need to match
I used
PHP Version 5.3.1
php.ini
extension=php_sqlsrv_52_ts_vc6.dll
extension=php_pdo_sqlsrv_52_ts_vc6.dll
anyone who can help me to solve this problem?
Hello, Pure.
I think I can help. Actually, the answer lies in the output of php.
The binary versions need to match. Change your PHP.ini to:
extension=php_sqlsrv_52_ts_vc9.dll
extension=php_pdo_sqlsrv_52_ts_vc9.dll
Notice VC9 instead of VC6.
This should work.