What are some best practices for structuring PHP classes for database access to ensure efficient and error-free communication?

When structuring PHP classes for database access, it is important to follow best practices to ensure efficient and error-free communication. One way to achieve this is by using Object-Oriented Programming (OOP) principles such as encapsulation, inheritance, and polymorphism. By organizing your code into classes that represent database tables or entities, you can improve readability, maintainability, and reusability.

class Database {
    private $host = 'localhost';
    private $username = 'root';
    private $password = '';
    private $dbname = 'mydatabase';
    private $conn;

    public function __construct() {
        $this->conn = new mysqli($this->host, $this->username, $this->password, $this->dbname);

        if ($this->conn->connect_error) {
            die("Connection failed: " . $this->conn->connect_error);
        }
    }

    public function query($sql) {
        $result = $this->conn->query($sql);

        if (!$result) {
            die("Error in query: " . $this->conn->error);
        }

        return $result;
    }

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