You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2框架project_id非空约束校验失效问题求助

Yii2框架中project_id非空约束校验失效问题解决

错误信息

Integrity constraint violation – yii\db\IntegrityException
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "project_id" violates not-null constraint
DETAIL: Failing row contains (853322, 395, 4, 2023, 5245.50, 1, null).
The SQL being executed was: INSERT INTO "db"."budget_report_by_project" ("month", "year", "category_id", "currency_id", "project_id", "value") VALUES (4, 2023, 395, 1, NULL, '5245.5') RETURNING "id"
Error Info: Array
(
    [0] => 23502
    [1] => 7
    [2] => ERROR:  null value in column "project_id" violates not-null constraint
DETAIL:  Failing row contains (853322, 395, 4, 2023, 5245.50, 1, null).
)


1. in /var/www/internal_system/vendor/yiisoft/yii2/db/Schema.php at line 676
2. in /var/www/internal_system/vendor/yiisoft/yii2/db/Command.php at line 1307– yii\db\Schema::convertException(PDOException, 'INSERT INTO "db"."budget_r...')
3. in /var/www/internal_system/vendor/yiisoft/yii2/db/Command.php at line 1168– yii\db\Command::internalExecute('INSERT INTO "db"."budget_r...')
4. in /var/www/internal_system/vendor/yiisoft/yii2/db/Command.php at line 424– yii\db\Command::queryInternal('fetch', null)
5. in /var/www/internal_system/vendor/yiisoft/yii2/db/pgsql/Schema.php at line 646– yii\db\Command::queryOne()
6. in /var/www/internal_system/vendor/yiisoft/yii2/db/ActiveRecord.php at line 604– yii\db\pgsql\Schema::insert('db.budget_report_by_projec...', ['month' => 4, 'year' => 2023, 'category_id' => 395, 'currency_id' => 1, ...])
7. in /var/www/internal_system/vendor/yiisoft/yii2/db/ActiveRecord.php at line 570– yii\db\ActiveRecord::insertInternal(null)
8. in /var/www/internal_system/vendor/yiisoft/yii2/db/BaseActiveRecord.php at line 676– yii\db\ActiveRecord::insert(true, null)
9. in /var/www/internal_system/models/BudgetReportProject.php at line 463– yii\db\BaseActiveRecord::save()

相关代码

$budgetItem->category_id = $item['category_id'];
$budgetItem->currency_id = $item['currency_id'];
$budgetItem->project_id = $item['project_id'];
$budgetItem->value = $item['value'];
if (!is_null($budgetItem->project_id))
{
    if (!$budgetItem->save())
    {
        $result['error'] = $budgetItem->getErrorMessge();
        return $result;
    }
}
unset($budgetItem);

问题说明

已添加!is_null($budgetItem->project_id)校验逻辑,期望project_id为null时跳过插入操作,但校验失效,project_id为null时仍触发数据库插入,触发非空约束报错。

解决方案

1. 替换为更严谨的判断逻辑

is_null()仅对严格的null值生效,如果$item['project_id']是空字符串''、数字0等空值,is_null()会返回false导致校验通过。根据project_id的数据类型调整判断:

// 针对字符串类型ID:排除null和空字符串
if ($budgetItem->project_id !== null && $budgetItem->project_id !== '') {
    // 执行save逻辑
}

// 针对数字类型ID:排除null和非正整数
if ($budgetItem->project_id !== null && $budgetItem->project_id > 0) {
    // 执行save逻辑
}

2. 调试确认属性真实值

在判断前添加调试代码,确认$budgetItem->project_id的实际类型和值:

$budgetItem->project_id = $item['project_id'];
// 输出真实值和类型
var_dump($budgetItem->project_id);
var_dump(gettype($budgetItem->project_id));
die;

根据输出结果调整判断逻辑,比如实际值是空字符串,就需要加入空字符串的判断。

3. 检查模型与赋值逻辑

  • 确认BudgetReportProject模型中project_id是否设置了默认值,若模型属性默认值覆盖了赋值的null值,会导致校验失效。
  • 排查代码中是否存在其他修改$budgetItem->project_id的逻辑,比如在判断前/后被二次赋值。

4. 结合模型验证增强防护

在BudgetReportProject模型的rules()方法中添加非空验证,即使前置判断失效,模型验证也会阻止插入:

public function rules()
{
    return [
        // 其他验证规则
        ['project_id', 'required', 'message' => 'project_id不能为空'],
        // 仅在插入场景验证可添加:['project_id', 'required', 'on' => 'insert'],
    ];
}

调用save()时会自动执行验证,也可以手动调用validate()提前校验:

if (!is_null($budgetItem->project_id)) {
    if (!$budgetItem->validate() || !$budgetItem->save(false)) {
        $result['error'] = $budgetItem->getErrorSummary(true);
        return $result;
    }
}

内容的提问来源于stack exchange,提问作者Mikel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 01:39:55