I am writing some business critical queries and am relying on is_resource to filter all failed queries (ie, bad syntax etc.)
Take this query for example:
$result = pg_query('SELECT * FROM logs');
if (!is_resource($result)) {
die('Error');
}
Will that also die('Error') if the query works but no rows are returned? I need it to return a resource even if no rows have been returned from the database.
There will be a resource if there is no error. To check rows, you want to use pg_num_rows.
Quote from php.net:
"If an error occurs, and FALSE is returned, details of the error can be retrieved using the pg_last_error() function if the connection is valid."
"A query result resource on success or FALSE on failure."
That sounds like there will always be a resource as result as long as there was no error.
I'm using MySQL with strict mode turned on. I am inserting data supplied by user through an HTML form. I've already done all my validation and this is the final step.
Here is an excerpt from my PHP code:
$sql = 'SET sql_mode = TRADITIONAL'; //last chance data validation
$mysqli->query($sql) or output_error('Database Error: Failed to set SQL mode');
$db_err_msg = 'Database Error: Failed to update profile summary';
$sql = "INSERT INTO {$tables['text']} (lngProfileId, memProfileText) VALUES(?, ?)
ON DUPLICATE KEY UPDATE memProfileText = VALUES(memProfileText)";
$stmt = $mysqli->prepare($sql) or output_error($db_err_msg);
$stmt->bind_param('is', $profile_id, $_POST['memProfileText'])
or output_error($db_err_msg);
$stmt->execute() or output_error($db_err_msg);
$stmt->close();
//if code reaches this point, can it assume insert/update succeeded?
Note: output_error is my error handler for fatal errors. It doesn't return; it exits.
Do I need to check for warnings? Or can I safely assume the insert/update succeeded? Is there some scenario that could cause a warning instead of an error even with strict mode turned on?
EDIT: I'm only concerned about things that should be considered fatal errors. If it was updated rather than inserted, that is of no concern to me. That's not an error.
Also, last_insert_id and affected_rows are meaningless in this case. If the user didn't make any changes, affected_rows will be 0 and the value of last_insert_id will not be updated.
My definition of succeeded in this case:
it inserted the record or updated the record or did nothing if no changes were made
it did not 'silently mangle my data'
Many newbie programmers make the mistake of assuming that a query succeeded without ever checking the return value or warnings. Their code works... under normal conditions.
My question is: "Considering my code, with strict mode turned on, and the error checking I've done, is it safe to assume the query succeeded? Is that a correct or incorrect assumption? Should I also check for warnings or would that be redundant?"
You should check the value of mysqli::info() function.
If it inserts data the string will look something like this,
Records: 1 Duplicates: 0 Warnings: 0
Another function is mysqli::affected_rows. it returns the number of rows affected for last insert/update/delete query.
Yes you can safely assume that, but just for a double check Fetch the ID of the latest record that is inserted. If there is an id, it was inserted then
While I think that it's probably a safe assumption, I figured better safe than sorry. I've added the following code directly after the execute statement before the close statement.
//I think this is probably redundant, but just in case
if ($mysqli->warning_count) {
$warnings = $stmt->get_warnings();
do {
trigger_error('Database Warning (' . $warnings->errno . '): '
. $warnings->message, E_USER_WARNING);
} while ( $warnings->next() );
}
I've added the comment so that I remember why I did that.
This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 5 years ago.
Can anybody explain why
$sql->execute($params);
returns FALSE, whereas
print $pdo->errorCode();
print_r($pdo->errorInfo());
both return SQLSTATE 00000, which means according to the documentation success? It is an INSERT and nothing is actually being inserted into the database... so, why do I get a success message from SQLSTATE?
In case it helps, this is the code...
$sql = $pdo->prepare("
INSERT INTO user (
username, fname, pass, salt, email,
loc_id_home, country_id_home, region_id_home,
cont_id_home, timestamp_reg, timestamp_upd, timestamp_lastonline,
online_status, gender, birthdate
)
VALUES (
:username,:fname,:pass,:random_salt,:email,
:loc_id_home,:country_id_home,:region_id_home,
:cont_id_home,'".time()."','".time()."','".time()."',
1,:gender,:birthdate)
");
$params=array(
':username'=>$username,
':fname'=>$fname,
':pass'=>$pass,
':random_salt'=>$random_salt,
':email'=>$email,
':loc_id_home'=>$loc_id_home,
':country_id_home'=>$country,
':region_id_home'=>$region,
':cont_id_home'=>$continent,
':gender'=>$gender,
':birthdate'=>$birthdate
);
$sql->execute($params);
print $pdo->errorCode();
print_r($pdo->errorInfo());
It is because $pdo->errorInfo() refers to the last statement that was successfully executed. Since $sql->execute() returns false, then it cannot refer to that statement (either to nothing or to the query before).
As to why $sql->execute() returns false, I don't know... either there is a problem with your $params array or with your database connection.
PDO::errorCode — Fetch the SQLSTATE associated with the last operation on the database handle
Note: The PHP manual (http://php.net/manual/en/pdo.errorinfo.php) does not define exactly what "last operation on the database handle" means, but if there was an issue with binding parameters, that error would have occurred inside PDO and without any interaction with the database. It is safe to say that if $pdo->execute() returns true, that $pdo->errorInfo() is valid. If $pdo->execute() returns false, the behavior of $pdo->errorInfo() is not explicitly clear from the documentation. If I recall correctly from my experience, execute returns true, even if MySQL returned an error, returns false if no operation was done. Since the documentation is not specific, it might be db driver specific.
This answer reflects practical experience as of when it was written in September 2012. As a user has pointed out, the documentation does not explicitly reaffirm this interpretation. It also may only reflect the particular database driver implementation, but it should always be true that if $pdo->execute() returns true, that $pdo->errorInfo() is valid.
You might also want to set PDO::ERRMODE_EXCEPTION in your connect sequence. Exception handling makes it unnecessary to check and query the error.
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
I Faced the similar problem ,
This occurs manly due to error in query, try to run your query in php-myadmin or any other query runner and confirm that your query is working fine.Even if our query syntax is correct other simple errors like leaving null or not mentioan a column that set as not null in table structure will cause this error.(This was the errror made by me)
As user1122069 explained the reason for $pdo->errorInfo() says nothing is wrong may be due to
$pdo->errorInfo() refers to the last statement that was successfully
executed. Since $sql->execute() returns false, then it cannot refer to
that statement (either to nothing or to the query before)
Hopes this helps :)
From the php manual:
PDO::ERR_NONE (string)
Corresponds to SQLSTATE '00000', meaning that the SQL statement was successfully issued with no errors or warnings. This constant is for your convenience when checking PDO::errorCode() or PDOStatement::errorCode() to determine if an error occurred. You will usually know if this is the case by examining the return code from the method that raised the error condition anyway.
So it sounds like it did insert the record. Check the last record id in your table... maybe you just missed it?
I was getting this error at one time. I only got it on one server for all failures. A different server would report the error correctly for the same errors. That led me to believe it was a MySQL client configuration error. I never solved the specific error, but check your configurations.
Try to check $sql by print_r() and copy your query then try resultant query in phpMyadmin. Hope will get the reason. There would be chance of irrelevant value.
$result=mysql_query("SELECT * FROM playerlocations WHERE player<>'0'");
$returntext="";
while($row=mysql_fetch_array($result))
{
if($returntext!=""){$returntext.="&";}
$returntext.=$row['player']."#".$row['locations'];
}
the error message claims that $result isn't a valid result set. I tested it in phpmyadmin, and it worked. I don't know why it won't work here, please help.
It says it isn't a valid result set. That doesn't necessarily mean it isn't a valid query. (Although != instead of <> would be nice.)
To figure out why it's not valid, output the result of calling mysql_error() after running the query:
echo mysql_error(); //most direct way to do this
It will tell you what MySQL reports as the error message.
One obvious thing to check: have you opened the connection (with mysql_connecst()) before running the query?
We have a function used within our PHP/MySQL application which returns basic configuration information, it contains a simple select query and looks like this:
public function getConfigurationValue($field)
{
$res = mysql_query("SELECT `cfg_value` FROM `ls_config` WHERE `cfg_name` = '".mysql_real_escape_string($field)."'");
$cfg = htmlspecialchars(mysql_result($res,0));
return $cfg;
}
This problem we are having is that occasionally, seemingly at random, this query throws a mysql error on mysql_result saying that "supplied argument is not a valid mysql result resource". In our debugging we have determined though that this is not because $field is not being passed. Essentially, for a reason we cannot determine a perfectly valid query fails and returns no results causing an empty result set and the subsequent error. If the error was due to the mysql connection failing the script would have died well before this. Also, this function may be called 50-100 times on some page loads but it only tends to fail once on each load.
Please let me know if you need any other information to work this out.
Thanks.
searching for php "supplied argument is not a valid mysql result resource" reveals that to get the actual error, you'd need to call mysql_error, and the error that you get is because the result of the query is FALSE - this value not being a valid mysql result resource.
i.e. in short you have something like:
$res = FALSE; # should contain the mysql result but does not, due to error.
$cfg = htmlspecialchars(mysql_result($res,0)); # the attempt to call mysql_result on invalid argument errors out.
So you'd want to use something like this:
$query = "SELECT * FROM cats WHERE id=$id";
$qr1 = mysql_query ($query)
or die ("Query failed: " . mysql_error() . " Actual query: " . $query);
You might want to give this a shot and see what the underlying error message says.
Given that the error is "MySQL server has gone away", There can be multitude of reasons for it - this article would be a good start to investigate. Searching suggests also some php-related and stack-specific bugs, so it looks like you might need to debug it with a closer attention.
Maybe try to duplicate the setup on another box and then start experimenting with the versions/settings, and see if any of the already reported scenarios match your case. Unfortunately, seems there's no single simple answer to this.