Laravel 10.x在到达控制器之前将查询参数转换为正确的类型

nfs0ujit  于 2023-10-22  发布在  其他
关注(0)|答案(5)|浏览(99)

我有一个GET端点,它接受一个布尔值active和一个整数ID作为查询参数。比如GET /stuff?active=1&ID=10
这两个参数都不是必需的。
如果我执行GET /stuff?active=1,并尝试通过执行$request->get('active')Request中检索值,我将获得1作为字符串的值。
如果启用了declare(strict_types=1),并且在服务(如

public function getBy(bool $active = null) {
   ...
}

Controller中调用该方法,

$controllerMethod->getBy($request->get('active'))

会导致Argument #0 ($active) must be of type ?bool, string given,这显然是不好的。
我的问题是是否有办法在请求参数到达Controller之前对其进行强制转换?也许在FormRequest类以某种方式?
我很清楚我可以在Controller中做$request->has('active') ? $request->get('active') : null,但这只是额外的混乱,我想搬到其他地方。

hmmo2u0o

hmmo2u0o1#

将其外包给 FormRequest 类应使用以下任一项:

/**
 * Handle a passed validation attempt.
 */
protected function passedValidation(): void
{
    $this->replace(['active' => (bool)$this->active]);
}

或者甚至在内部验证之前执行相同的操作:

protected function prepareForValidation(): void

文件

cgvd09ve

cgvd09ve2#

1路(吸气剂)

<?php

declare(strict_types=1);

/**
 * @property-read ?string $active
 */
class MyRequest extends \Illuminate\Foundation\Http\FormRequest
{
    public function rules(): array
    {
        // TODO: implement it
    }

    public function getActive(): bool 
    {
        return (bool)$this->query('active');
    }
}

// $controllerMethod->getBy($request->getActive());

2路(覆盖)

<?php

declare(strict_types=1);

/**
 * @property-read bool $active
 */
class MyRequest extends \Illuminate\Foundation\Http\FormRequest
{
    public function rules(): array
    {
        // TODO: implement it
    }

    /**
     * @inheritDoc
     */
    protected function prepareForValidation(): void
    {
        $this->merge([
            'active' => (bool)$this->query('active'),
        ]);
    }
}

// $controllerMethod->getBy($request->active);
gopyfrb3

gopyfrb33#

使用mergeIfMissing
您可以创建自己的自定义中间件,并将下面的内容放入其中,或者在Controller的构造函数中调用下面的内容(取决于您的设计)

$request->mergeIfMissing(['active' => null /* or false */, 'ID' => -1]);
9rbhqvlz

9rbhqvlz4#

好吧,我们都同意查询参数是字符串!
您可以做的事情:

getBy(Request $request){

   $request->boolean('active') // method returns true for 1, "1", true, "true", "on", and "yes". All other values will return false

}
vx6bjr1n

vx6bjr1n5#

你可以为此创建一个middleware并尝试重新设置参数:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class CastAtiveToBool
{
    public function handle(Request $request, Closure $next): Response
    {

        $is_active = null;
        if ($request->get('active') === 1) {
            $is_active = true;
        } elseif ($request->get('active') === 0) {
            $is_active = false;
        }

        $request->merge(['active' => $is_active]);

        return $next($request);
    }
}

相关问题