在 Laravel 项目的数据处理场景中,经常需要校验数据表的多列是否都不为空,同时排除部分不需要参与校验的指定列,比如自增主键、创建时间、更新时间这类自动生成的字段。如果逐个列手动判断,当列数量较多时会产生大量重复代码,维护起来也很麻烦,因此需要更高效的实现方式。

基础实现方案:循环遍历判断
最直观的方式是获取需要校验的列列表,排除指定列之后,循环判断每个列对应的值是否非空。以下是通过数组循环实现的基础示例:
<?php
namespace AppServices;
use IlluminateSupportFacadesDB;
class ColumnCheckService
{
/**
* 检查多列非空并排除指定列
* @param array $data 待校验的数据数组
* @param array $excludeColumns 需要排除的列名数组
* @return bool
*/
public function checkColumnsNotNull(array $data, array $excludeColumns = []): bool
{
// 获取所有需要校验的列,排除指定列
$checkColumns = array_diff(array_keys($data), $excludeColumns);
foreach ($checkColumns as $column) {
// 判断值是否为 null 或者空字符串
if (is_null($data[$column]) || $data[$column] === '') {
return false;
}
}
return true;
}
}
// 使用示例
$data = [
'id' => 1,
'name' => '测试用户',
'email' => 'test@ipipp.com',
'age' => 25,
'created_at' => '2024-01-01 00:00:00'
];
$service = new ColumnCheckService();
// 排除 id 和 created_at 列
$result = $service->checkColumnsNotNull($data, ['id', 'created_at']);
// 输出 true,因为剩余列都不为空
var_dump($result);
利用 Laravel 集合优化判断逻辑
Laravel 内置的集合工具提供了丰富的数组操作方法,可以简化非空判断的逻辑,减少手动循环的代码量。以下是基于集合的实现方式:
<?php
namespace AppServices;
use IlluminateSupportCollection;
class ColumnCheckService
{
/**
* 基于集合的多列非空检查
* @param array $data 待校验数据
* @param array $excludeColumns 排除列
* @return bool
*/
public function checkWithCollection(array $data, array $excludeColumns = []): bool
{
$collection = collect($data);
// 排除指定列,然后判断剩余值是否都不为空
return $collection->except($excludeColumns)->every(function ($value) {
return !is_null($value) && $value !== '';
});
}
}
// 使用示例
$data = [
'title' => '测试标题',
'content' => '测试内容',
'author_id' => 10,
'updated_at' => '2024-01-02 00:00:00'
];
$service = new ColumnCheckService();
// 排除 updated_at 列
$result = $service->checkWithCollection($data, ['updated_at']);
// 输出 true
var_dump($result);
结合模型场景的校验方案
如果是在模型保存数据时进行校验,可以结合模型的$fillable属性和校验规则来实现,避免重复定义列列表。以下是在模型层实现的示例:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateSupportFacadesValidator;
class Article extends Model
{
// 允许批量赋值的字段
protected $fillable = ['title', 'content', 'author_id', 'category_id'];
// 不需要校验的字段
protected $excludeCheckColumns = ['id', 'created_at', 'updated_at'];
/**
* 校验可填充字段非空(排除指定列)
* @param array $data 待保存的数据
* @return bool
*/
public function validateFillableColumns(array $data): bool
{
// 获取需要校验的字段:可填充字段减去排除列
$checkColumns = array_diff($this->fillable, $this->excludeCheckColumns);
$rules = [];
foreach ($checkColumns as $column) {
$rules[$column] = 'required';
}
$validator = Validator::make($data, $rules);
return !$validator->fails();
}
}
// 使用示例
$article = new Article();
$data = [
'title' => 'Laravel 教程',
'content' => '详细内容',
'author_id' => 5,
'category_id' => 3
];
$isValid = $article->validateFillableColumns($data);
// 输出 true
var_dump($isValid);
不同方案对比
以下是三种方案的适用场景和特点对比:
| 方案类型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 基础循环判断 | 简单的数据校验场景,无额外依赖 | 逻辑直观,容易理解,无额外依赖 | 代码相对冗余,灵活性较低 |
| 集合优化方案 | Laravel 项目通用场景,需要简化代码 | 代码简洁,利用框架内置工具,可读性强 | 依赖 Laravel 集合,不适合非 Laravel 环境 |
| 模型结合方案 | 模型数据保存前的校验场景 | 和模型属性联动,减少重复列定义,支持校验规则扩展 | 耦合模型属性,通用性稍弱 |
注意事项
- 非空判断需要根据业务需求调整,比如是否允许空字符串、0 是否算非空等,上述示例默认排除 null 和空字符串,可根据实际情况修改判断条件。
- 如果数据中包含数组或者对象类型的值,需要额外增加类型判断逻辑,避免误判。
- 排除列的参数建议做成可配置项,方便不同业务场景复用校验逻辑。