-
Notifications
You must be signed in to change notification settings - Fork 2.6k
[ZF3] [RFC] Removal of get([A-Z][A-Za-z]+)Config
methods from modules
#5288
Comments
I'm all for this. 👍 |
Discussed this with @Ocramius in #zftalk and I am 👍. This would also simplify training (or new developer learning curve in general) around these concepts. |
|
else 👍 |
How about |
|
Sounds nice. @akrabat I doubt you'll ever see that resolved. From my personal experience, a single feature I wrote yesterday required 15 factories depending on each other. It's just much quicker to write closures than to write separate files with factory classes. There's also the benefit of navigation (I can easily see all my 3-5 line factories at a glance, as opposed to opening each separate file). (of course a proper DIC and build would solve it all, but I digress). The only drawback, (per @akrabat ) I see, is moving again in the direction of arrays-of-arrays-of-arrays which emulate duck-typing, instead of feature-based loading, interfaces and OOP structures. For example, explaining "in order to add view helper, define getViewHelperConfig() method" you'd be saying "shove it into that big getSomethingConfig() method, but watch out, don't confuse it with getConfig() method". Whatcha say professor @EvanDotPro ? :-) I'd vote for either |
For the sake of sanity, I would probably suggest something like... public function getUncachableConfig()
{
return array(
'service_manager' => $this->getServiceConfig(),
'view_helpers' => $this->getViewHelperConfig(),
// etc
);
} Which could also produce a backwards-compatible module.
In my eyes, this is not the purpose. I see nothing wrong with closures and direct services being registered directly in the module class, especially in very, very simple cases like EdpMarkdown. Personally, I think doing it this way simply makes it easier to understand how and why it works the way it does. Right now, you see a lot of people defining things like invokables, etc in |
@Thinkscape yes, I agree about it being easier to explain. As I mentioned to @Ocramius on IRC:
|
@Thinkscape Yes - I'm not a fan of creating a factory classes for a 3 line method either, so do the same as you and am happy with that. I like @EvanDotPro's idea of |
I haven't formulated a final opinion yet, but I'm currently leaning towards something like While not as "fancy" sounding as the alternatives, |
It should be I don't especially like |
I don't think that the size of public function getConfig() // works also for getUnCacheableConfig
{
return [
'service_manager' => require __DIR__ . '/../../config/service_manager.config.php',
'view_gelper' => require __DIR__ . '/../../config/view_helpers.config.php',
// ...
];
} Just a note on the method naming: please suggest something that is easy to understand.
|
Possible questions:
I'd hope to have a name that is more about the semantics and architecture than what the MM is going to do with it later (caching, serialization etc. should not be part of module definition). |
@Thinkscape yes,
No. |
Marco, I know answers to those questions, I'm pointing out the ambiguity of the name and possible questions that such method name could raise :-) |
@Thinkscape got it. Yes, I don't have better names so far. |
Calling it the uncacheable config isn't unreasonable as the only reason that it exists is that getConfig() cannot have closures in it's returned array. |
@akrabat yes, that's the main reason for it to exist (and it's the same reason for the |
I'm for removing completely those in ZF3, for the only reason that it allows us to remove this crap. By the way, still no zf3 branch/repo ? :( |
@bakura10 this empty repo ? https://github.com/zendframework/zf3 |
We could always reverse it, so |
@samsonasik , this repo has been here for months. But still empty for months too :). |
Changing meaning of an existing method would be a no-go. That's much more of a BC in my opinion. Think carefully and look for a better name first. @bakura10 I'm still against a separate repo for zf3, but this is not the thread for it. Focus on the issue, please |
I think everyone is against a seperate repo for zf3 |
You're right.. however it doesn't give me much more hint than existing Current contenders public function getConfig();
public function getRuntimeConfig();
public function getDynamicConfig();
public function getCachedConfig();
public function getUncachedConfig();
public function getCacheableConfig();
public function getUncacheableConfig();
public function getUnCacheableConfig(); |
@Ocramius If you consider we won't be using serialized closures, |
@Thinkscape super_closure is an experimental project. I wouldn't use it anyway ;) Dynamic can do for me as well. I just hope people don't abuse it =D |
You mean removing it completely without a
I was put in charge of starting this, but it created a large debate on how it should be handled (branch, vs separate repo, etc), and there was no consensus reached, so I postponed the new repo for now. We'll kick it off soon, but in the meantime, the WIP/RFC issues and PR's here in the ZF2 repo are working perfectly fine.
Definitely 👎 from me on this, sorry. I'm also still 👎 for |
No Evan, I want the getUncacheable thing. I ust want to remove all the various getXXXConfig and just keep two ones. |
@Ocramius Wouldn't that config be written without the ['report_timespan' => ['start' => '-1 month', 'end' => '+1 month']] |
@texdc good point - I will need to think about that! |
Like with the datetime example, keep in mind that many of those cases should be handled by callables (i.e. instances created on-demand of validators, services etc.). Similar to the diff between |
@EvanDotPro maybe this should be split out then ? There's a difference between uncacheable config, cacheable config and not-a-config :-) This would give us 3 concerns instead of 2. We could also think about calling it |
It's not just about services. Anything not cacheable would fall in here. |
|
I raise on |
getBearConfig() |
getConfigThatCantBeCachedBecauseItsProbablyAClosure() On Fri, Oct 25, 2013 at 9:21 AM, Artur Bodera notifications@github.comwrote:
|
What if you avoided this completely, by using an event listener, as we do for bootstrapping (onBootstrap). If you want to use closures (or anything else that cannot be cached), you would implement the ConfigListenerInterface (onConfigLoaded). This would be triggered by the module manager and passed the merged (and usually cached) configuration. From here you could make additional contributions to the configuration object as necessary. |
What about getPostCacheConfig() ? |
@mschindler83 very confusing for web developers... |
We already have an event for that, actually. However, it should not be used for this purpose, as any configuration provided via such a listener will not be overridden by global/local autoload configuration. IMO the global/local config files need to always the be "winners" of the entire merging process. The primary use-case for the existing event is unsetting config keys that are defaulted by vendor modules (removing ZfcUser's routes for example), though I've seen a few other uses such as token processing, etc. |
We had a discussion at ZCEU about this: I've explained my proposal of split cacheable and not cacheable config values iterating over the merged config and then store each one in the best storage possible (cacheable things in opcode caches and not cacheable things in a PHP file written in disk) @Ocramius Notice the problem with the closures context ( So we think that in source of the question config should be static values and there are no options for non cacheable things beeing the correct way for that use cases write a service with the aim of generate a dynamic config from static parameters (ServiceA inject ServiceAConfig) We could add a trigger_error warning for non cacheable values so the user could be noticed when are not making a config in the correct way. If I forgive something of our discussion please comment. /cc @Ocramius @EvanDotPro @akrabat |
No, that pretty much sums it up. Current solutions:
The example with a special config key doesn't work at all anyway. Right now I'd just suggest dropping all those |
👍 |
I wrote down the conclusions of the brainstorming I had with @Maks3w as well as what has been discussed here. That's what I'm gonna implement, so please read now or forget about it later on :-) |
👍 |
This issue has been closed as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html |
This is an RFC for a simplification that would help a lot in building ZF applications considering non-cacheable configurations.
Problem
Some configurations rely on closures, service instances and generally non-serializable data that may break the application when config is merged and then cached
Current solution (ZF2)
In order to solve the problem, ZF2 introduced a series of interfaces that allow developers can implement in their
Module
classes to add configured services programmatically:Zend\ModuleManager\Feature\ControllerPluginProviderInterface
Zend\ModuleManager\Feature\ControllerProviderInterface
Zend\ModuleManager\Feature\FilterProviderInterface
Zend\ModuleManager\Feature\FormElementProviderInterface
Zend\ModuleManager\Feature\HydratorProviderInterface
Zend\ModuleManager\Feature\InputFilterProviderInterface
Zend\ModuleManager\Feature\RouteProviderInterface
Zend\ModuleManager\Feature\SerializerProviderInterface
Zend\ModuleManager\Feature\ServiceProviderInterface
Zend\ModuleManager\Feature\ValidatorProviderInterface
Zend\ModuleManager\Feature\ViewHelperProviderInterface
These configurations basically merge data to the already merged config AFTER it is cached. They all act in the same way, just with different naming and providing different config keys. That's a lot of duplicated code, triggered events and inconsistencies. Additionally, we never suggest usage of those methods if not strictly needed, which makes their existence very confusing for those who don't know that.
Suggestion (ZF3)
I hereby suggest removing (deprecating?) all the interfaces mentioned above, and instead introduce something like
Zend\ModuleManager\Feature\UnCacheableConfigProviderInterface
(suggestions on the name, please!):Bonus
With this approach, we can also get rid of
Zend\ModuleManager\Feature\LocatorRegisteredInterface
, which allows us to have modules likeEdpMarkdown
register the module as a service:Benefits
get([A-Z][A-Za-z]+)Config
methodsZend\ModuleManager\Feature\LocatorRegisteredInterface
getUnCacheableConfig
does. The name says it for itselfZF2 BC compatibility
In order to keep BC with ZF2, we can create a
Zend\ModuleManager\Listener\Zf2CompatibilityListener
, which emulates the same logic of all the currentget([A-Z][A-Za-z]+)Config
methods. It can be either on by default or opt-in, but that has to be decidedDrawbacks
None so far
TODO
getUnCacheableConfig
Zend\ModuleManager\Feature\UnCacheableConfigProviderInterface
Zend\ModuleManager\Listener\Zf2CompatibilityListener
being turned on or off by defaultConclusions
get([A-Z][A-Za-z]+)Config
will be removed from the module classes.getConfig
will be usedget([A-Z][A-Za-z]+)Config
can still be usedThat's it, only removal of of methods, and that's perfectly fine. I'll work on a PR as soon as possible.
The text was updated successfully, but these errors were encountered: