K
K
kanstantsin2015-09-11 12:42:54
PHP
kanstantsin, 2015-09-11 12:42:54

Is it a bad idea to configure classes/services with closures rather than, for example, arrays?

Many libraries have the ability to load a configuration from an array (or any configuration file). Wouldn't it be a better idea to configure the service with a closure or any other callable (Class::__invoke() for example)?
To illustrate:

class Router 
{
    public function __construct(Closure $config)
    {
        $closure($this);
    }

    public function addRoute(...$params) {
        // some code
    }
}

The configuration looks like this:
return function($router) {

    $router
        ->addRoute('/')
        ->setName('home')
    ;

    // and so on....        
}

And finally the service call:
$router = new Router(include 'config/router.php');
$controller = $router->match('/some/path');

Wouldn't it be easier than loading a static configuration and parsing this configuration already in the service, calling public methods and essentially doing the same thing?
UPD : removed the mention of frameworks so as not to be misleading. We are talking about libraries/components without external dependencies.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
C
Cat Anton, 2015-09-11
@27cm

No, not better.
Configs may need to be merged, cached, etc. In the same ZF2, the config of one module can override the values ​​of another or even global application settings. With closures, it won't be so easy.
But even if you do this, then go even further, to the end, just create an inheritor of class MyRoute extends Route , and as a result, the code will be simpler:

$router = new MyRoute();
$controller = $router->match('/some/path');

It seems to me that it is correct when the configuration file contains only settings values ​​and does not know anything about who will use these values ​​and how. In your case, it turns out that the configuration file provides a closure for setting up an object of the Router class.

T
Timofey, 2015-09-11
@mr_T

It looks good, but it's better to pass the function not to the constructor, but to some method. Then, for classes configured in this way, it will be possible to use an impurity, something like this:

trait ClosureConfigurable {
    public function configureWith(Closure $closure) {
        $closure($this);
    }
}

Thus, the constructor will not contain additional code, and the logic of the mixin can be painlessly changed and supplemented (for example, queue closures, pass additional parameters to them, make a conditional configuration, etc.).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question