yii2中deleteall()安全写法:单条件用关联数组,多条件须用'and'/'or'包裹,复杂sql用占位符绑定参数,并建议事务保护。

Yii2.0.49 中批量删除用 deleteAll(),关键不是版本号,而是条件写法必须规范——稍有嵌套错误就会报 strtoupper() expects parameter 1 to be string。下面直接说清楚怎么写才安全、有效。
基础语法:单条件最简写法
最常用也最不容易出错的写法是传入一个关联数组,键为字段名,值为匹配值:
User::deleteAll(['status' => User::STATUS_DELETED]);Order::deleteAll(['created_at' => $timestamp]);- 支持 IN 查询:
Article::deleteAll(['id' => [101, 102, 105]]);(自动生成IN (101,102,105))
多条件组合:必须显式用 'AND' 或 'OR' 包裹
只要涉及运算符(如 NOT、IN、BETWEEN、> 等)或多个独立条件,就不能扁平混写,必须用逻辑操作符数组开头:
- ✅ 正确(AND 组合):
Log::deleteAll([<br> 'AND',<br> ['level' => ['error', 'critical']],<br> ['created_at' => ['>=', $from]],<br> ['NOT', ['module' => null]],<br>]);
- ❌ 错误(混合写法,会报错):
Log::deleteAll([<br> 'level' => ['error', 'critical'],<br> 'created_at' => ['>=', $from],<br> ['NOT', ['module' => null]], // 这里破坏结构<br>]);
带参数绑定的字符串条件(适合复杂 SQL)
当需要手写表达式(比如范围查询、模糊匹配、函数调用),推荐用带占位符的字符串 + 参数数组方式,更直观且防注入:
Post::deleteAll('status = :status AND created_at ':status' => Post::STATUS_DRAFT,<br> ':cutoff' => date('Y-m-d H:i:s', strtotime('-30 days'))<br>]);- 支持
AND、OR、NOT、IN、BETWEEN等原生 SQL 写法,Yii 自动参数化
安全与事务建议
批量删除不可逆,生产环境务必加防护:
- 用事务包裹:
$transaction = Yii::$app->db->beginTransaction();<br>try {<br> User::deleteAll(['is_temp' => 1]);<br> $transaction->commit();<br>} catch (\Exception $e) {<br> $transaction->rollBack();<br> throw $e;<br>} - 提前校验变量类型,尤其
array_keys($arr)要确保结果是字符串数组,否则可能触发类型不匹配 - 避免拼接用户输入到字段名或操作符中,例如不要写
[$userInput => 1],只用于值部分











