0

I'm trying to define a custom error handler for mysqli errors. Following my Database singleton:

<?php

class Database extends mysqli
{
    private static $instance;
    public function __construct($host, $user, $password, $database)
    {
        set_error_handler('self::error', MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        parent::__construct($host, $user, $password, $database);
    }

    public static function instance()
    {
        if (self::$instance === null) {
            self::$instance = new self('example', 'example', 'example', 'example');
        }

        return self::$instance;
    }

    public static function error()
    {
        echo 'database error';
        error_log('...');
        exit();
    }
}

Trying following code I don't see 'database error' on screen, and there aren't the three dots in the error log file:

<?php
include 'database.singleton.php';
$query = Database::instance()->prepare('wrong query');
$query->bind_param('si', $test, $test);
$query->execute();
$query->close();

Instead, there is the message Fatal error: Uncaught exception 'BadMethodCallException' with message 'Call to a member function bind_param() on a non-object (boolean) in the errors log file. The error is true, because the query is deliberately wrong, so $query is false, but I want to handle all mysqli errors with Database::error(). I tried to replace set_error_handler('self::error', MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); to set_error_handler('self::error'); and also set_error_handler('self::error()'); but I don't see any difference. How can I solve?

Mark
  • 55
  • 1
  • 6

1 Answers1

-1

As you can see, MySQLi use Exception (and perhaps most of the new features in PHP stop using obsolete error API and shift to Exception API). For the differents between Exception and Error you can find it here

Your example code throw an BadMethodCallException which is not caught by set_error_handler and bubble up to become a Fatal error (notice that set_error_handler cannot catch fatal error)

So the solution is using Exception and its complements: try ... catch block, or set_exception_handler.

Regards,

Community
  • 1
  • 1
Dat Pham
  • 1,765
  • 15
  • 13
  • Thank you for replying, how can I use set_exception_handler for handle ONLY mysqli exceptions? So my existing code to handle mysqli errors is completely useless? – Mark Oct 15 '15 at 10:10
  • The exception API is a hierarchy of class whose root is Exception. You can check instanceof an object passed to handler function. For only mysqli exceptions check instanceof mysqli_sql_exception class. You also can make use of your error handler, just catch Exception and throw an error and then catch it by error handler. Regards – Dat Pham Oct 15 '15 at 12:55