Подтвердить что ты не робот

Возвращает переменную Laravel к контроллеру

Я выполняю проверку прав пользователя, чтобы определить, могут ли они просматривать страницу или нет. Это включает в себя передачу запроса через некоторое промежуточное ПО.

Проблема заключается в том, что я дублирую один и тот же запрос базы данных в промежуточном программном обеспечении и в контроллере, прежде чем возвращать данные самому представлению.

Вот пример настройки;

- routes.php

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

- 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

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

Как вы можете видеть, Page::with('users')->where('id', $id)->first() повторяется как в промежуточном программном обеспечении, так и в контроллере. Мне нужно передать данные от одного к другому, чтобы не дублировать.

4b9b3361

Ответ 1

Я считаю, что правильный способ сделать это (в Laravel 5.x) - добавить свои настраиваемые поля в свойство attribute.

Из комментариев исходного кода мы видим, что атрибуты используются для пользовательских параметров:

 /**
 * Custom parameters.
 *
 * @var \Symfony\Component\HttpFoundation\ParameterBag
 *
 * @api
 */
public $attributes;

Таким образом, вы бы реализовали это следующим образом;

$request->attributes->add(['myAttribute' => 'myValue']);

Затем вы можете получить атрибут, вызвав:

\Request::get('myAttribute');

Или из объекта запроса в laravel 5. 5+

 $request->get('myAttribute');

Ответ 2

Вместо настраиваемых параметров запроса вы можете следовать шаблону инверсии управления и использовать инъекцию зависимостей.

В вашем промежуточном программном средстве зарегистрируйте экземпляр Page:

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

Затем объявите, что вашему контроллеру нужен экземпляр Page:

class PagesController 
{
    protected $page;

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

Laravel автоматически разрешит зависимость и создаст экземпляр вашего контроллера с экземпляром Page, который вы связали в своем промежуточном программном обеспечении.

Ответ 3

В laravel> = 5 вы можете использовать $request->merge в промежуточном программном обеспечении:

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

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

    return $next($request);
}

И в контроллере:

public function index(Request $request)
{

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

Ответ 4

Я уверен, что если бы можно было передавать данные из промежуточного программного обеспечения в контроллер, это было бы в документации Laravel.

Посмотрите этот и этот, это может помочь.

Короче говоря, вы можете копировать свои данные на объект запроса, который передается промежуточному программному обеспечению. Фасад аутентификации Laravel тоже делает это.

Итак, в вашем промежуточном программном обеспечении вы можете:

$request->myAttribute = "myValue";

Ответ 5

Как упоминалось в одном из комментариев выше для laravel 5.3.x

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

Не работает. Но установка такой переменной в промежуточном программном обеспечении

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

Я мог бы извлечь данные, используя это в моем контроллере

$request->get('key');

Ответ 6

Ларавел 5.7

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

а также

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

Ответ 7

Это очень просто:

Вот код промежуточного программного обеспечения:

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

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

    return $next($request);
}

и вот код контроллера:

$request->customVar;

Ответ 8

$ request - это массив, так что мы можем просто добавить значение и ключ в массив и получить $ request с этим ключом в контроллере.

$ request ['id'] = $ id;

Ответ 9

Если на вашем сайте есть страницы 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);

}

Затем перейдите к своим 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>

Большое спасибо всем и наслаждайтесь кодом :)

Ответ 10

Я не говорю по-английски, поэтому... извините за возможные ошибки.

Для этого вы можете использовать привязку IoC. В вашем промежуточном программном обеспечении вы можете сделать это для привязки экземпляра $page:

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

После этого в контроллере вы вызываете этот экземпляр:

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

App:: instance не повторяет экземпляр класса, вместо этого возвращает экземпляр, предшествующий привязке.

Ответ 11

Я был в состоянии добавить значения к объекту запроса с:

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

и вернуть их позже с помощью:

$request->attributes->get('key');

Это возможно, потому что laravels Request расширяет запрос symfonys, имеющий атрибут " $ attribute " типа ParameterBag, предназначенный для хранения пользовательских параметров.

Я думаю, что это должна быть лучшая практика для передачи данных в последующее промежуточное ПО, контроллеры или любое другое место, где есть возможность доступа к объекту запроса.

Протестировано с Laravel 5.6, но, вероятно, также работает с другими версиями.