php Laravel 中间件将变量返回给控制器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30212390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:37:30  来源:igfitidea点击:

Laravel Middleware return variable to controller

phplaravellaravel-5laravel-middleware

提问by Alex

I am carrying out a permissions check on a user to determine whether they can view a page or not. This involves passing the request through some middleware first.

我正在对用户进行权限检查,以确定他们是否可以查看页面。这涉及首先通过一些中间件传递请求。

The problem I have is I am duplicating the same database query in the middleware and in the controller before returning the data to the view itself.

我遇到的问题是,在将数据返回到视图本身之前,我在中间件和控制器中复制了相同的数据库查询。

Here is an example of the setup;

这是设置示例;

-- routes.php

-- 路由.php

Route::get('pages/{id}', [
   'as' => 'pages',
   'middleware' => 'pageUser'
   'uses' => 'PagesController@view'
]);

-- PageUserMiddleware.php (class PageUserMiddleware)

-- PageUserMiddleware.php(PageUserMiddleware 类)

public function handle($request, Closure $next)
    {
        //get the page
        $pageId = $request->route('id');
        //find the page with users
        $page = Page::with('users')->where('id', $pageId)->first();
        //check if the logged in user exists for the page
        if(!$page->users()->wherePivot('user_id', Auth::user()->id)->exists()) {
            //redirect them if they don't exist
            return redirect()->route('redirectRoute');
        }
        return $next($request);
    }

-- PagesController.php

-- 页面控制器.php

public function view($id)
{
    $page = Page::with('users')->where('id', $id)->first();
    return view('pages.view', ['page' => $page]);
}

As you can see, the Page::with('users')->where('id', $id)->first()is repeated in both the middleware and controller. I need to pass the data through from one to the other so an not to duplicate.

如您所见,Page::with('users')->where('id', $id)->first()中间件和控制器中都重复了 。我需要将数据从一个传递到另一个,以免重复。

回答by Gaz_Edge

I believe the correct way to do this (in Laravel 5.x) is to add your custom fields to the attributes property.

我相信这样做的正确方法(在 Laravel 5.x 中)是将您的自定义字段添加到 attributes 属性中。

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+

或者来自 laravel 5.5+ 中的请求对象

 $request->get('myAttribute');

回答by crishoj

Instead of custom request parameters, you can follow the inversion-of-control pattern and use dependency injection.

除了自定义请求参数,您还可以遵循控制反转模式并使用依赖项注入。

In your middleware, register your Pageinstance:

在您的中间件中,注册您的Page实例:

app()->instance(Page::class, $page);

app()->instance(Page::class, $page);

Then declare that your controller needs a Pageinstance:

然后声明你的控制器需要一个Page实例:

class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}

Laravel will automatically resolve the dependency and instantiate your controller with the Pageinstance that you bound in your middleware.

Laravel 将自动解决依赖关系并使用Page您在中间件中绑定的实例实例化您的控制器。

回答by Vinicius

In laravel >= 5 you can use $request->mergein the middleware:

在 laravel >= 5 中,您可以$request->merge在中间件中使用:

public function handle($request, Closure $next)
{

    $request->merge(array("myVar" => "1234"));

    return $next($request);
}

And in the controller:

在控制器中:

public function index(Request $request)
{

    $myVar = $request->instance()->query('myVar');
    ...
}

回答by Илья Зеленько

Laravel 5.7

Laravel 5.7

// in Middleware register instance
app()->instance('myObj', $myObj);

and

// to get in controller just use the resolve helper
$myObj = resolve('myObj');

回答by Tariq Khan

As mentioned in one of the comments above for laravel 5.3.x

正如上面对 laravel 5.3.x 的评论之一所述

$request->attributes->add(['key => 'value'] ); 

Doesn't work. But setting the variable like this in the middleware works

不起作用。但是在中间件中设置这样的变量是有效的

$request->attributes->set('key', 'value');

I could fetch the data using this in my controller

我可以在我的控制器中使用它来获取数据

$request->get('key');

回答by Noman Ur Rehman

I am sure if it was possible to pass data from a middleware to a controller then it would be in the Laravel documentation.

我确信是否可以将数据从中间件传递到控制器,那么它会在 Laravel 文档中。

Have a look at thisand this, it might help.

看看这个这个,它可能会有所帮助。

In short, you can piggy back your data on the request object which is being passed to the middleware. The Laravel authentication facade does that too.

简而言之,您可以在传递给中间件的请求对象上搭载您的数据。Laravel 身份验证外观也可以做到这一点。

So, in your middleware, you can have:

因此,在您的中间件中,您可以拥有:

$request->myAttribute = "myValue";

回答by Ashfaq Muhammad

It is very simple:

这很简单:

Here is middleware code:

下面是中间件代码:

public function handle($request, Closure $next)
{

    $request->merge(array("customVar" => "abcde"));

    return $next($request);
}

and here is controller code:

这是控制器代码:

$request->customVar;

回答by Kamlesh

If your website has cms pages which are being fetched from database and want to show their titles in the header and footer block on all pages of laravel application then use middleware. Write below code in your middleware:

如果您的网站有从数据库中获取的 cms 页面,并希望在 Laravel 应用程序的所有页面的页眉和页脚块中显示它们的标题,请使用中间件。在中间件中编写以下代码:

namespace App\Http\Middleware;

use Closure;

use Illuminate\Support\Facades\DB;

public function handle($request, Closure $next)
{    

$data = DB::table('pages')->select('pages.id','pages.title')->where('pages.status', '1')->get();

\Illuminate\Support\Facades\View::share('cms_pages', $data);

return $next($request);

}

Then goto your header.blade.php and footer.blade.php and write below code to add links of cms pages:

然后转到您的 header.blade.php 和 footer.blade.php 并编写以下代码以添加 cms 页面的链接:

<a href="{{ url('/') }}">Home</a> | 

@foreach ($cms_pages as $page) 

<a href="{{ url('page/show/'.$page->id) }}">{{ $page->title }}</a> | 

@endforeach

<a href="{{ url('contactus') }}">Contact Us</a>

Thanks a lot to all and enjoy the code :)

非常感谢所有人并享受代码:)

回答by Carlos Porter

i don't speak english, so... sorry for possible errors.

我不会说英语,所以......对可能的错误感到抱歉。

You can use the IoC binding for this. In your middleware you can do this for binding $page instance:

您可以为此使用 IoC 绑定。在您的中间件中,您可以执行此操作来绑定 $page 实例:

\App::instance('mi_page_var', $page);

After, in your controller you call that instance:

之后,在您的控制器中调用该实例:

$page = \App::make('mi_page_var');

The App::instance not re-instance the class, instead return the instance previusly binding.

App::instance 不会重新实例化该类,而是返回先前绑定的实例。

回答by Durgesh Pandey

$requestis the array so that we can just add value and key to the array and get the $requestwith this key in the controller.

$request是数组,以便我们可以将值和键添加到数组中,并$request在控制器中使用此键获取。

$request['id'] = $id;

$request['id'] = $id;