[freetds] Re: Problem with return value from PHP's mssql_query()when calling a stored procedure that returns an empty result set

Daniel Fazekas fdsubs at axelero.hu
Wed Mar 31 23:25:57 EST 2004


On Apr 1, 2004, at 4:22, Michael Sims wrote:

> In the above example I'm using a custom error handler which will 
> trigger if
> mssql_query fails.  Let's suppose I didn't do that:
>
> <quote>
> if ($result = mssql_query('select foo from bar')) {
>   while ($row = mssql_fetch_object($result)) {
>     //Do something
>   }
> } else {
>   echo "An error occured with the query";
> }
> </quote>
>
> The above example breaks when it runs across the problem I mentioned 
> in my
> original post.  The mssql_fetch_object() expects a result resource and 
> barfs
> when given a boolean.

This is exactly the kind of scenario I was thinking of when I said it's 
easy to fix.

/* if it's an error when there's no result resource */
if (is_resource($result = mssql_query('select foo from bar'))) {
   while ($row = mssql_fetch_object($result))  {
//Do something
   }
} else {
   echo "An error occured with the query";
}

/* if it's not an error when there's no result resource */
if ($result = mssql_query('select foo from bar')) {
   if (is_resource($row)) while ($row = mssql_fetch_object($result))  {
//Do something
   }
} else {
   echo "An error occured with the query";
}

> That may be true, but I have hundreds of existing PHP pages that 
> depend on
> the old behavior.  Using grep and wc I can see that I'd have to modify 
> 280
> calls to mssql_fetch_object() in 112 different files.  To be honest, I 
> use a
> database abstraction object, and if I absolutely had to I could work 
> around
> this inside my fetch_object() wrapper function, but that's awfully 
> kludgy.

The inconvenience of rewriting all the old code having the weaker error 
checking is a very valid concern. It's my turn however to respectfully 
disagree on the point that strict error checking is in any way kludgy.

When you know that the _fetch_* calls will "break" if $result is not a 
result resource, is it not logical to check beforehand if it really is 
a resource? Especially in case you already had it inside a check which 
in essence reads "if $result is not 0, '0', null, false or anything 
else which in PHP's weakly typed language equals to false" and you 
could simply make it read "if $result is a resource."

And on the point of "breaking," even in the original case, the _fetch_* 
call would simply emit a warning message to where you set error logging 
to write to, and still return false and the code would work the same 
way it did when confronted with an empty result resource in the 
original case.

Since you already have the fetch call inside a wrapper, it should be 
easy enough to add a check there, which could as well have been there 
already anyway, regardless of whether you ever encountered this bug or 
not.

Taking into account that the callers of your wrapper function expect it 
to fail only if the query failed, you might add something along the 
lines of:

if (!is_resource($result)) {
	if ($result === true) {
		-- do as if there wasn't any error, there simply weren't any results 
to return
	} else return -- an error occurred
}

I hope you aren't offended by me offering this workaround or suggesting 
that you should use an is_resource() check in any future code.

You have reported two separate bugs for which we are undoubtedly 
grateful.

The first is this discrepancy between how the sybase extension now 
behaves as opposed to the sybase_ct or mssql extensions, or, according 
to you, the sybase extension used to work in the past with older 
versions. This is clearly a bug, it just didn't sound easy enough to 
locate where and why does it occur, or whether the bug is in FreeTDS or 
PHP, hence my suggestion to amend your PHP code instead.

You were also the first to report that the PHP sybase extension no 
longer compiles with the current FreeTDS snapshot. Actually this may 
have been broken for a while longer, I guess most people wanted to use 
the sybase_ct or mssql extensions instead anyway. I have reproduced 
this problem on my system with PHP 4.3.5, so I'll look into it and 
hopefully figure out what's causing it. Before this is fixed, it's hard 
to even reproduce your first problem.

--
fds




More information about the FreeTDS mailing list