Published
- 2 min read
Doctrine and SQLite migrations: How to disable foreign keys in PHP 8.4
SQLite has limited capabilities for modifying tables—often, you must drop the original table and recreate it, which can break your foreign keys. PHP 8.4 provides a cool solution for that.
The problem
If you use a SQLite database in a Doctrine project and enable foreign key checks, you’ll run into an issue with table-modifying migrations: You often need to drop and fully recreate the table. If that table is referenced by others, the migration will fail unless you disable the foreign key checks. Furthermore, the entire migration runs inside a transaction, and SQLite doesn’t allow changing foreign key checks during a transaction.
The solution
There are several possible solutions, but here’s a particularly neat one made possible by PHP 8.4’s new property hooks:
final class VersionXXXXXXXXXXXXXX extends AbstractMigration
{
protected $connection {
get {
$this->connection->executeStatement('PRAGMA foreign_keys = OFF');
return $this->connection;
}
set => $this->connection = $value;
}
public function up(Schema $schema): void
{
// TODO create migration
}
public function down(Schema $schema): void
{
// TODO create migration
}
}
The code above overrides the $connection
property from the parent class with a property hook, so every time the migration system requests a connection, the foreign key checks are disabled.