yii2.0.45批量删除须用deleteall()并显式包裹'and',条件结构错误会报strtoupper()参数类型错误;需转字符串防类型不匹配、加事务保障、配合gridview checkboxcolumn实现安全批量操作。

Yii2.0.45 中批量删除主要依赖 ActiveRecord::deleteAll() 方法,它直接生成 SQL DELETE 语句,不实例化模型、不触发事件和验证,性能高但需格外注意条件格式安全。该版本对查询条件结构更严格,错误写法极易引发 strtoupper() expects parameter 1 to be string, array given 报错。
以下为实际可用、经验证的配置要点:
✅ 正确声明多条件结构(必须用 'AND' 或 'OR' 包裹)
不能把键值对和运算符表达式混在同一个数组里:
// ❌ 错误:混合写法,会报错
AllAdjustments::deleteAll([
'plan_year_id' => $plan_year_id,
'column_type' => array_keys($allAdjustment),
'is_auto' => $is_auto,
['NOT', ['column_id' => 1]], // 这里破坏了数组结构
]);
应统一使用逻辑操作符作为首元素:
// ✅ 正确:显式 'AND' 封装,每个子条件独立
AllAdjustments::deleteAll([
'AND',
['plan_year_id' => $plan_year_id],
['column_type' => array_keys($allAdjustment)],
['is_auto' => $is_auto],
['NOT', ['column_id' => 1]],
]);
⚠️ 注意:即使全是等值条件,也必须加
'AND';否则 QueryBuilder 无法识别结构,直接抛出类型错误。
✅ 安全处理动态值(防 SQL 类型/注入风险)
-
array_keys($allAdjustment)返回数字键时,可能被当整型传入IN查询,导致类型不匹配。建议强制转字符串:'column_type' => array_map('strval', array_keys($allAdjustment)) 所有变量(如
$plan_year_id,$is_auto)应确保已校验或来自可信来源。Yii2 自动参数化标量值,但不防护字段名、表名或逻辑符,严禁拼接用户输入到条件键中。
✅ 加事务保障(强烈推荐)
批量删除不可逆,务必包裹事务:
$transaction = Yii::$app->db->beginTransaction();
try {
AllAdjustments::deleteAll([
'AND',
['plan_year_id' => $plan_year_id],
['column_type' => array_map('strval', array_keys($allAdjustment))],
['is_auto' => $is_auto],
['NOT', ['column_id' => 1]],
]);
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollBack();
throw $e;
}
✅ GridView 前端配合批量删除(常用场景)
后端接收选中的 ID 列表,再调用 deleteAll():
// 控制器 action
public function actionBatchDelete()
{
$ids = Yii::$app->request->post('id'); // 前端 checkbox 提交的 id 数组
if (!empty($ids)) {
$result = YourModel::deleteAll(['id' => $ids]); // 自动转为 IN 查询
Yii::$app->session->setFlash('success', "成功删除 {$result} 条记录");
}
}
前端 GridView 需配置 CheckboxColumn 和按钮:
= GridView::widget([
'options' => ['id' => 'grid'],
'columns' => [
['class' => 'yii\grid\CheckboxColumn', 'name' => 'id'],
// 其他列...
],
]); ?>
= Html::a('批量删除', ['batch-delete'], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => '确定要删除选中的记录?',
'method' => 'post',
],
]) ?>
注:Yii2.0.45 默认支持
data-method="post",无需额外 JS,但需确保 CSRF token 已启用(默认开启)。
不复杂但容易忽略。











