What are the potential pitfalls of using the Active Record pattern in PHP classes for database interactions?

One potential pitfall of using the Active Record pattern in PHP classes for database interactions is tight coupling of database logic with business logic, making it harder to test and maintain. To solve this issue, consider separating database logic into a separate data access layer.

class User {
    private $db;

    public function __construct(Database $db) {
        $this->db = $db;
    }

    public function save() {
        $query = "INSERT INTO users (name, email) VALUES (:name, :email)";
        $params = array(':name' => $this->name, ':email' => $this->email);
        $this->db->execute($query, $params);
    }
}

class Database {
    private $connection;

    public function __construct($host, $username, $password, $dbname) {
        $this->connection = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    }

    public function execute($query, $params) {
        $statement = $this->connection->prepare($query);
        $statement->execute($params);
    }
}

$db = new Database('localhost', 'root', '', 'mydatabase');
$user = new User($db);
$user->name = 'John Doe';
$user->email = 'john.doe@example.com';
$user->save();