DEV Community

Joël Harkes
Joël Harkes

Posted on


Make Laravel do type safe validation

Laravel has a nice validation framework, but a big catch is that it doesn't make sure your result has the right types.

here an example:

$data = ['isOk' => '1'];
$result = $this->validate($data, ['isOk' => 'boolean');

$isOkString = $result['isOk'];
$isOkBoolean = (boo;)  $result['isOk'];
if($isOkString === true){
    // wont fall here.
if($isOkBoolean === true){
    // but will go here.

wouldn't be wonderful to make sure you have no side affects.

Todo this we must create a nice interface to be able to make Rules allow to transform the result. You must subclass the Laravel Validator and extend the method: validateUsingCustomRule

interface RuleTransformsResult
    public function transformResult($attribute, $value);

class MyTypeSafeValidator extends \Illuminate\Validation\Validator {
    protected function validateUsingCustomRule($attribute, $value, $rule)
        // below is just copy pasted laravel code of method
        if (!$rule->passes($attribute, $value)) {
            $this->failedRules[$attribute][get_class($rule)] = [];

            $messages = (array) $rule->message();

            foreach ($messages as $message) {
                $this->messages->add($attribute, $this->makeReplacements(
                    $message, $attribute, get_class($rule), []

        // here is where we do our magic
        } elseif ($rule instanceof RuleTransformsResult) {
            $newValue = $rule->transformResult($attribute, $value, $result);
            if($newValue !== $value) {
                Arr::set($this->data, $attribute, $result);

Now we can write our own Boolean validator:

class ValidBoolean implements Rule, RuleTransformsResult
    public static $validValuesMap = [
        '0' => false,
        '1' => true,
        'false' => false,
        'true' => true,
        'yes' => true,
        'no' => false,

    public function passes($attribute, $value)
        if (is_bool($value)) {
            return true;

        return array_key_exists((string) $value, self::$validValuesMap);

    public function message()
        return __('validation.boolean');

    public function transformResult($attribute, $value)
        return (bool) $value;

Now we can always have a boolean as result:

$data = ['isOk' => '1'];
$result = $this->validate($data, ['isOk' => [new ValidBoolean()]);

if($result['isOk'] === true){
   // yeah we will make it here.

Top comments (0)

Timeless DEV post...

Git Concepts I Wish I Knew Years Ago

The most used technology by developers is not Javascript.

It's not Python or HTML.

It hardly even gets mentioned in interviews or listed as a pre-requisite for jobs.

I'm talking about Git and version control of course.

One does not simply learn git