Current Location: Home> Latest Articles> Best practices for encapsulating mysqli::get_warnings in database driver classes

Best practices for encapsulating mysqli::get_warnings in database driver classes

gitbox 2025-05-28

1. Understand the role of mysqli::get_warnings

mysqli::get_warnings returns a chain of mysqli_warning objects containing all warnings when executing SQL statements. Use this function to capture non-fatal problems such as data truncation, data type mismatch, index failure, etc., for easy subsequent processing.

However, it is cumbersome to call this method directly, and it requires traversing the returned linked list structure. After encapsulating it into a class method, the calling process can be simplified and the warning information can be handled uniformly.


2. Basic ideas for packaging

  • Add a public method to get warning information in the database driver class.

  • This method calls mysqli::get_warnings , and iterates over the warning list, sorting all warnings into an array or string.

  • Provides formatted output for easy logging or display.

  • This method is called proactively after performing SQL operations to capture potential problems.


3. Sample code implementation

 <?php

class DatabaseDriver
{
    /** @var mysqli */
    protected $mysqli;

    public function __construct($host, $user, $password, $dbname, $port = 3306)
    {
        $this->mysqli = new mysqli($host, $user, $password, $dbname, $port);
        if ($this->mysqli->connect_errno) {
            throw new Exception("Connect failed: " . $this->mysqli->connect_error);
        }
    }

    /**
     * implement SQL Query
     *
     * @param string $sql
     * @return mysqli_result|bool
     */
    public function query(string $sql)
    {
        $result = $this->mysqli->query($sql);
        // Query后可以检查警告
        $warnings = $this->getWarnings();
        if (!empty($warnings)) {
            // You can do logging or exception handling here
            foreach ($warnings as $warning) {
                error_log("MySQL Warning [{$warning['errno']}]: {$warning['message']} (SQLSTATE: {$warning['sqlstate']})");
            }
        }
        return $result;
    }

    /**
     * Get all warning messages for the current connection
     *
     * @return array Warning message array,Each element contains errno, sqlstate, message
     */
    public function getWarnings(): array
    {
        $warnings = [];
        $warning = $this->mysqli->get_warnings();
        while ($warning) {
            $warnings[] = [
                'errno' => $warning->errno,
                'sqlstate' => $warning->sqlstate,
                'message' => $warning->message,
            ];
            $warning = $warning->next;
        }
        return $warnings;
    }

    public function close()
    {
        $this->mysqli->close();
    }
}

// Example of usage
$db = new DatabaseDriver('localhost', 'root', 'password', 'testdb');
$db->query("INSERT INTO users (id, name) VALUES (1, 'Alice')");
$db->close();


4. Key point analysis and improvement skills

4.1 Avoid repeated warnings

get_warnings returns a warning for the current connection, and may repeatedly read old warnings if they are not cleaned or used properly. Usually, warnings can be read and cleaned after each statement is executed, or if necessary, mysqli::clear_warnings() (supported by PHP 8.1+) can be called to clear the warning chain to prevent interference with subsequent operations.

4.2 Unified exception or log processing

It is recommended to return warning information in an array in the encapsulation. The calling layer can decide whether to record logs or throw exceptions according to the needs, which enhances flexibility.

4.3 Compatibility and Error Handling

Some early PHP versions have incomplete support for get_warnings . Version compatibility should be considered when encapsulating, or version checking should be used to fall back to other error handling methods.


5. Summary

Encapsulating mysqli::get_warnings in the database driver class not only improves the reusability of the code, but also facilitates the capture and handling of potential SQL execution problems. Through reasonable encapsulation and call, the robustness and debugging capabilities of the system can be greatly enhanced.

If you are designing or maintaining a database driver class, it is highly recommended to include warning capture mechanisms and combine them with log or exception mechanisms to make database operations more transparent and secure.