klein/klein.php

Injecting $app, $req, $res, $services params to controllers?

Opened this issue · 6 comments

Hey,

I have a code like this:

$klein->respond(function ($request, $response, $service, $app) {
     // Bunch of stuff
});

I want to pass them into a class (not controllers) but doing this each time looks crazy.

$klein->respond(function ($req, $res, $service, $app) {
     $something = new App\Something($req, $res, $service, $app, $myParams);
});

Is there any trick or patterns to pass those values to those classes on the fly. For example, can something like this be done?

class Controller
{
     protected $req, $res, $service, $app;
     public function__construct($req, $res, $service, $app)
     {
            $this->req = $req;
            $this->res = $res;
            $this->service = $service;
            $this->app = $app;
     }
}

class HomeController extends Controller
{
     protected $myParams
     public function__construct($myParams)
     {
            $this->myParams = $myParams;
     }
}

$klein->respond(function ($req, $res, $service, $app) {
     $something = new App\HomeController($myParams);
     dd($something->req); // same as $req
});

I just want to inject $req, $res, $service, $app to my classes somehow.

Any tip would be appreciated.

Don't inject it on the class but pass it along to each action method like klein does:

class HomeController extends Controller
{
    public function homeAction($req, $resp, $service, $app)
    {
        return $resp;
    }
}

$controller = new HomeController();

$klein->respond([$controller, 'homeAction']);

That can be improved I think. Passing 4 parameters to every single method sounds pretty bad imo.

The parameters are optional if you are not going to use them then don't put
them on the method signature.
On Feb 1, 2016 2:45 PM, "Anıl ÜNAL" notifications@github.com wrote:

That can be improved I think. Passing 4 parameters to every single method
sounds pretty bad imo.


Reply to this email directly or view it on GitHub
#313 (comment).

I just want to pass them into each controller without having to all 4 variables into methods as seperate parameters. I don't enjoy passing them into methods as parameters everywhere because the app barely be maintainanle like that. That's why I asked this question in first place.

Whenever I create a controller, I want them to be injected into the class (without having to specify that myself, Klein should resolve the call itself and append the parameters automatically) so I can organize my code much easier.

Thanks for your contributions though, but that's not I'm asking for.

jk3us commented

klein includes a simple dependency injector (see $app->register in the docs). Instead of $something = new App\Something($req, $res, $service, $app, $myParams);, you could register something as a dependency:

$app->register("something", function() {
    return new App\Something($req, $res, $service, $app, $myParams);
});

Then, when you need it, you just ass $app for an instance:

$something = $app->something;

and it creates the object with the correct params injected. If you want "smarter" injection, you may want something like php-di, which can look at your classes and try to guess what to inject.

Request, Response, and Service can be pulled from within the $klein object so I just pass that to my controller or add it to a global singleton registry object.

$klein->respond('/search/[results:action]/?[i:page]?', function() use ($klein) {

	$klein->service()->layout('app/layouts/2-column.php');
	
	$control = new SearchController( $klein );
	$control->run();

});