Alexander Lomia Alexander Lomia - 1 year ago 66
PHP Question

Unique validation of a substring in Laravel

I am storing

filenames + their extensions
column in the
table. My problem is, that since only the name is present in the
object without it's corresponding extension
, I can't validate the filename using unique validation rule without tinkering with the input data first. Example:

// . . .
$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'
// . . .

Is there a way to validate the filename ignoring it's suffix (extension) in the database?

Answer Source

You can try to override the all() method in your Request class and append your extension before validation instead of after. That would be something like this

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

Now, your rule will work properly because it will search for the file with the extension. Reminder: You'll need to stop appending the extension in your Controller or whichever place you use to do so, otherwise you'll end up with filename.txt.txt and will be back to square 1.

Personally, I find it a little messy to override the all() method whenever I feel like it, so I have the following trait

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->sanitized = true;
        return $inputs;


This trait allows me to write a custom method with the field name whenever I want to sanitize it before validation. Using this approach allows you to have a method like this

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';