after move all rowCount() Functions return fatal error
Fatal error: Call to a member function rowCount() on a non-object
i use this function like this :
$co = $pdo->query("SELECT * FROM `tbl_users`");
$pages->items_total = $co->rowCount();
This means something went wrong while executing the query. Perhaps something went wrong with the update and MySQL isn't running anymore? Verify this, make sure MySQL is running.
Also, you can try to run the same query in PhpMyAdmin to see if that works. If it does, you're sure this is a problem with PDO. If it doesn't, something must be wrong with the MySQL server.
But perhaps the easiest way to debug is to do something like this:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
With this, PDO will throw an exception when the query fails. Then put the query in a try ... catch block:
try {
$co = $pdo->query("SELECT * FROM `tbl_users`");
$pages->items_total = $co->rowCount();
} catch (PDOException $e) {
echo $e->getMessage();
}
This will give you more debug info. When the query fails, the exception will be caught by the catch block, and the message will be outputted. This message usually tells you where the problem is.
Related
This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 5 years ago.
I'm trying to get my head around MySQli and I'm confused by the error reporting.
I am using the return value of the MySQLi 'prepare' statement to detect errors when executing SQL, like this:
$stmt_test = $mysqliDatabaseConnection->stmt_init();
if($stmt_test->prepare("INSERT INTO testtable VALUES (23,44,56)"))
{
$stmt_test->execute();
$stmt_test->close();
}
else echo("Statement failed: ". $stmt_test->error . "<br>");
But, is the return value of the prepare statement only detecting if there is an error in the preperation of the SQL statement and not detecting execution errors? If so should I therefore change my execute line to flag errors as well like this:
if($stmt_test->execute()) $errorflag=true;
And then just to be safe should I also do the following after the statement has executed:
if($stmt_test->errno) {$errorflag=true;}
...Or was I OK to start with and the return value on the MySQLi prepare' statement captures all errors associated with the complete execution of the query it defines?
Thanks
C
Each method of mysqli can fail. Luckily, nowadays mysqli can report every problem to you, all you need is ask. Simply add this single line to the connection code,
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
And after that every error will reveal itself. No need to test any return values ever, just write your statements right away:
$stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
$stmt->bind_param('iii', $x, $y, $z);
$stmt->execute();
When the error occurs at any step, it will throw a usual PHP Exception that can be handled or just reported the same way as any other PHP error. Just make sure you configured PHP error reporting properly, i.e. on the dev server errors are displayed on-screen and on the production server errors are never displayed but logged instead.
Completeness
You need to check both $mysqli and $statement. If they are false, you need to output $mysqli->error or $statement->error respectively.
Efficiency
For simple scripts that may terminate, I use simple one-liners that trigger a PHP error with the message. For a more complex application, an error warning system should be activated instead, for example by throwing an exception.
Usage example 1: Simple script
# This is in a simple command line script
$mysqli = new mysqli('localhost', 'buzUser', 'buzPassword');
$q = "UPDATE foo SET bar=1";
($statement = $mysqli->prepare($q)) or trigger_error($mysqli->error, E_USER_ERROR);
$statement->execute() or trigger_error($statement->error, E_USER_ERROR);
Usage example 2: Application
# This is part of an application
class FuzDatabaseException extends Exception {
}
class Foo {
public $mysqli;
public function __construct(mysqli $mysqli) {
$this->mysqli = $mysqli;
}
public function updateBar() {
$q = "UPDATE foo SET bar=1";
$statement = $this->mysqli->prepare($q);
if (!$statement) {
throw new FuzDatabaseException($mysqli->error);
}
if (!$statement->execute()) {
throw new FuzDatabaseException($statement->error);
}
}
}
$foo = new Foo(new mysqli('localhost','buzUser','buzPassword'));
try {
$foo->updateBar();
} catch (FuzDatabaseException $e)
$msg = $e->getMessage();
// Now send warning emails, write log
}
Not sure if this answers your question or not. Sorry if not
To get the error reported from the mysql database about your query you need to use your connection object as the focus.
so:
echo $mysqliDatabaseConnection->error
would echo the error being sent from mysql about your query.
Hope that helps
try {
self::$dbinstance = new PDO(
"mysql:host=$c[host];dbname=$c[dbname]", $c['user'], $c['password']
);
self::$dbinstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo "Errors" . $e->getMessage();
}
In the above code, if PDO fails to connect to the host, a fatal error reveals the username and password.
Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2003]
Can't connect to MySQL server on '172.25.102.65' (10060)' in
D:\xampp\htdocs\mytest\wh_client_2.1\classes\importmodule-class.php:33 Stack trace: #0
D:\xampp\htdocs\mytest\wh_client_2.1\classes\importmodule-class.php(33): PDO-
>__construct('mysql:host=172....', 'host', 'password') #1
One possible way is to turn the display_error=0 off in php.ini, but this way I won't able to know that when my host is not responding.
Is there a way I can modify the error message?
There is a difference between error handling and error reporting.
Error handling is the process of preventing your end users to see any stack trace, vital information or automatically generated error messages. It can also modify the way your script runs by using a try catch block.
Error reporting defines which information will be reported by a given script.
To handle errors properly, I think that ini_set('display_errors',0); is the better approach. You do not want any error message displaying on the screen.
However, I want to have all possible information on errors, so I use error_reporting(E_ALL);.
Errors are written in a file, error_log, which usually resides at the same level as your index.php (or any PHP file called directly). You can also access it from your cPanel.
Your error is probably uncaught because your code is in a namespace, whereas you want to catch the global namespace PDOException. Use a \ to indicate your script you're looking for the global PDOException. Once you catch your error, you can echo the content you want, using the normal methods of the PDOException class.
try {
$db = new PDO (/*connection infos*/);
}
catch (\PDOException $e) {
switch ($e->errorCode()) {
case 'HY000':
// Or whatever error you are looking for
// here it's the general error code
mail('your#email.com','connection problem',$e->getTraceAsString());
$db = new PDO (/*rollback connection infos of a local database*/);
break;
}
}
That would send you a mail, containing the trace of the error, preventing your user from seeing it while telling you something is wrong.
Here is the reference for the error codes returned by PDO statements.
When your host is not responding you will know all right - your host will stop responding. Then you have to peek into the error log and find the error message with the particular error.
So, just keep with display_errors=0 as it's a must-have in a production environment anyway.
No, don't try to throw the exception as it will spit out such critical information... Handle them with some appropriate custom error messages and handle those exceptions inside your custom logging functions...
You must be doing something similar to this...
<?php
try {
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'uname', 'pass');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->query('bla bla bla bla'); //<---- This will definitely fail!!!!
} catch(PDOException $ex) {
echo "An error occurred!";
file_put_contents('somefile.txt', $ex->getMessage(), FILE_APPEND);
}
As you can see, the above query is indeed going to fail. So the end user will be seeing just An error occurred! message, but the error will be logged to your somefile.txt file.
You can do something like this:
<?php
// connect
try
{
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
}
catch (PDOException $e)
{
$dbh = NULL;
}
// check if connected
if($dbh)
{
// run queries
}
else
{
die('Oops! Our server has encountered an error, please try again later');
}
?>
I'm doing mysql queries with PHP5 and PDO.
I'm trying to handle exceptions from queries using try/catch. But if, for example, I have a syntax error like this :
try{
$sql = 'IggggNSERT INTO t_table (ID, MONTH) VALUES (:ID, :MONTH)';
$r = $conn->prepare($sql);
$r->bindValue(':ID', $id);
$r->bindValue(':MONTH', $month);
$r->execute();
return $r;
}
catch (Exception $e) {
die('Error');
}
I get this fatal error :
PHP Fatal error: Call to a member function bindValue() on a non-object
But no exception is raised and my catch block is not executed.
How could I handle this so I could rollback previous queries?
PDO will only throw an exception if the problem happens from within PDO. The error that you're getting is in reference to you accessing $r->bindValue despite $r failing to initialize.
In normal operation, you shouldn't ever get any syntax errors with your SQL.
You can however try setting the following line in your database file:
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
As far as I understand from PHP.NET, prepare() throws an exception if this line is set, which should set off the catch statement.
PHP.NET PDO::prepare
If the database server successfully prepares the statement, PDO::prepare() returns a PDOStatement object. If the database server cannot successfully prepare the statement, PDO::prepare() returns FALSE or emits PDOException (depending on error handling).
In my Symfony 1.4 project in one of my class.php file I used the following codes to execute query and fetch object.
$statement = Doctrine_Manager::connection()->execute($query);
$resultset = $statement->fetchAll(PDO::FETCH_OBJ);
I tried to use try-catch block to catch any run-time exceptions. I can easily do that for the first line like
try {
$statement = Doctrine_Manager::connection()->execute($query);
}
catch (Exception $exc) {
echo "custom error message";
}
But, I this dosen't work for the second line. It always show the following error when I run the page
Fatal error: Call to a member function fetchAll() on a non-object in
\lib\model\doctrine\DeductionInfo.class.php on line 104
How can I resolve this?
Of course it seems to be an invalid query or something like that, resulting in a non-object in your var $statement. Debug or var_dump your $statement var at first.
Doctrine btw is on top of PDO. By default a PDO construct throws an exception on error. But you have to set error handling for quering to exception (http://php.net/manual/en/pdo.error-handling.php) if you want to use try-catch statements. I don't know exactly the way Doctrine 1 handles this.
I have a script that I am updating by replacing the inline mysql queries with PDO prepared statements and queries. When the query is correct or returns a result, it works fine. However, when there is an error in the query statement try/catch dies not work. For example, I used this test code:
$query = $this->dbh->prepare('SELEC menu_item, hyperlink, admin FROM top_menu;');
try
{
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC));
die("success");
}
catch(Exception $e)
{
die("fail");
}
The query is wrong ("SELEC" instead of "SELECT"), so the flow of the script should go into the exception/error brackets, and yet it doesn't; I keep getting "success". I've tried catch(PDOException $e) instead of catch(Exception $e) with the exact same results.
What am I doing wrong, and how can I fix this? Thanks.
A similar problem has been answered here, PDO won't throw exceptions unless you tell it to. Have you run:
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
on the PDO object.
For PDO's fetch() on failure FALSE is returned. No exception is thrown.
See: http://php.net/manual/en/pdostatement.fetch.php