Laravel 的表单验证 , 如何做到验证并改变 ( 转换 ) 数据 ?( 使用中间件 )

在回答社区中,我提问了这个问题 :Laravel 的表单验证 , 如何做到验证并改变 ( 转换 ) 数据 ?

最终,我找到了一种使用中间件的方法 ,这种方法比验证的同时并转换更好 。

注意 :所针对的是非路由参数 。

首先,先看看 Laravel 的 2 个中间件 :TrimStringsConvertEmptyStringsToNull

use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;

// 此中间件继承了 TrimStrings 中间件基类
class TrimStrings extends Middleware
{
    protected $except = [
        'password',
        'password_confirmation',
    ];
}

// 找到 TrimStrings 中间件基类
namespace Illuminate\Foundation\Http\Middleware;

class TrimStrings extends TransformsRequest
{
    protected $except = [
        //
    ];

    // 重要方法
    protected function transform($key, $value)
    {
        if (in_array($key, $this->except, true)) {
            return $value;
        }
        // 这里已经写的很清楚了
        return is_string($value) ? trim($value) : $value;
    }
}

ConvertEmptyStringsToNull 中间件同理,就不上代码了 。

我们完全可以模仿这个中间件的写法,构造我们自己的中间件,去做一些参数的 “ 预转换 ” ,下面上代码 :

class ConvertNumericStringsToInt extends TransformsRequest
{
    /**
     * The attributes that should not be trimmed.
     *
     * @var array
     */
    protected $except = [
        //
    ];

    /**
     * Transform the given value.
     *
     * @param  string $key
     * @param  mixed $value
     * @return mixed
     */
    protected function transform($key, $value)
    {

        $transform = false;
        if ($key === 'id') {

            // 参数为 id
            $transform = true;
        } else if (1 === preg_match('/^[a-zA-Z][0-9a-zA-Z]*_id$/', $key)) {

            // 参数为 *_id
            $transform = true;
        } else if (1 === preg_match('/^[a-zA-Z][0-9a-zA-Z]*Id$/', $key)) {

            // 参数为 *Id
            $transform = true;
        }

        if ($transform) {

            if (!is_numeric($value)) {

                // 我自己做的处理,会直接抛出异常,不会再向下进行
                return responseJsonOfFailure([], 4444, $key . '参数必须是整数');
            }

            return is_numeric($value) ? intval($value) : $value;
        }

        // 返回原值
        return $value;
    }
}

我在这个中间件中处理所有名称中有 id 的参数 ,如果参数符合并且不是数字就抛出异常 ,如果参数符合并且是数字( 此时还是字符串 ) 就强转为 int 类型 ,之后程序中就不用做任何强转了。

同理很多情况下,我们如果想对参数做任何的预处理,都可以使用这种方法 ,我们可以根据实际情况,决定如何设置这些 “ 参数预转换中间件 ” 的作用域范围 。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

哈哈,我也遇到过这个问题,一直也没想过怎么解决,感觉大佬了,不知道为什么其他人没遇到过吗?

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!