简体   繁体   中英

escaping Laravel validation rules

I have a user-configurable drop-down list where the user can populate it with their own list of options. I'd like to validate it with the in:foo,bar sort of validation rule.

Unfortunately, this means that some people are going to put in options like "Yes, I would". This is obviously going to break the validation if I pass an imploded list of drop-down options to the validation rule.

Is it possible to escape Laravel's rules to avoid this problem?

The Validator class makes use of PHP's str_getcsv() to parse the attributes of a rule. The process goes something like:

  • Explode all rules using the | pipe delimiter ( Validator::explodeRules() )
  • Explode the rule name and parameters using the : colon delimiter ( Validator::parseRule() )
  • Send the attributes through str_getcsv() ( Validator::parseParameters() )

This enables you to define your list of In: options the same way you would a CSV file -- with each column in quotes! Here's an example:

$input = ['foo' => 'Hello, world!'];

// Note the formatting of the `in:` options
$rules = ['foo' => 'required|in:"StackOverflow","Laravel","Hello, world!"',];

$v = Validator::make($input, $rules);

var_dump($v->passes()); // true

Also, remember that like most things Laravel, you can extend the Validator class in whatever way suits your application. If you want something more powerful, there's no need to stick with just the "stock" out-of-the-box options. :)

As Cryode says in his answer, Laravel decodes the allowed values as CSV. Here is a helper method you can use to produce this CSV-encoded string from an array of strings without worrying about manually escaping things.

<?php

class ValidatorHelper {

    /*
     * Get an "in" rule from a list of allowed strings
     *
     * @param array $allowed Array of allowed strings, unescaped
     * @return string In rule starting 'in:' with the allowed strings properly 
     * escaped
     */
    public static function inRule(array $allowed) {
        // Laravel separates options via CSV, so we can encode as CSV and not 
        // worry about quotes and commas in the options
        $fp = fopen('php://temp', 'r+');
        fputcsv($fp, $allowed);
        rewind($fp);
        $csv = fgets($fp);
        fclose($fp);
        return 'in:' . $csv;
    }

}

Use it like this:

$validator = new Validator(Input::all(), [
    'flavour' => [
        'required',
        ValidatorHelper::inRule([
            "mint choc chip",
            "rum and raisin",
            "orange, peach and pineapple",
        ]),
    ],
]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM