【问题标题】:How to validate if name is duplicate in the uploaded file?如何验证上传文件中的名称是否重复?
【发布时间】:2021-10-18 15:45:48
【问题描述】:

如果上传文件中的名称字段重复,如何显示验证消息?

<?php

namespace App\Imports;
use App\Models\Customer;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;

class CustomerImport implements ToCollection, WithHeadingRow, WithValidation
{
    public $timestamps = false;
   

    public function collection(Collection $rows)
    {
        foreach ($rows as $row) {
            
            Customer::create([
                'name'     => $row['name'],
                'address'  => $row['address'],
            ]);
             
        }
    }

    public function rules(): array
    {
        return [
            'name'      => [
                'required',
                'max:50',
                'unique:customers,name',
            ],
            'address'      => [
                'required',
                'max:50',
                'unique:customers,address',
            ]
        
        ];
    }
}

我上传的 csv 文件示例如下:名称“AAA”重复。所以我需要为文件中的重复条目显示验证错误消息。

姓名、地址

AAA,测试地址

AAA,testaddress1

BBB,地址2

现在我得到 Illuminate\Database\QueryException SQLSTATE[23000]:违反完整性约束:1062 Duplicate entry 'AAA' 错误。

我的控制器代码如下:

public function uploadFile(Request $request)
{
        $request->validate(
            ['file' => ['required', 'file', 'mimes:txt,csv']],
            ['file.required' => 'Please upload the file']
        );
        try {
            Excel::import(new CustomerImport(), $request->file('file'));
        } catch (\Maatwebsite\Excel\Validators\ValidationException $e) {
            $failures = $e->failures();
            return redirect()
                ->route('customers.upload')
                ->withErrors($failures);
        }
        return redirect()
            ->route('customers.index')
            ->with('success', __('customers.message_uploaded'));
    }

【问题讨论】:

  • 你在做这个吗? docs.laravel-excel.com/3.1/imports/…,即围绕这个逻辑添加try { ... } catch (\Maatwebsite\Excel\Validators\ValidationException $e) { ... }
  • @Tim Lewis 是的,我已经在上面的控制器中添加了它(请检查 uploadFile())
  • 有趣;我可以看到您的代码与示例代码的唯一真正区别是$row[0]$row['name'] 的用法,以及规则在public function rules() 中引用0 =&gt; ...'name' =&gt; ... 的方式。看起来ValidationException 从未被触发,但您必须深入了解原因。

标签: php laravel laravel-8 maatwebsite-excel


【解决方案1】:

您可以通过创建自定义验证规则来实现此目的。使用Maatwebsite 库的示例实现可以是:

文件:app\Rules\CsvUnique.php

namespace App\Rules;

use App\Imports\CustomerImport;
use Illuminate\Contracts\Validation\Rule;
use Maatwebsite\Excel\Facades\Excel;

class CsvUnique implements Rule
{

    public function __construct($column)
    {
        $this->column = $column;
    }

    public function passes($attribute, $value)
    {
        $data = Excel::toArray(new CustomerImport(), $value);

        $names = array_map(function($i) {
            return $i[0];
        }, array_slice($data[0],1));

        return count($names) === count(array_unique($names));
    }

    public function message()
    {
        return 'The :attribute has already been taken.';
    }
}

然后你可以像这样在你的验证逻辑中使用它:

$request->validate(
    ['file' => ['required', 'file', 'mimes:txt,csv', new CsvUnique('name')]],
    ['file.required' => 'Please upload the file']
);

注意我们将列名(在此示例中为 name)传递给自定义规则。

【讨论】:

  • 得到未定义的偏移量 0 错误。所以修改如下: $names = array_map(function($i) { return $i['name']; }, array_slice($data[0],1));但仍然遇到同样的错误
  • @Hello 我在本地机器上用你的结构在一个 CSV 文件上测试了它,它工作正常。可能是因为$data[0]。尝试在 map 之前 dd $data 看看它是否有项目 0。
猜你喜欢
  • 1970-01-01
  • 2020-08-08
  • 2011-10-31
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
  • 2013-03-13
相关资源
最近更新 更多