Laravel Middleware return variable to controller
I believe the correct way to do this (in Laravel 5.x) is to add your custom fields to the attributes property.
From the source code comments, we can see attributes is used for custom parameters:
/**
* Custom parameters.
*
* @var \Symfony\Component\HttpFoundation\ParameterBag
*
* @api
*/
public $attributes;
So you would implement this as follows;
$request->attributes->add(['myAttribute' => 'myValue']);
You can then retrieved the attribute by calling:
\Request::get('myAttribute');
Or from request object in laravel 5.5+
$request->get('myAttribute');
Laravel - Passing variables from Middleware to controller/route
pass key value pair like this
$route = route('routename',['id' => 1]);
or to your action
$url = action('UserController@profile', ['id' => 1]);
You can pass data the view using with
return view('demo.manage', [
'manage_link_class' => 'active',
'twilio_workspace_capability' => //how do I get the token here?...
]) -> with('token',$token);
in your middleware
public function handle($request, Closure $next)
{
$workspaceCapability = new .....
...
$request -> attributes('token' => $token);
return $next($request);
}
in your controller
return Request::get('token');
Passing variable from middleware to controllers __construct to prevent repeating myself
For reasons currently unclear to me, the controller object is constructed before the request changes are reflected in the request object. In short the request is not considered properly constructed when a controller is constructed. This post seems to imply that.
There's two ways to work around this (if for a second we ignore what you're trying to do).
Use request dependency injection
public function index(Request $request)
{
$compary = $request->attributes->get('company');
}
This is not really WET because you're just swapping $this->company
with $request->attributes->get('company')
it's just a refactor. You should be injecting the request in the controller action anyway and if you don't want to do that you can use the request()
helper.
- Use a callback middleware in the constructor (Maraboc's answer explains how)
Now if you want a more case specific solution though you can use case specific dependency injection:
If you need to bind a model to a specific route parameter you can use route model binding and add the following in your RouteServiceProvider
(or any provider).
Route::bind("companyAsARouteVarName", function () {
// this is why more details in the question are invaluable. I don't know if this is the right way for you.
//checks
// success
return $someModel;
});
Then you will register your route as:
Route::get("/something/{companyAsARouteVarName}", "SomeController@index");
and your controller will be:
public function index(Company $companyAsARouteVarName) {
//Magic
}
Passing data from controller to middleware laravel
In your middleware you are returning response (a view), so
return $next($request);
will never be executed, so neither will your controller.
User call /dashboard > Your middleware is called > if it's an admin you are returning admin.Dashboard, else member.dashboard.
But you never execute code in your Controller.
As a quick fix you could replace your Middleware by :
public function handle(Request $request, Closure $next)
{
if ($request->user() && $request->user()->role == 'admin') {
$count = User::count();
return view('admin.Dashboard', compact('count'));
}
return response()->view('member.dashboard');
}
or make those test (admin/not admin) in your controller
Laravel - How to pass variables to middleware through route group?
You can simply pass multiple arguments into the middleware using a colon. Use it like:
Route::group(['middleware' => 'checkUserLevel:some_value_of_level'], function () {
// my routes
});
Now, you can have this value inside your $level variable.
public function handle($request, Closure $next, $level)
{
$user = Auth::user();
if ($user->level > $level) {
return redirect('testUrl');
}
return $next($request);
}
This would help.
Edit: 14 Dec 2018
You can also send multiple variables to middleware. You just need to seperate the values using a comma (,).
Route::group(['middleware' => 'checkUserLevel:some_value_of_level, one_more_value_to_send'], function () {
// my routes
});
And you will get the value one_more_value_to_send
in the variable after $level
in the middleware handler.
public function handle($request, Closure $next, $level, $another_value)
{
$user = Auth::user();
if ($user->level > $level) {
return redirect('testUrl');
}
return $next($request);
}
For more details you can refer to: Passing parameters to Middleware in Laravel 5.1
Laravel 5 Pass Data from Middleware to Controller
I would flash the data to the session. When you flash data it only stays there until the next request.
In your middleware add
Session::flash('user', $user);
Don't forget to add this at the top of your middle ware
use Session;
Then whenever you need to access your user use
Session::get('user');
Here is a link to the docs for reference
http://laravel.com/docs/5.0/session#flash-data
Related Topics
Is There Any Difference Between _Dir_ and Dirname(_File_) in PHP
Is There Java Hashmap Equivalent in PHP
PHP Warning: Unknown: Failed to Open Stream
How to Make Short Random Unique Keys, Like Youtube Video Ids, in PHP
Loop Through All Months in a Date Range
How to Perform Multiple Guzzle Requests at the Same Time
Laravel Middleware with Multiple Roles
Laravel Eloquent: How to Get Only Certain Columns from Joined Tables
How to Save PHP Session Data to a Database Instead of in the File System
How to Document Magic (_Call and _Callstatic) Methods for Ides
Laravel SQLstate[Hy000] [2002] Connection Refused
How to Use Perl Libraries from PHP