[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