MySQL外键必须显式指定ON DELETE CASCADE才能触发级联删除,PHP不处理该逻辑;若未设置,需重建外键或手动分步删除并加事务保障一致性。
MySQL 外键定义时必须显式指定
PHP 本身不处理级联删除逻辑,真正起作用的是 MySQL 的外键约束行为。如果你执行
后,关联的
表数据没被删,大概率是建表时没加
。
检查现有外键是否支持级联删除:
如果
是
或
,那就不会自动删子记录。
要补上级联删除,需先删旧外键再重建(注意备份):
立即学习
“
PHP免费学习笔记(深入)
”;
PHP 中用
或
执行普通
即可触发级联
只要外键约束已正确设置,PHP 层不需要额外写逻辑。直接删主表,MySQL 自动清理子表。
例如用
删除用户:
或用
:
⚠️ 注意:事务中执行更安全,避免部分删除成功、部分失败导致数据不一致:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
开启事务:
执行主表删除
检查影响行数:
返回受影响总行数(含级联删除的子记录)
成功则
,失败则
没有外键或不能改表结构?得手动删子表再删主表
有些老项目禁用外键,或表引擎是
(不支持外键),这时只能在 PHP 里分步操作。
顺序必须是:先删子表 → 再删主表,否则会报外键约束错误:
常见坑:
漏删某个子表(比如还有
、
)
没加事务,删了一半出错,留下脏数据
用
替代
——
不触发外键级联,也不走 WHERE,还不能回滚
和
的实际区别
不是所有场景都适合
。比如用户删了,但订单历史要保留,只是把
设为空:
此时要求
字段允许
(
)。
是默认行为,删主记录前会检查子表是否存在关联行,有就直接报错:
。这时候你得自己查、自己提示、自己决定怎么处理。
级联删除看着省事,但一旦误删,恢复成本高。生产环境上线前务必确认外键行为,别只靠 PHP 代码“以为”它会自动删。
ON DELETE CASCADEDELETE FROM users WHERE id = 123ordersON DELETE CASCADESELECT
CONSTRAINT_NAME,
TABLE_NAME,
COLUMN_NAME,
REFERENCED_TABLE_NAME,
UPDATE_RULE,
DELETE_RULE
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE k
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS r
ON k.CONSTRAINT_NAME = r.CONSTRAINT_NAME
WHERE k.TABLE_SCHEMA = 'your_db_name'
AND k.TABLE_NAME = 'orders'
AND k.COLUMN_NAME = 'user_id';DELETE_RULERESTRICTNO ACTIONALTER TABLE orders DROP FOREIGN KEY fk_orders_user_id;
ALTER TABLE orders ADD CONSTRAINT fk_orders_user_id
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;mysqliPDODELETEPDO$pdo->prepare("DELETE FROM users WHERE id = ?")->execute([123]);mysqli$stmt = $mysqli->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
$id = 123;
$stmt->execute();$pdo->beginTransaction()$pdo->exec("DELETE ...")commit()rollback()MyISAM$pdo->beginTransaction();
try {
$pdo->exec("DELETE FROM orders WHERE user_id = 123");
$pdo->exec("DELETE FROM users WHERE id = 123");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollback();
throw $e;
}user_profilesaddressesTRUNCATEDELETETRUNCATEON DELETE SET NULLON DELETE RESTRICTCASCADEuser_idALTER TABLE orders
DROP FOREIGN KEY fk_orders_user_id,
ADD CONSTRAINT fk_orders_user_id
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;user_idNULLALTER TABLE orders MODIFY user_id INT NULLON DELETE RESTRICTCannot delete or update a parent row: a foreign key constraint fails