Laravel dependency injection from middleware to form request

I have a multi language site and I’d like to inject the language list from the language middleware to the form request. As far as I can tell there is a service container which could be used for this purpose, but it is based on the class of the value, while here I just want to inject an array of Language models or stdClass if it comes from cache. Is there a way to inject an array from the middleware to a controller or form request?

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>namespace AppHttpMiddleware;
use AppModelsLanguage;
use Closure;
use IlluminateHttpRequest;
use IlluminateSupportFacadesApp;
use IlluminateSupportFacadesCache;
use IlluminateSupportFacadesRequest as FacadesRequest;
use IlluminateSupportFacadesURL;
use IlluminateSupportFacadesView;
use SymfonyComponentHttpFoundationResponse;
class SetUrlLanguage
{
public function handle(Request $request, Closure $next): Response
{
if (Cache::has('locales'))
$locales = collect(json_decode(Cache::get('locales')));
else {
$locales = Language::all();
Cache::add('locales', $locales->toJson());
}
$locales = $locales->keyBy('code');
$codes = $locales->keys()->toArray();
$code = FacadesRequest::segment(1);
if (!in_array($code, $codes))
abort(404);
URL::defaults([
'locale' => $code
]);
View::share('locales', $locales);
View::share('selectedLocale', $locales->get($code));
if (App::getLocale() !== $code)
App::setLocale($code);
return $next($request);
}
}
</code>
<code>namespace AppHttpMiddleware; use AppModelsLanguage; use Closure; use IlluminateHttpRequest; use IlluminateSupportFacadesApp; use IlluminateSupportFacadesCache; use IlluminateSupportFacadesRequest as FacadesRequest; use IlluminateSupportFacadesURL; use IlluminateSupportFacadesView; use SymfonyComponentHttpFoundationResponse; class SetUrlLanguage { public function handle(Request $request, Closure $next): Response { if (Cache::has('locales')) $locales = collect(json_decode(Cache::get('locales'))); else { $locales = Language::all(); Cache::add('locales', $locales->toJson()); } $locales = $locales->keyBy('code'); $codes = $locales->keys()->toArray(); $code = FacadesRequest::segment(1); if (!in_array($code, $codes)) abort(404); URL::defaults([ 'locale' => $code ]); View::share('locales', $locales); View::share('selectedLocale', $locales->get($code)); if (App::getLocale() !== $code) App::setLocale($code); return $next($request); } } </code>
namespace AppHttpMiddleware;

use AppModelsLanguage;
use Closure;
use IlluminateHttpRequest;
use IlluminateSupportFacadesApp;
use IlluminateSupportFacadesCache;
use IlluminateSupportFacadesRequest as FacadesRequest;
use IlluminateSupportFacadesURL;
use IlluminateSupportFacadesView;
use SymfonyComponentHttpFoundationResponse;

class SetUrlLanguage
{
    public function handle(Request $request, Closure $next): Response
    {
        if (Cache::has('locales'))
            $locales = collect(json_decode(Cache::get('locales')));
        else {
            $locales = Language::all();
            Cache::add('locales', $locales->toJson());
        }
        $locales = $locales->keyBy('code');
        $codes = $locales->keys()->toArray();
        $code = FacadesRequest::segment(1);
        if (!in_array($code, $codes))
            abort(404);
        URL::defaults([
            'locale' => $code
        ]);
        View::share('locales', $locales);
        View::share('selectedLocale', $locales->get($code));
        if (App::getLocale() !== $code)
            App::setLocale($code);
        return $next($request);
    }
}

edit:

Solved it with the Config facade for now, but I am curious what is the best way to do this.

3

There are so many way through which you can do this. But 1st I want draw your attention to

Why using Config::set(...) is not the best approach ?

  1. When you use Config::set('locales', $locales); & Config::set('selectedLocale', $locales->get($code)) , It only temporarily sets a configuration value in memory for the current request lifecycle.So basically during each request-lifecycle you set a configuration value, that may involve additional overhead.
  2. Laravel caches configuration files for performance in production environments using the php artisan config:cache command. Changes made to configuration values at runtime (e.g., using Config::set()) might not be reflected in the cached configuration.
  3. When you use this approach it is not well-scoped to the request passing through the SetUrlLanguage middleware though you have set the value of the Config in the middleware if other parts of the application are also trying to set or get configuration values, this can make your application harder to debug.

So I think to implement the best approach and as well as to get rid of all the issue I mentioned above you need to use request-object to do the same like this.

In your middleware do this..

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>public function handle(Request $request, Closure $next): Response
{
....//Do your other works//....
// Injecting array into the request
$languages = ['locales' => $locales, 'selectedLocale' => $locales->get($code)];
$request->merge(['data' => $languages]);
return $next($request);
}
</code>
<code>public function handle(Request $request, Closure $next): Response { ....//Do your other works//.... // Injecting array into the request $languages = ['locales' => $locales, 'selectedLocale' => $locales->get($code)]; $request->merge(['data' => $languages]); return $next($request); } </code>
public function handle(Request $request, Closure $next): Response
{
  ....//Do your other works//....
  // Injecting array into the request
  $languages = ['locales' => $locales, 'selectedLocale' => $locales->get($code)];
  $request->merge(['data' => $languages]);

  return $next($request);
}

You can access the injected array in the controller using the Request object.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>public function index(Request $request)
{
$data = $request->input('data');
//$data is now the array injected by the middleware
}
</code>
<code>public function index(Request $request) { $data = $request->input('data'); //$data is now the array injected by the middleware } </code>
public function index(Request $request)
{
    $data = $request->input('data');
    //$data is now the array injected by the middleware
}

If you’re using a form request, you can access the array the same way.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>class CustomFormRequest extends FormRequest
{
public function rules()
{
//Accessing the array in form request
$data = $this->input('data');
}
}
</code>
<code>class CustomFormRequest extends FormRequest { public function rules() { //Accessing the array in form request $data = $this->input('data'); } } </code>
class CustomFormRequest extends FormRequest
{
    public function rules()
    {
        //Accessing the array in form request
        $data = $this->input('data');
    }
}

N:B :-

  1. Injecting the array into the Request object using $request->merge() in the middleware is clean, and scoped to a single request.
  2. Other approches includes using session & Laravel’s Service Container Binding that you have also mentioned in your question. But in this particular scenario I think the above procedure is best suited as per the condition you mentioned.
  3. Please also add laravel tag to your question since this particular question focuses on laravel and it’s core feature as a whole rather than it’s specific version. Even before the release of laravel-11 all the features discussed here in the Q&A already existed in the other versions.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật