Jump to content

Anonymous function to get array


NotionCommotion

Recommended Posts

I have the following lines of code, and about 50 more similar ones which respond to different requests.  Many of them just pass ['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account] to the class, but some pass a couple more parameters.

$app->get('/configure', function (Request $request, Response $response) {
    $configure=new \MyApp\Configure(['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]);
    return $response->withJson($configure->get());
});

I would like to type less regarding the the array passed to the class.  While the following doesn't work, I hope it better conveys what I am trying to accomplish.

 

Any suggestions?  Thank you

$get=function($extra=[]) {
   return array_merge($extra,['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]);
};
$app->get('/configure', function (Request $request, Response $response) {
    $configure=new \MyApp\Configure($get());
    return $response->withJson($configure->get());
});
$app->get('/oneThatNeedsMore', function (Request $request, Response $response) {
    $configure=new \MyApp\Configure($get(['extra'=>123]));
    return $response->withJson($configure->foo());
});
Link to comment
Share on other sites

What is Configure? And why does it need extra parameters when it's always the same class?

 

Right now, it seems a much reasonable approach would be to pass $this (which is appearently the Slim application) and possibly other data sources like $request and $response to the class and let it decide which data is needed. If you need extra data for a specific method, use method parameters.

Link to comment
Share on other sites

What is Configure? And why does it need extra parameters when it's always the same class?

 

Right now, it seems a much reasonable approach would be to pass $this (which is appearently the Slim application) and possibly other data sources like $request and $response to the class and let it decide which data is needed. If you need extra data for a specific method, use method parameters.

 

Configure is a class to set the configuration values.  You are correct, it doesn't need any extra parameters, but I have other classes which do.

 

Yes, passing the Slim application will work, but maybe gives too much.

Link to comment
Share on other sites

I wouldn't worry about just passing $this possibly providing access to too much. So long as your target class only deals with what it needs it doesn't really matter.

 

Something you could do is create a function that returns your closure and does the parameter merging there. For example:

function Controller($controller, $extra=[]){
    return function(Request $request, Response $response){
        $params = array_merge($extra, ['logger'=>$this->logger, 'db'=>$this->db, 'account'=>$this->account]);
        $controller = new $controller($params);
        return $response->withJson($controller->get());
    };
}

$app->get('/configure', Controller(\MyApp\Configure::class));
$app->get('/oneThatNeedsMore', Controller(\MyApp\Configure::class, ['extra'=>123]));
Passing the class name would allow you to use different classes provided they all used the same structure. Alternatively you could pass an instance of a class that uses a specific interface and call a method to set the parameters / app object.

 

interface ControllerInterface {
    public function setApplication($app);
    public function setParameters($params);
    public function get(Request $request);
}

abstract class Controller implements ControllerInterface {
    protected $app;
    protected $params = [];

    public function setApplication($app){
        $this->app = $app;
    }

    public function setParams($params){
        $this->params = $params;
    }
}

class Configure extends Controller(){
    public function get(Request $request){
        $logger = $this->app->logger;
        $db = $this->app->db;
        $account = $this->app->account;
    }
}

function Controller(ControllerInterface $controller, $extra=[]){
    return function(Request $request, Response $response){
        $controller->setApplication($this);
        $controller->setParams($extra);

        return $response->withJson($controller->get($request));
    };
}

$app->get('/configure', Controller(new Configure));
$app->get('/oneThatNeedsMore', Controller(new Configure, ['extra'=>123]));
If you take some time to think about what you need to do and how to do it, you could come up with some better code based on your requirements. For example, maybe pass those extra parameters as constructor arguments instead. Maybe have the controller alias some useful services so you can just do $this->db instead of $this->app->db in your methods.
Link to comment
Share on other sites

Manual page

 

 

::class

Since PHP 5.5, the class keyword is also used for class name resolution. You can get a string containing the fully qualified name of the ClassName class by using ClassName::class. This is particularly useful with namespaced classes.

Edited by kicken
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.