Laravel 中子字符串的唯一验证

Unique validation of a substring in Laravel

我将 filenames + their extensions 存储在 files table 的 filename 列下。我的问题是,由于 只有名称存在于 $request 对象中而没有相应的扩展名 ,我无法使用唯一验证规则验证文件名而不修改输入数据第一。示例:

// . . .
$this->validate($request, [
    //   Suppose the name of uploaded file is 'file'.
    // The below rule will NEVER fail, because in the 
    // database, similar file will be stored as 'file.txt',
    // thus 'file' != 'file.txt'
    'filename' => 'unique:files'
]);
// . . .

有没有一种方法可以忽略数据库中的后缀(扩展名)来验证文件名?

您可以尝试覆盖 Request class 中的 all() 方法,并在验证之前 附加您的扩展,而不是在 之后。应该是这样的

public function all() {
    $data = parent::all();           // Get all the data in your request
    $data['filename'] .=  '.txt';    // Concatenate the file extension

    return $data;           // DONT FORGET TO RETURN THE CHANGED DATA
}

现在,您的规则将正常工作,因为它将搜索扩展名为 的文件提醒:您需要停止在您的 Controller 或任何您用来这样做的地方附加扩展,否则您将以 filename.txt.txt 结束并返回到正方形 1.

就我个人而言,我觉得随心所欲地重写 all() 方法有点麻烦,所以我有以下特点

trait SanitizeRequest {

    protected $sanitized = false;

    public function all() {
        return $this->sanitize(parent::all());
    }

    protected function sanitize(array $inputs) {
        if ($this->sanitized) return $inputs;

        foreach ($inputs as $field => $value) {
            if (method_exists($this, $field))
                $inputs[$field] = $this->$field($value);
        }
        $this->replace($inputs);
        $this->sanitized = true;
        return $inputs;
    }

}

只要我想在验证前对其进行清理,这个特性允许我编写一个带有字段名称的自定义方法。使用这种方法可以让你有这样的方法

class YourRequest extends Request {

    use SanitizeRequest;

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize() {
        return true;
    }

    ...

   protected function filename($value) {
       return $value . '.txt';
   }

}