Forum Moderators: coopster
I've made my own database (MySQL) driver / layer. No problem so far till it comes to looping. At first all looks fine, but at the end my own error handler reports an error. There is no usefull information available (like what MySQL errorcode returned) only things that are logical. It seems that the loop loops one time too much. So if there are 8 rows in the result, he tries to get an 9th one. That one doesn't exists --> error.
I have really no idea what it could be. Here's the source code of my testfile:
<?phpinclude_once("../source/api.php");
$API = new API;
$testquery = "SELECT * FROM ".$API->pre."modinfo";
$p = $API->database->dbquery($testquery, 0, __LINE__, __FILE__);
while($res = $API->database->dbFetchQuery($p, __LINE__, __FILE__))
{
echo "ID: <b>".$res[0]."</b><br />\n";
echo "mName: <b>".$res[1]."</b><br />\n";
echo "mDesc: <b>".$res[2]."</b><br />\n";
echo "mImage: <b>".$res[3]."</b><br />\n";
echo "mActive: <b>".$res[4]."</b><br />\n";
echo "mFN: <b>".$res[5]."</b><br />\n";
echo "mCat: <b>".$res[6]."</b><br />\n";
echo "mShow: <b>".$res[7]."</b><br />\n";
echo "<br />\n";
}
?>
And the source codes of the used db-functions plus the error-handler I wrote:
<?phpfunction dbquery($query, $do_fetch = 1, $linenumber = 0, $file = "Not specified (dbquery)") {
// false and 0 are seen as the same in php. everything else will be seen as true
$the_query = mysql_query($query) or die($this->sqlFatalError($query, $linenumber, $file));
if($do_fetch == 1){
$this->queryCount++;
$this->arrayQueries[] = $query;
$result = mysql_fetch_row($the_query) or die($this->sqlFatalError($query, $linenumber, $file));
}
else {
$this->queryCount++;
$this->arrayQueries[] = $query;
$result = $the_query;
}
if(!$result){
die($this->sqlFatalError($query, $linenumber, $file));
}
return $result;
}
function dbFetchQuery($query_to_fetch, $linenumber = 0, $file = "Not specified (fetch)")
{
if(!isset($query_to_fetch))
{
return;
}
$query_to_fetch = mysql_fetch_row($query_to_fetch) or die($this->sqlFatalError($query_to_fetch, $linenumber, $file));
return $query_to_fetch;
}
[...]
function sqlFatalError($sqlquery, $ln = 0, $f = "Not set")
{
$error = mysql_error();
$errno = mysql_errno();
$add_info .= "Line number where it went wrong: ".$ln."<br />\n";
$add_info .= "File in where it went wrong: ".$f."<br />\n";
if(!isset($add_info))
$add_info = "No Additional Information<br />\n";
echo "<font face=\"Verdana\" size=\"2\" color=\"#000000\"><strong>A serious error occured while trying to
use the MySQL driver.</strong><br />
Below you'll find more technical information about the error, this can be handy
when an administrator tries to solve the problem. So please contact an administrator to take a look at
this errormessage.</font><br /><br />
<table width=\"60%\" border=\"1\" bordercolor=\"#000000\" style=\"border-collapse: collapse\">
<tr>
<td><font face=\"Courier New\" size=\"2\"><b>MySQL error no.</b>: $errno<br />\n
<b>MySQL detailed errormessage</b>: $error<br />\n
<b>MySQL query that failed</b>: $sqlquery<br />\n
<b>Additional Information</b>:<br />\n $add_info</font></td>
</tr>
</table>";
}
?>
Does anyone have an idea? I posted this on many forums but without success. I was tipped by a friend to go to this site. He said there were some goog php'ers around here... Can you take a look at this one then, please?
FALSE if there are no more rows. Therefore, when your user-defined function dbFetchQuery is executed, and there are no more rows to process, your [b]or[/b] condition kicks in and ends after your user-defined function sqlFatalError because you specified it in a die [php.net] language construct. Why the
[b]or[/b] condition?
FALSE if there are no more rows the last fetch is always going to return FALSE and your error-handling logic is going to kick in. I would terminate the fetch statement and check for an error afterward and handle accordingly:
$query_to_fetch = mysql_fetch_row($query_to_fetch);
if (mysql_errno()) die($this->sqlFatalError($query_to_fetch, $linenumber, $file));
return $query_to_fetch;
But I thought of something that looks like that: just "kill" the error by putting a '@' in front of it. It's radical, I know. But your solution is a bit like this one: if the error no. is 0 then it's probably the extra loop that doesn't exist. So then you'll be doing the same but a little bit more elegant.
Am I right?