Laravel 5: Calling routes internally

2020-05-28 10:18发布

问题:

Is there a way, in Laravel 5, to call routes internally/programmatically from within the application? I've found a lot of tutorials for Laravel 4, but I cannot find the information for version 5.

回答1:

Using laravel 5.5, this method worked for me:

$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);

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

*note: maybe you will have issue if the route you're trying to access has authentication middleware and you're not providing the right credentials. to avoid this, be sure to set the correct headers required so that the request is processed normally (eg Authorisation bearer ...).



回答2:

You may try something like this:

// 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:

You can actually call the controller that associates to that route instead of 'calling' the route internally.

For example:

Routes.php

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

UserController.php

class UserController extends Controller {

   public function getUser($id){

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

   };
}

Instead of calling /getUser route, you can actually call UserController@getUser instead.

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

This is the same as calling the route internally if that what you mean. Hope that helps



回答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
   }


回答5:

None of these answers worked for me: they would either not accept query parameters, or could not use the existing app() instance (needed for config & .env vars).

I want to call routes internally because I'm writing console commands to interface with my app's API.

Here's what I did that works well for me:

<?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));
    }
}

Your Controller/Route will work exactly as if you had called it using curl. Have fun!