PHP Error:Fatal error: Call to a member function fetch_assoc() on a non-object in

Thanks, I placed the code and will keep an eye on the error_log and check what information it logs the next time this issue happens.

Yes. But without __METHOD__, __LINE__, date(), error_code(), error_message(), etc, included your answer offers very little help to the OP.

Besides, you are checking numerous statements on the different lines. Which particular __LINE__, error_code(), error_message(), etc, it should log?

Besides, with mysqli you don’t have to check for errors manually, as it can throw exceptions on it’s own, and said exception already contains __METHOD__, __LINE__, date(), error_code(), error_message(), etc, and thus can be logged without the need of any extra line code.

I was just trying to pinpoint the error and for the OP to start looking and to further investigate.

Exceptions are thrown - they are intended to be caught.
Errors are generally unrecoverable.

If the error only occurred once then there is little chance of ever discovering the problem. Recurring problems may be easily fixed or require a vast amount of investigation. The error log is a useful tool to get started on tracking errors especially when the problem is on a live site. It is up to the OP to pinpoint the problem with suggestions from the community.

Without having full access to the site it is virtually impossible to cater for every eventuality.

I think it is essential to test return results which are often unrecoverable errors.

Why not? This statement of yours contradicts with the very case in question: the OP noticed this kind of odd error and come to ask.
You probably misunderstood the nature of this last problem. There is no question how to spot an error - the OP has been already aware of it, because PHP is good with error reporting already. No need to check for the execute() result manually, if the very next line will report it already.

There was only a question how to get the cause of error.

No need to test for the unrecoverable errors. All you need is to log them and to show an excuse page along with proper HTTP header.

Exceptions are thrown - they are intended to be caught.

That’s but a superstition. An uncaught exception is as good as a caught one. If you have no particular handling scenario, it’s better to let it go and be handled by PHP, than catch only for sake of it and handle it wrong way.

OP #27

Unfortunately, I am still getting the same error after updating my code to prepared statements. It seems to rarely occur when a user or bot tries to reach some invalid URL. Below is my function:

@colshrapnel
The reason I posted was because of the above post. The OP appears to be relatively new to PHP and maybe does not appreciate that sometimes errors are incorrectly shown and are due to a previous PHP statement.

I think the error was due to the $result = $stmt->get_result(); returning a boolean instead of an object:

PHP Fatal error: Call to a member function fetch_assoc() on a non-object
it points to this line:

$post = $r->fetch_assoc();

As shown if the $result was tested there was an opportunity to log the error_code, etc and to recover gracefully.

I acknowledge your other comments and think it would be better to raise the issues in another topic.

Hi colshrapnel and John,

Thank you for your further tips. I put the line as colshrapnel suggested and I get the following error two times in the last couple of days for different "category"s.

[09-Mar-2016 01:21:14 America/New_York] PHP Fatal error:  Uncaught exception 'mysqli_sql_exception' with message 'Prepared statement needs to be re-prepared' in /home/***/public_html/functions.php:35
Stack trace:
#0 /home/***/public_html/functions.php(35): mysqli_stmt->execute()
#1 /home/***/public_html/category.php(8): get_category('my_category')
#2 {main}
  thrown in /home/***/public_html/functions.php on line 35

My access logs say that this request was made by Googlebot in the two times that the error was logged.

66.249.79.98 - - [09/Mar/2016:01:21:14 -0500] "GET /my_category/ HTTP/1.1" 500 - "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

Here is my get_category() function:

function get_category($cat) {
	$cat = preg_replace('/[^a-z0-9-]/', '', $cat);
	$stmt = DB::$db->prepare("SELECT * FROM categories WHERE category_name = ?");
	$stmt->bind_param('s', $cat);
	$stmt->execute();
	$result = $stmt->get_result();
	$category = $result->fetch_assoc();
	if (empty($category)) {
		require('404.php');
		exit;
	}
	return $category;
}

It seems to me this issue is caused randomly, because that URLs work fine and also the Googlebot fetched them with no errors at other times. I just need to know if this error is caused by my function/query so that I can fix it, if not and it happens randomly due to temporary server or Googlebot script malfunction, I will just ignore and stop trying to fix it.

Thanks.

Or something that identified itself as googlebot

The user-agent HTTP header can be spoofed.

If you can check the IP used, see if it’s a known Google IP

1 Like

Yes, the IP (66.249.79.98) is a Googlebot IP.

1 Like

Check your error log.

‘Prepared statement needs to be re-prepared’
in /home/***/public_html/functions.php:35

1 Like

I never seen such an error before, so I had to google for it (by the way, you can always do it yourself).

Mysql docs say, that such an error may occur only if you’re modifying table structure. Does your code make any modifications like ALTER TABLE or anything like this during runtime?

1 Like

My code doesn’t make any modifications such as ALTER or anything else. Just a database connection and then the get_category function.

I did some more search on Google and from the comments on the following pages:

http://zend-framework-community.634137.n4.nabble.com/Mysqli-statement-execute-error-Prepared-statement-needs-to-be-re-prepared-tp3380895p3405712.html

http://bugs.mysql.com/bug.php?id=42041

I learned the following:

  • This error happens only when using mysqli prepared statements, it doesn’t happen with normal queries or PDO.
  • This error happens when a create, alter, drop etc. operation occurs in the moment between a SQL statement prepare() and execute() or when there’s a concurrent mysqldump running.

I haven’t done any mysqldumps, unless an administrator did that without my knowledge. I don’t know if other users’ usage of the database server effect me on a shared hosting platform. I mean if another user makes a mysqldump, would that effect me too. I also did not do any DDL operations as far as I know.

I guess I will just move to PDO.

Well, despite the reason, I uphold such a decision.
For a replacement I’d suggest to use the simple PDO wrapper I wrote. Here is your function rewritten using it

function get_category($cat) {
    $sql = "SELECT * FROM categories WHERE category_name = ?";
    $category = DB::run($sql, [$cat])->fetch();
    if (!$category)) {
        require('404.php');
        exit;
    }
    return $category;
}

Here in one line you prepare the query, bind variables to it, and get the result.

1 Like

Thanks a lot! Looks much simpler, which is very important for me as someone who tries to optimize every single byte in the code. Hopefully, PDO will cause less issues.

Feel free to ask any questions regarding PDO as well.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.