Laravel 5:内部调用路由

16
在Laravel 5中,是否有一种方式可以在应用程序内部/以编程方式调用路由?我找到了很多Laravel 4的教程,但是我找不到版本5的信息。

你是在问如何在应用程序内部使用自己的路由吗?例如,在控制器中获取路由的结果?这些是JSON端点吗? - Ohgodwhy
你不必这样做。你可以实例化你的控制器并调用方法。 - geckob
@Geckob 发布了正确的答案。出于好奇,你为什么需要这样做? - jfadich
将返回值嵌入到更大的返回值中作为子元素。 - vcardillo
5个回答

22
使用laravel 5.5,这个方法适用于我:
$req = Request::create('/my/url', 'POST', $params);
$res = app()->handle($req);
$responseBody = $res->getContent();
// or if you want the response to be json format  
// $responseBody = json_decode($res->getContent(), true);

来源: https://laracasts.com/discuss/channels/laravel/route-dispatch

*注意:如果您尝试访问的路由具有身份验证中间件并且未提供正确的凭据,则可能会遇到问题。 为了避免这种情况,请确保设置所需的正确标头,以便请求被正常处理(例如Authorization bearer ...)。

更新:我已经尝试过在 Laravel 8 中使用此方法,并且它可以正常工作,但是如果您使用 PHP 版本 8.0,则可能需要在此行$req = Request::create('/my/url', 'POST', $params);之前调用opcache_reset();以避免出现错误。

请参见guzzlehttp/guzzle dosn't work after update php to php 8以获取更多信息。


2
我正在尝试这种方法,但是我无法在$params下发送POST数据。 - Pranin Shakya

16

您可以尝试像这样做:

// GET Request
$request = Request::create('/some/url/1', 'GET');
$response = Route::dispatch($request);

// POST Request
$request = Request::create('/some/url/1', 'POST', Request::all());
$response = Route::dispatch($request);

3
当从Artisan命令调用时,Route::dispatch似乎不能正常工作!但是@erwan的答案在这种情况下很有效:$response = app()->handle($request); - Arno van Oordt
@ArnovanOordt 建议使用 app()->handle() 而不是 Route::dispatch(),如果您遇到一个问题,其中错误的 \Illuminate\Http\Request 实例被注入到您的中间件中,则这是解决方案。 - antriver
同意@ArnovanOordt有关从Artisan命令调用的信息。app()->handle($request)是解决方案。 - Matt Rabe

7

您可以直接调用与该路由相关联的控制器,而不是在内部“调用”路由。

例如:

Routes.php

Route::get('/getUser', 'UserController@getUser');

UserController.php

class UserController extends Controller {

   public function getUser($id){

      return \App\User::find($id);

   };
}

不必调用/getUser路由,实际上可以直接调用UserController@getUser

$ctrl = new \App\Http\Controllers\UserController();
$ctrl->getUser(1);

这与在内部“调用”路由的方式相同,如果这就是你的意思。希望这可以帮到你。

4
对于需要输入数据的路由,比如 POST 路由,这将如何运作? - vcardillo
@geckob,有什么想法吗? - vcardillo
@vcardillo 一样的事情。但是传递一些参数给函数来模拟POST请求体。 - geckob
Laravel 在调度路由时会执行许多内部操作,远不止创建控制器实例和调用方法这么简单,因此您采用这种方式可能会遇到很多问题。正确的做法是来自 @The Alpha。 - Okneloper

4
// this code based on laravel 5.8
// I tried to solve this using guzzle first . but i found guzzle cant help me while I 
//am using same port. so below is the answer
// you may pass your params and other authentication related data while calling the 
//end point
public function profile(){

//    '/api/user/1' is my api end please put your one
// 
$req = Request::create('/api/user/1', 'GET',[ // you may pass this without this array
        'HTTP_Accept' => 'application/json', 
        'Content-type' => 'application/json'
        ]);
$res = app()->handle($req);
$responseBody = json_decode($res->getContent()); // convert to json object using 
json_decode and used getcontent() for getting content from response 
return response()->json(['msg' =>$responseBody ], 200); // return json data with 
//status code 200
   }

-1
这些答案都对我没用:它们要么无法接受查询参数,要么无法使用现有的 app() 实例(需要配置和 .env 变量)。
我想要内部调用路由,因为我正在编写控制台命令来与我的应用程序 API 进行交互。
以下是我做的事情,对我非常有效:
<?php // We're using Laravel 5.3 here.

namespace App\Console;

use App\MyModel;
use App\MyOtherModel;
use App\Http\Controllers\MyController;
use Illuminate\Console\Command;

class MyCommand extends Command
{
    protected $signature = 'mycommand
                            {variable1} : First variable
                            {variable2} : Another variable';

    public function handle()
    {
        // Set any required headers. I'm spoofing an AJAX request:
        request()->headers->set('X-Requested-With', 'XMLHttpRequest');

        // Set your query data for the route:
        request()->merge([
            'variable1' => $this->argument('variable1'),
            'variable2'  => $this->argument('variable2'),
        ]);

        // Instantiate your controller and its dependencies:
        $response = (new MyController)->put(new MyModel, new MyOtherModel);

        // Do whatever you want with the response:
        var_dump($response->getStatusCode()); // 200, 404, etc.
        var_dump($response->getContent()); // Entire response body

        // See what other fun stuff you can do!:
        var_dump(get_class_methods($response));
    }
}

你的控制器/路由将会和使用curl命令调用它一样正常工作。玩得开心!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接