yii 2.0.47 的 deleteall() 必须用 'and' 或 'or' 显式包裹条件数组,不可混用键值对与表达式;支持简单键值、in、运算符数组、嵌套逻辑及 not 表达式;推荐字符串+绑定参数写法并置于事务中执行。

Yii 2.0.47 中 deleteAll() 批量删除的传参方式必须严格遵循查询构建器规范,否则会直接报错(如 strtoupper() expects parameter 1 to be string, array given)。关键不是“能不能传”,而是“怎么组织参数结构”——条件数组的顶层必须是逻辑运算符,不能混用键值对和表达式。
必须用 'AND' 或 'OR' 显式包裹所有条件
即使全部是等值匹配,也不能写成扁平关联数组。Yii 2.0.47 的 deleteAll() 不支持这种写法:
- ❌ 错误示例(会崩溃):
AllAdjustments::deleteAll(['plan_year_id' => $year,'status' => 1,['NOT', ['id' => 100]],]); - ✅ 正确写法(唯一安全结构):
AllAdjustments::deleteAll(['AND',['plan_year_id' => $year],['status' => 1],['NOT', ['id' => 100]],]);
支持的子条件类型要分清
每个子条件可以是以下任意一种,但必须作为 'AND' 数组的独立元素:
- 简单键值对:
['status' => 1] - 字段 IN 数组:
['type' => [1, 2, 3]](自动转为IN) - 运算符数组:
['>', 'created_at', $time]、['BETWEEN', 'age', 18, 60] - 嵌套逻辑:
['OR', ['status' => 0], ['is_deleted' => 1]] - 否定表达式:
['NOT', ['id' => $id]]或['NOT IN', 'category_id', $list]
带命名占位符的字符串条件(更灵活的备选)
如果逻辑复杂或想避免数组嵌套,可用字符串 + 参数绑定方式:
-
AllAdjustments::deleteAll("plan_year_id = :year AND status = :status AND NOT (id = :excluded)",[':year' => $year,':status' => 1,':excluded' => 100]); - 这种写法由 Yii 自动参数化,防注入,也更容易读和调试。
务必注意变量安全性与事务
传参本身不危险,但变量来源必须可控:
-
$year、$list等应来自模型验证后或白名单过滤的数据;不要直接用$_GET或$_POST值拼进键名或运算符 -
array_keys($assocArray)要确保返回的是字符串键,否则可能引发 SQL 类型错误;可加array_map('strval', ...)防御 - 批量删除不可逆,建议包裹在事务中:
Yii::$app->db->transaction(function ($db) use ($condition) {return AllAdjustments::deleteAll($condition);});











