【问题标题】:Create a Laravel Request object on the fly动态创建 Laravel 请求对象
【发布时间】:2017-03-08 20:37:18
【问题描述】:

我正在一个控制器中处理数据,并希望将其进一步传递到另一个控制器以避免重复代码。

有没有办法设置另一个控制器的store 方法中需要的请求对象?我追踪了 Request 继承,并找到了 Symfony 的 Request 对象,它有一个 request 属性,实际上是一个 ParameterBag ,它拥有一个方法 add 来向它添加带有值的参数。

我尝试了以下方法,但结果是 null

$myRequest = new Request();
$myRequest->request->add(['foo' => 'bar']);
var_dump($myRequest->foo);

我正在为这个项目使用 Laravel 5.1。

【问题讨论】:

  • 要“避免重复代码”,您需要将通用功能抽象到一个专用类中,给它一个适当的助记名称,围绕它编写一组单元测试,然后在控制器中模拟它单元测试控制器。

标签: php request laravel-5.1


【解决方案1】:

你可以使用replace():

$request = new \Illuminate\Http\Request();

$request->replace(['foo' => 'bar']);

dd($request->foo);

或者,为第二个控制器中发生的任何事情创建Job 并删除ShouldQueue 接口以使其同步运行会更有意义。

希望这会有所帮助!

【讨论】:

  • 谢谢,由于时间限制,我用一些重复的代码解决了这个问题(其他事情也必须在外部控制器中发生)。我会记住这一点!
  • 您能告诉我如何将请求方法更改为POST 吗?
【解决方案2】:

使用$myRequest = new Request(); 创建请求对象会创建使用method = 'GET' 的对象。您可以使用$myRequest->getMethod() 检查您的请求方法。 由于 request 属性保存 POST 请求的数据,因此默认情况下您不能使用 $myRequest->request->add()。首先,您必须将请求的方法设置为 POST:

$myRequest = new \Illuminate\Http\Request();
$myRequest->setMethod('POST');
$myRequest->request->add(['foo' => 'bar']);
dd($request->foo);

顺便说一句,使用$myRequest->query->add() 可以将数据添加到 GET 请求中。

【讨论】:

  • 这个很棒
【解决方案3】:

您可以使用这些方法即时添加请求参数。

替换

replace function doc

如果您在控制器中,则在函数的参数中传递请求对象,如

  function createUser(Illuminate\Http\Request $request){
     $request->replace(array_merge(array("new_key1"=>"new_value1","new_key_n"=>"new_value_n"), $request->all()));
}

合并函数

merge function doc

function createUser(Illuminate\Http\Request $request){
     $request->merge(array("new_key1"=>"new_value1","new_key_n"=>"new_value_n"));
}

添加功能

 function createUser(Illuminate\Http\Request $request){
     $request->request->add(array_merge(array("new_key1"=>"new_value1","new_key_n"=>"new_value_n"), $request->all()));
}

注意:: 在我们扩展请求的所有函数中,意味着之前的参数将保留在那里。您将添加自己的。您可以全部替换。

【讨论】:

    【解决方案4】:

    为了“避免重复代码”,您需要将通用功能抽象到一个专用类中,给它一个适当的助记名称,围绕它编写一组单元测试,然后在对控制器进行单元测试时在控制器中模拟它。

    但如果您仍然需要提出请求:

    use Illuminate\Http\Request;
    
    $request = new Request([
            'name'   => 'unit test',
            'number' => 123,
        ]);
    

    如果您需要请求的全部功能,则需要添加一些额外的行

    $request
        ->setContainer(app())
        ->setRedirector(app(\Illuminate\Routing\Redirector::class))
        ->validateResolved();
    

    【讨论】:

      【解决方案5】:

      您可以克隆现有请求并用新数据填充它:

      $request = (clone request())->replace(['foo' => 'bar']);
      

      【讨论】:

        猜你喜欢
        • 2020-10-11
        • 2019-09-21
        • 2017-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 2012-09-07
        • 1970-01-01
        相关资源
        最近更新 更多