slimphp / Slim

Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
http://slimframework.com
MIT License
11.98k stars 1.95k forks source link

Container Information can not be access in custom classes #1510

Closed ghost closed 9 years ago

ghost commented 9 years ago

For example not everyone wants all classes to be in a Container, i think most people will put in the ones that are commonly used like "view", "log", "db" ...

So not everyone will want to define and pass container instance into the class: $container['Action'] = function ($container) { return new Action($container); };

What if class is autoloaded and i just wanna do: $app->get('/', 'Action:dispatch'); In this aproache without above definition container does not get avaible inside custom class ...

FILE: CallableResolver.php CHANGE: $resolved = [new $class($this->container), $method];

silentworks commented 9 years ago

I think this is up to the developer, we don't want to be passing around the container as this is classed as bad design. If you require this for your own application, you should probably replace the Resolver inside of the Container with your own implementation.

akrabat commented 9 years ago

I agree with @silentworks.

ghost commented 9 years ago

Hmmm ... Route -> Function ... container is available inside the function so it is passed inside also. How come this is not bad design ?

$app->get('/foo', function ($req, $res, $args) { $container = $this->getContainer(); $myService = $container->get('myService');

return $res;

});

Another issue is that CallableResolver is defined as Final class and can not be overwritten ... already tryed ;)

silentworks commented 9 years ago

@xMolchy almost all classes in the framework can be replaced and CallableResolver is one of them. Using the service inside of a closure would almost be the only way of getting an service inside of the closure, you can't inject dependencies into an closure unless you want to write some non-performant code.

You can replace using the code below:

$container = Slim\Container();
$container['callableResolver'] = function ($c) {
    return new MyOwnCallableResolver($c);
}

$app = new Slim\App($container);
akrabat commented 9 years ago

To follow up, CallableResolver is final as solely implements CallableResolverInterface as suggested by https://ocramius.github.io/blog/when-to-declare-classes-final/

ghost commented 9 years ago

I understand why is final no issues there ... but why allow passing container into functions of the route but not the class-es ? explanation why is bad design ?

Ty for: $container['callableResolver'] = function ($c) { return new MyOwnCallableResolver($c); }

;) did not know can do that ... can i use the same for "Route" to extend some chain functions ... for example route validation also which container i wish to pass into specified routes (depands which application what needs) ?

Ty already extended personal knowledge ;)

akrabat commented 9 years ago

Mainly because there's no way to inject dependencies into a closure.

akrabat commented 9 years ago

Oh, and for the record, we're totally happy to have our decisions questioned.

silentworks commented 9 years ago

@xMolchy its bad design because we have no idea of the requirements of each Class at that point, we are also giving the caller(Class) access to everything inside of the container even if it doesn't need them. There are also issues our IDE will have to deal with if we needed to deal with any refactoring as we would be working with strings inside of our Classes and not actual object references.

Yes you can do the same with the Router which creates the Route.

ghost commented 9 years ago

@akrabat Ty for the information. Above information already allows me to do some custom things which are needed, but do not want to change slim core files within Slim ... normally overwrite or extend.

Discussion are always needed in any project, more minds know more ...

@silentworks I understand, it is very hard to make an framework to satisfy everyone's needs, that's why i like Slim ;) its Slim and i put needed things myself. You can not fully support object references for refactoring in IDE ... new [$class, $function] does not help ;) . My plan is to extend "Route" with chain function that i can specify which container i wish to pass into the specific route (Api, Web, Soap have different needs) and then CallableResolver change that i have access to specified container so i can do MVC/HMVC structure and perform this inside Controller classes $this->view = $container->get('view'), database, logs, ....

Ty and great work on Slim!