php - tipos - Laravel Middleware devuelve variable al controlador



recoger datos formulario laravel (8)

Laravel 5.7

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

y

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

Estoy llevando a cabo una verificación de permisos de un usuario para determinar si puede ver una página o no. Esto implica pasar primero la solicitud a través de algún middleware.

El problema que tengo es que estoy duplicando la misma consulta de base de datos en el middleware y en el controlador antes de devolver los datos a la vista en sí.

Aquí hay un ejemplo de la configuración;

- routes.php

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

- PageUserMiddleware.php (clase 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]);
}

Como puede ver, la Page::with('users')->where('id', $id)->first() se repite tanto en el middleware como en el controlador. Necesito pasar los datos de uno a otro para no duplicarlos.


Answer #1

$ request es la matriz para que podamos agregar valor y clave a la matriz y obtener la solicitud $ con esta clave en el controlador.

$ request ['id'] = $ id;


Answer #2

Creo que la forma correcta de hacer esto (en Laravel 5.x) es agregar sus campos personalizados a la propiedad de atributos.

De los comentarios del código fuente, podemos ver que los atributos se usan para parámetros personalizados:

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

Entonces implementaría esto de la siguiente manera;

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

Luego puede recuperar el atributo llamando a:

\Request::get('myAttribute');

O del objeto de solicitud en laravel 5.5+

 $request->get('myAttribute');

Answer #3

En laravel> = 5 puede usar $request->merge en el middleware:

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

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

    return $next($request);
}

Y en el controlador:

public function index(Request $request)
{

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

Answer #4

Es muy simple:

Aquí está el código de middleware:

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

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

    return $next($request);
}

y aquí está el código del controlador:

$request->customVar;

Answer #5

Estoy seguro de que si fuera posible pasar datos de un middleware a un controlador, estaría en la documentación de Laravel.

Eche un vistazo a this y this , podría ayudar.

En resumen, puede recuperar sus datos en el objeto de solicitud que se pasa al middleware. La fachada de autenticación de Laravel también lo hace.

Entonces, en su middleware, puede tener:

$request->myAttribute = "myValue";

Answer #6

Pude agregar valores al objeto de solicitud con:

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

y recuperarlos en un momento posterior con:

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

Esto es posible porque laravels Request extiende symfonys Request que tiene el atributo " $attributes " del tipo ParameterBag que está destinado a contener parámetros personalizados .

Creo que esta debería ser la mejor práctica para pasar datos a Middleware, controladores o cualquier otro lugar donde sea posible acceder al objeto de solicitud.

Probado con Laravel 5.6 , pero probablemente también trabajando con otras versiones.


Answer #7

Si su sitio web tiene páginas cms que se obtienen de la base de datos y desea mostrar sus títulos en el bloque de encabezado y pie de página en todas las páginas de la aplicación laravel, utilice middleware. Escriba el siguiente código en su middleware:

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

}

Luego, vaya a su header.blade.php y footer.blade.php y escriba el código a continuación para agregar enlaces de páginas 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>

Muchas gracias a todos y disfruten el código :)