Michael,
First of all, thanks for taking the time to go over the prototype, give feedback, and even expand on the code! Your time and efforts are very much appreciated! On Sat, Sep 17, 2011 at 1:08 PM, Michael Scholl <[hidden email]> wrote: > Hi there, > > talked to Evan on irc. So according to his response I'm sending an email here too. > > I started to check out the new mvc approach by building a base app with the help of Evans tutorial. > > Some problems I got while setting things up: > - If you have more than one "IndexController" in different modules you could use different aliases to make them accessible. But I dont like the idea of aliasing different IndexController to get them working (or should thinking about good aliases the new creative part of my work?). There should be a real module based approach to separate the calls. It should handle it out of the route and the route needs a module parameter. I tried to port the "Module" Route from "old" mvc setup and I got it working in some ways (problem is to get informations about the possible modules in the route match method) - https://gist.github.com/c08635648a43e698be57. > > Fetching the right controller based on the module param could be solved like this: $controller = $locator->get($moduleName . '_' . $controllerName); aliases needed to setup like this: admin_index - https://gist.github.com/9f226c2ce591c0dbf3e1. I generally agree, there probably be some default routing strategy that "works" out of the box without aliases, and takes advantage of module's namespacing to prevent controller name collisions between modules. (ZF1-style /module/controller/action could work fine). I don't imagine anyone ever intended for this to be omitted, but rather it's just one of those things that hasn't been added to the prototypes yet. The commits in your zf2 fork seem like a decent start. My thoughts: 0) Will it be acceptable for a module to provide controllers under more than one namespace (modules/Foo/src/Foo/Controller/IndexController.php _AND_ modules/Foo/src/Bar/Controller/IndexController.php), perhaps a module that provides a front-end and an admin interface? If so, then is the routing simply based on the namespace under modules/Foor/src/? (This is sort of a discussion in it's own right, but relevant none-the-less) 1) I would suggest keeping the route type a bit more generic, such as a "http namespace route" or something; keeping it generic and not dependent on the actual module system. By this I mean, it would be some default route we could provide that tries to map: /foo/index/bar to the class Foo\Controller\IndexController as long as it exists or is available via a registered autoloader / service locator, without requiring the router to have any actual knowledge of the concept of "modules". This keeps the functionality generic and still useful to those who choose not develop their application within the "module" paradigm. 2) Going along with point 1), I'd propose we go with namespace separators versus the underscore. I realize you may have just left that from your ZF1 port to minimize time invested in the prototype, so I'm just mentioning it for the sake of clarity. > View rendering is problematic, there are more ScriptPaths set up, and it picks up the first match. So there should be an option to render the view script in a special module view path or manipulating the used script paths. Dont know where to plugin. This is reasonable, similar to how ZF1 behaved in this regard. Again, I think this should not necessarily be hard-coded around the concept of "modules". Some unorganized thoughts: 0) We need to keep in mind that modules need to be able to explicitly override the views/layouts provided by another module for things like themes and utilizing alternative static assets (css, images, etc). View/layout overrides == good, View/layout collisions == bad. You're right that the current implementation poses a problem of collisions (unintentional overrides). We need a balanced solution here. 1) Will view paths always be a runtime thing, or should we also provide an "install" mechanism that copies them over to a central location, and overrides are resolved at that step? On that note (but slightly off topic), I don't think there should be much "framework" functionality that _depends_ on an install process other than obvious stuff like schema importing, copying assets, etc. The install process may be able to _do_ other things, but I think runtime alternatives should be available for most of those (even if for no other reason that development). > I think a real module based approach would make some things more easy and separated, how they should be - perhaps for people coming from zf1 too :) … I only see the benefits of a clear structure. If you build a UserController in your module but also using Evans User module - I mean, there absolutly seems to be a need for it. Even if you only have two modules! (I hope, that solution should work with just _many_ modules having all a UserController without any collisions) See above. > - /attribute/value/attribute/value notation for get params should be integrated in some way (my module loader approach supports notation of params already) I see no problem in providing this functionality with the default route the same as ZF1. I'm sure most people are expecting this anyway. Again, this is probably something that wasn't meant to be excluded, but simply hadn't been added yet, as there really hasn't been a spot to cleanly put it yet. This would belong in the default route provided, or _maybe_ in a more generic abstract route, depending on how globally available we want behavior to be without code duplication (traits sure would be nice! ;)). > Last I would like to add my opinion to: Optimistic loading / Dynamic bootstrap. > > There should be a solution for it. This topic was the biggest problem in zf1 modules with using Zend_Application. All modules were bootstrapped by request. I know many people running in crazy problems because of thinking, only there one module would be bootstrapped by request. Instead of implementing caching mechanism for big configurations I definitely would prefer finding a good way to do bootstrapping in connection to the request. Would be great to see some solution like Evan was talking about: > >> I thought about this quite a bit and it's a challenging issue to say >> the least. For this to work, the system needs an intricate >> understanding of what modules are required to dispatch a request >> (http/cli/etc); and unfortunately that can be completely dynamic and >> is not necessarily 1:1. The only thing I can think of is somehow >> having modules themselves work within a sort of DI container >> themselves, which just knows _of_ the modules, but doesn't actually >> load them or their config until they're called via a 'get()' or >> something along those lines. The idea is too abstract for me to even >> begin trying to implement something like that. However that seems like >> a bad idea to me, and I'm not confident it'll actually work in >> practice, or be worth the complication even if it were possible. > > Doesn't seem to be a bad idea, I would love having a solution where a ModuleManager bootstraps all things needed for a requested module. > > > If I compare Zend_Application Module approach to module approach right now, the one big difference is getting things loaded by di and based on events. In the end for building applications it not soo much change compared to zf1. You get fat configurations/bootstrap, all modules are bootstrapped by request. Im missing the points we complain about zf1 modules all the time. > > Matthew: > >> I would expect most sites would likely compose one or two modules, and >> have one "main" module that composes the majority of the site >> functionality. As such, the whole need for optimistic configuration may >> be a moot point. >> >> However, for larger projects, where you may have many teams working on >> parallel features, modules may also be another good fit -- and this is >> where the problem may crop up. However, those same sites likely would >> have issues under ZF1 as well -- with complexity and size usually come >> performance issues as well. It's good for us to keep these issues in >> mind, but we shouldn't choose _not_ to explore a given path only because >> of them. > > I think, a new ZF2MVC approach should handle modules connected to a request. And it should be clear separated. > If you dont want to deal with all that module stuff no one is keeping you from doing only one or perhaps two modules. > But the general idea of modules, being plugable and all that stuff, I dont get the point, why we shouldnt have this issue straight before our eyes and not somewhere backuped in our minds. Otherwise we could just forget it perhaps on our ways to a final zf2. I think we need to be very careful with this concept of optimistic loading. While runtime loading and merging of every config can be a somewhat heavy operation, it would be discouraged in a production environment. I'm not entirely convinced the performance hit or ram footprint of loading even an _enormous_ cached/pre-merged configuration would be very substantial percentage wise in your average request cycle for any app (enough to justify a very complicated optimistic loading system which may introduce even more of a performance hit than it's intended to solve). I think it may fall under one of those "Throw an SQL query somewhere, and you wouldn't notice it on the xdebug output" cases that Paddy was mentioning in the option array vs parameter objects thread a few days ago. Some time last week, I spoke to Artur (Thinkscape) on IRC about this and he had an idea along the lines of: extend the classmap concept to contain Class Name -> File Name -> Module Name, then in the classmap autoloader (or an extended version), you would only run the module's init stuff once the first class from the module has been called. (Artur: please correct me if I have misinterpreted your idea here.) I brought up that essentially that's the same as a cached merged classmap, but he responded by saying it could be optimized on a per-namespace basis so the map only resolves namespace -> module, then the module's autoloaders are set up as-needed, and any module with classes that are never called would not be set up at all. - How would a module register it's routes to begin with? - If Artur's concept is strictly for autoloaders and not for configurations, would that really provide any performance benefit, or would it actually add even more overhead to autoloading? - Does this restrict modules from "adding" code to another module's namespace? It's possible via classmaps now, but would that even be acceptable practice in the first place? - What about a module that overrides some view scripts of another module that would simply be injecting some view path (or something along those lines; think themes)? I'd love to be proved wrong on this one, trust me! I'm all ears if there's an elegant solution that allows for truly loading modules on-demand. The problem anyone trying will likely run into (aside from the "chicken or the egg" problem with route configurations) is making the solution actually outperform that of just loading the configs and autoloaders of all the modules. Really, if you look at the current module manager/loader, you'll notice that the actual tasks that are performed on every module, every time are really not expensive. Really it only includes / instantiates ONE object per module (Foo\Module) and calls an init() method on that object IF the init method exists (it's optional). In my examples, I used this init method for setting up the module's autoloader (which can be cached and skipped). There should be very little code that _actually_ needs to be ran during this init. Other than that, it's just the getConfig and config->merge() which would also be cached in production. To beat a dead horse: try to remember in production we'd be caching classmaps and the merged configs, eliminating a large chunk of that overhead. TL;DR on optimistic loading: It's a _great_ idea in theory, but it's complicated and there may not really be that much existing overhead to optimize. Look over my module manager/loader prototypes and if you _still_ feel like it's too expensive and have an idea for optimistic loading that would actually improve the performance, then let's hear about it! -- Evan Coury -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
On Monday 19 September 2011 19:49:56 Evan Coury wrote: > This is reasonable, similar to how ZF1 behaved in this regard. Again, > I think this should not necessarily be hard-coded around the concept > of "modules". > > Some unorganized thoughts: > > 0) We need to keep in mind that modules need to be able to explicitly > override the views/layouts provided by another module for things like > themes and utilizing alternative static assets (css, images, etc). > View/layout overrides == good, View/layout collisions == bad. You're > right that the current implementation poses a problem of collisions > (unintentional overrides). We need a balanced solution here. > > 1) Will view paths always be a runtime thing, or should we also > provide an "install" mechanism that copies them over to a central > location, and overrides are resolved at that step? On that note (but > slightly off topic), I don't think there should be much "framework" > functionality that _depends_ on an install process other than obvious > stuff like schema importing, copying assets, etc. The install process > may be able to _do_ other things, but I think runtime alternatives > should be available for most of those (even if for no other reason > that development). Can't DI play a role in here? At one time A shouldn't collide with B while their namings are the same and accidentally the view paths are placed in a wrong order. The second time you want A to override B but accidentally you forgot to explicitly place the view paths in the right order. I'm not an DI expert, but from the vague things I heard of, DI is capable of manage this stuff. Regards, Jurian -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
In reply to this post by EvanDotPro
Am 19.09.2011 um 19:49 schrieb Evan Coury: > Michael, > > First of all, thanks for taking the time to go over the prototype, > give feedback, and even expand on the code! Your time and efforts are > very much appreciated! > > On Sat, Sep 17, 2011 at 1:08 PM, Michael Scholl <[hidden email]> wrote: >> Hi there, >> >> talked to Evan on irc. So according to his response I'm sending an email here too. >> >> I started to check out the new mvc approach by building a base app with the help of Evans tutorial. >> >> Some problems I got while setting things up: >> - If you have more than one "IndexController" in different modules you could use different aliases to make them accessible. But I dont like the idea of aliasing different IndexController to get them working (or should thinking about good aliases the new creative part of my work?). There should be a real module based approach to separate the calls. It should handle it out of the route and the route needs a module parameter. I tried to port the "Module" Route from "old" mvc setup and I got it working in some ways (problem is to get informations about the possible modules in the route match method) - https://gist.github.com/c08635648a43e698be57. >> >> Fetching the right controller based on the module param could be solved like this: $controller = $locator->get($moduleName . '_' . $controllerName); aliases needed to setup like this: admin_index - https://gist.github.com/9f226c2ce591c0dbf3e1. > > I generally agree, there probably be some default routing strategy > that "works" out of the box without aliases, and takes advantage of > module's namespacing to prevent controller name collisions between > modules. (ZF1-style /module/controller/action could work fine). I > don't imagine anyone ever intended for this to be omitted, but rather > it's just one of those things that hasn't been added to the prototypes > yet. The commits in your zf2 fork seem like a decent start. Ok, I see… so we agree in this point. > My thoughts: > > 0) Will it be acceptable for a module to provide controllers under > more than one namespace > (modules/Foo/src/Foo/Controller/IndexController.php _AND_ > modules/Foo/src/Bar/Controller/IndexController.php), perhaps a module > that provides a front-end and an admin interface? If so, then is the > routing simply based on the namespace under modules/Foor/src/? (This > is sort of a discussion in it's own right, but relevant none-the-less) For me it would be not really necessary. I would separate different namespaces into different modules. Having to modules for admin and frontend in the end. But thats only a personally choice. Could imagine people like the idea of having one module distributed containing everything needed (but that would open a submodule logic into the given module strategic) > 1) I would suggest keeping the route type a bit more generic, such as > a "http namespace route" or something; keeping it generic and not > dependent on the actual module system. By this I mean, it would be > some default route we could provide that tries to map: /foo/index/bar > to the class Foo\Controller\IndexController as long as it exists or is > available via a registered autoloader / service locator, without > requiring the router to have any actual knowledge of the concept of > "modules". This keeps the functionality generic and still useful to > those who choose not develop their application within the "module" > paradigm. as long as the route offers calling a special namespace, everything is fine. This was the missing part for me in the route setup right now. > 2) Going along with point 1), I'd propose we go with namespace > separators versus the underscore. I realize you may have just left > that from your ZF1 port to minimize time invested in the prototype, so > I'm just mentioning it for the sake of clarity. The aliasing only allows _ and - at the moment, so namespace support for aliases needs to be hacked into the alias feature. Thats why I used underscores there. >> View rendering is problematic, there are more ScriptPaths set up, and it picks up the first match. So there should be an option to render the view script in a special module view path or manipulating the used script paths. Dont know where to plugin. > > This is reasonable, similar to how ZF1 behaved in this regard. Again, > I think this should not necessarily be hard-coded around the concept > of "modules". > > Some unorganized thoughts: > > 0) We need to keep in mind that modules need to be able to explicitly > override the views/layouts provided by another module for things like > themes and utilizing alternative static assets (css, images, etc). > View/layout overrides == good, View/layout collisions == bad. You're > right that the current implementation poses a problem of collisions > (unintentional overrides). We need a balanced solution here. ^^ overriding layout +1 balanced solution +1 :) Do you already have an idea how this solution could look like? Right now, script paths are merged together from all modules. How you would go from there? > 1) Will view paths always be a runtime thing, or should we also > provide an "install" mechanism that copies them over to a central > location, and overrides are resolved at that step? On that note (but > slightly off topic), I don't think there should be much "framework" > functionality that _depends_ on an install process other than obvious > stuff like schema importing, copying assets, etc. The install process > may be able to _do_ other things, but I think runtime alternatives > should be available for most of those (even if for no other reason > that development). hm overriding is per request? So how do you want to "install" / copy them to make them working for all different request types? >> - /attribute/value/attribute/value notation for get params should be integrated in some way (my module loader approach supports notation of params already) > > I see no problem in providing this functionality with the default > route the same as ZF1. I'm sure most people are expecting this anyway. > Again, this is probably something that wasn't meant to be excluded, > but simply hadn't been added yet, as there really hasn't been a spot > to cleanly put it yet. This would belong in the default route > provided, or _maybe_ in a more generic abstract route, depending on > how globally available we want behavior to be without code duplication > (traits sure would be nice! ;)). good to hear… $this->getRequest()->getMetadata('route-match')->getParam($name, $default) is not so pretty > … > I think we need to be very careful with this concept of optimistic > loading. While runtime loading and merging of every config can be a > somewhat heavy operation, it would be discouraged in a production > environment. I'm not entirely convinced the performance hit or ram > footprint of loading even an _enormous_ cached/pre-merged > configuration would be very substantial percentage wise in your > average request cycle for any app (enough to justify a very > complicated optimistic loading system which may introduce even more of > a performance hit than it's intended to solve). thats true in some way. All ways of doing it end up in a complex setup of things. (Was thinking about letting ModuleManager solve the module configuration setup - but for sure will be some kind of complex logic at the dispatch/routing part) > Some time last week, I spoke to Artur (Thinkscape) on IRC about this > and he had an idea along the lines of: extend the classmap concept to > contain Class Name -> File Name -> Module Name, then in the classmap > autoloader (or an extended version), you would only run the module's > init stuff once the first class from the module has been called. > (Artur: please correct me if I have misinterpreted your idea here.) I > brought up that essentially that's the same as a cached merged > classmap, but he responded by saying it could be optimized on a > per-namespace basis so the map only resolves namespace -> module, then > the module's autoloaders are set up as-needed, and any module with > classes that are never called would not be set up at all. Sounds some way how it could be integrated. The ini/config stuff should loaded by request and merged into main di. > - How would a module register it's routes to begin with? Some way to consume routes separate from all the other di stuff (extra file)? > - If Artur's concept is strictly for autoloaders and not for > configurations, would that really provide any performance benefit, or > would it actually add even more overhead to autoloading? As far as I see it only would make sense for loading configurations by request. But I get the point of overhead... > - Does this restrict modules from "adding" code to another module's > namespace? It's possible via classmaps now, but would that even be > acceptable practice in the first place? Its not restricted right now, why should it restricted then? > - What about a module that overrides some view scripts of another > module that would simply be injecting some view path (or something > along those lines; think themes)? > > I'd love to be proved wrong on this one, trust me! I'm all ears if > there's an elegant solution that allows for truly loading modules > on-demand. The problem anyone trying will likely run into (aside from > the "chicken or the egg" problem with route configurations) is making > the solution actually outperform that of just loading the configs and > autoloaders of all the modules. Really, if you look at the current > module manager/loader, you'll notice that the actual tasks that are > performed on every module, every time are really not expensive. Really > it only includes / instantiates ONE object per module (Foo\Module) and > calls an init() method on that object IF the init method exists (it's > optional). In my examples, I used this init method for setting up the > module's autoloader (which can be cached and skipped). There should be > very little code that _actually_ needs to be ran during this init. > Other than that, it's just the getConfig and config->merge() which > would also be cached in production. To beat a dead horse: try to > remember in production we'd be caching classmaps and the merged > configs, eliminating a large chunk of that overhead. Im not sure how a big di with 20 different autoloaders (for 20 different modules) getting registered is performing compared to a di setup with (with more complex config setup things). I do get the pro and cons better for this topic! hmmmm :) Cheers Mischosch -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
In reply to this post by EvanDotPro
On 11-09-19 10:49 AM, Evan Coury wrote:
> 0) Will it be acceptable for a module to provide controllers under > more than one namespace > (modules/Foo/src/Foo/Controller/IndexController.php _AND_ > modules/Foo/src/Bar/Controller/IndexController.php), perhaps a module > that provides a front-end and an admin interface? If so, then is the > routing simply based on the namespace under modules/Foor/src/? (This > is sort of a discussion in it's own right, but relevant none-the-less) I think modules should provide a single namespace and preferably the module namespace should correspond to the module name. This seems like the simplest and most straightforward approach to me. Regards, Stew -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
Administrator
|
-- Stewart Lord <[hidden email]> wrote
(on Monday, 19 September 2011, 01:34 PM -0700): > On 11-09-19 10:49 AM, Evan Coury wrote: > >0) Will it be acceptable for a module to provide controllers under > >more than one namespace > >(modules/Foo/src/Foo/Controller/IndexController.php _AND_ > >modules/Foo/src/Bar/Controller/IndexController.php), perhaps a module > >that provides a front-end and an admin interface? If so, then is the > >routing simply based on the namespace under modules/Foor/src/? (This > >is sort of a discussion in it's own right, but relevant none-the-less) > > > I think modules should provide a single namespace and preferably the > module namespace should correspond to the module name. This seems > like the simplest and most straightforward approach to me. During the IRC meeting last week, the following points were made: * We should not dictate the filesystem structure of modules * We should not restrict what a module may contain * There are use cases for having multiple namespaces under a given module * There are use cases for code-only modules (i.e., without MVC artifacts) * There are use cases for asset-only modules (e.g., containing only CSS, JS, images, etc.) * We *should* provide a recommended structure So, while a single namespace matching the module namespace may be the most straight-forward, there should be nothing restricting other use cases. BTW, the recommended structure is in the summary from last week's meeting log: http://framework.zend.com/wiki/display/ZFDEV2/2011-09-14+Meeting+Log The rationale is to allow for a separation of code from configuration from tests from public assets, etc. As you can see, with this structure, there's absolutely nothing preventing serving additional namespaces from the given module. And since it's up to the module's Module class to setup autoloading, then it really doesn't matter. The only place it _would_ matter is for automating some sort of optimistic configuration/DI initialization setup. Even so, I'd expect that we'd provide more of a rules-based setup than a conventions based one. -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
On 11-09-19 1:57 PM, Matthew Weier O'Phinney wrote:
> -- Stewart Lord<[hidden email]> wrote > (on Monday, 19 September 2011, 01:34 PM -0700): >> On 11-09-19 10:49 AM, Evan Coury wrote: >>> 0) Will it be acceptable for a module to provide controllers under >>> more than one namespace >>> (modules/Foo/src/Foo/Controller/IndexController.php _AND_ >>> modules/Foo/src/Bar/Controller/IndexController.php), perhaps a module >>> that provides a front-end and an admin interface? If so, then is the >>> routing simply based on the namespace under modules/Foor/src/? (This >>> is sort of a discussion in it's own right, but relevant none-the-less) >> >> >> I think modules should provide a single namespace and preferably the >> module namespace should correspond to the module name. This seems >> like the simplest and most straightforward approach to me. > > During the IRC meeting last week, the following points were made: > > * We should not dictate the filesystem structure of modules > * We should not restrict what a module may contain > * There are use cases for having multiple namespaces under a given > module > * There are use cases for code-only modules (i.e., without MVC > artifacts) > * There are use cases for asset-only modules (e.g., containing only > CSS, JS, images, etc.) > * We *should* provide a recommended structure > > So, while a single namespace matching the module namespace may be the > most straight-forward, there should be nothing restricting other use > cases. > > BTW, the recommended structure is in the summary from last > week's meeting log: > > http://framework.zend.com/wiki/display/ZFDEV2/2011-09-14+Meeting+Log > > The rationale is to allow for a separation of code from configuration > from tests from public assets, etc. As you can see, with this structure, > there's absolutely nothing preventing serving additional namespaces from > the given module. And since it's up to the module's Module class to > setup autoloading, then it really doesn't matter. > > The only place it _would_ matter is for automating some sort of > optimistic configuration/DI initialization setup. Even so, I'd expect > that we'd provide more of a rules-based setup than a conventions based > one. Thanks! That makes sense. Looks like I need to catch up on the meeting notes. It might be too late, but it would be nice if the recommended structure were not so deeply nested. If we think that most modules will have a single namespace and that the namespace will correspond to the module name, then we could eliminate the 'SpinDoctor' folder under src and tests. Presumably we will have an abstract Module.php class that users can extend to get auto-loading, etc. for free if they follow our recommended directory structure? Is the 'Controller' suffix actually something we intend to carry forward, or just shown here by force of habit? Regards, Stew -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
In reply to this post by Mischosch
On Mon, Sep 19, 2011 at 1:30 PM, Michael Scholl <[hidden email]> wrote:
>> 1) I would suggest keeping the route type a bit more generic, such as >> a "http namespace route" or something; keeping it generic and not >> dependent on the actual module system. By this I mean, it would be >> some default route we could provide that tries to map: /foo/index/bar >> to the class Foo\Controller\IndexController as long as it exists or is >> available via a registered autoloader / service locator, without >> requiring the router to have any actual knowledge of the concept of >> "modules". This keeps the functionality generic and still useful to >> those who choose not develop their application within the "module" >> paradigm. > > as long as the route offers calling a special namespace, everything is fine. > This was the missing part for me in the route setup right now. Yep, I see no reason that we wouldn't provide this out of the box. >> 2) Going along with point 1), I'd propose we go with namespace >> separators versus the underscore. I realize you may have just left >> that from your ZF1 port to minimize time invested in the prototype, so >> I'm just mentioning it for the sake of clarity. > > The aliasing only allows _ and - at the moment, so namespace support for aliases needs to be hacked into the alias feature. > Thats why I used underscores there. Understood. >>> View rendering is problematic, there are more ScriptPaths set up, and it picks up the first match. So there should be an option to render the view script in a special module view path or manipulating the used script paths. Dont know where to plugin. >> >> This is reasonable, similar to how ZF1 behaved in this regard. Again, >> I think this should not necessarily be hard-coded around the concept >> of "modules". >> >> Some unorganized thoughts: >> >> 0) We need to keep in mind that modules need to be able to explicitly >> override the views/layouts provided by another module for things like >> themes and utilizing alternative static assets (css, images, etc). >> View/layout overrides == good, View/layout collisions == bad. You're >> right that the current implementation poses a problem of collisions >> (unintentional overrides). We need a balanced solution here. > > ^^ > overriding layout +1 > balanced solution +1 :) > > Do you already have an idea how this solution could look like? > Right now, script paths are merged together from all modules. > How you would go from there? Nope, I had not put much thought into this yet, as this is more-so on the MVC side of things rather than directly module-related. I'd say it's open to suggestions and/or prototypes at this point. :) >> 1) Will view paths always be a runtime thing, or should we also >> provide an "install" mechanism that copies them over to a central >> location, and overrides are resolved at that step? On that note (but >> slightly off topic), I don't think there should be much "framework" >> functionality that _depends_ on an install process other than obvious >> stuff like schema importing, copying assets, etc. The install process >> may be able to _do_ other things, but I think runtime alternatives >> should be available for most of those (even if for no other reason >> that development). > > hm overriding is per request? > So how do you want to "install" / copy them to make them working for all different request types? I'm not sure I understand your question. I was not proposing anything specific. >> Some time last week, I spoke to Artur (Thinkscape) on IRC about this >> and he had an idea along the lines of: extend the classmap concept to >> contain Class Name -> File Name -> Module Name, then in the classmap >> autoloader (or an extended version), you would only run the module's >> init stuff once the first class from the module has been called. >> (Artur: please correct me if I have misinterpreted your idea here.) I >> brought up that essentially that's the same as a cached merged >> classmap, but he responded by saying it could be optimized on a >> per-namespace basis so the map only resolves namespace -> module, then >> the module's autoloaders are set up as-needed, and any module with >> classes that are never called would not be set up at all. > > Sounds some way how it could be integrated. The ini/config stuff should loaded by request and merged into main di. The config (including the di config) _is_ currently being loaded and merged per request; plus caching can be enabled with the more recent commits I've made. >> - How would a module register it's routes to begin with? > > Some way to consume routes separate from all the other di stuff (extra file)? So we split out routes into their own special config files that must be _always_ loaded, then all other config is loaded once a class from a module is loaded? Is that worth it, or would it even provide any performance gain at all? I'd love to see some benchmarks like I did with the config caching stuff here on the ML. >> - If Artur's concept is strictly for autoloaders and not for >> configurations, would that really provide any performance benefit, or >> would it actually add even more overhead to autoloading? > > As far as I see it only would make sense for loading configurations by request. > But I get the point of overhead... Exactly; it becomes expensive to try to optimizing, thus making the effort itself an oxymoron. ;) >> - Does this restrict modules from "adding" code to another module's >> namespace? It's possible via classmaps now, but would that even be >> acceptable practice in the first place? > > Its not restricted right now, why should it restricted then? I was referring to Artur's suggestion that a map could contain: Namespace -> Module Which then triggers the initiation of the appropriate module when a class from some namespace is called, then it would check if the class is available after that (assuming that module's init set up an autoloader for the class in question). I may be misunderstanding what Artur was getting at, but that implies a 1:1 relationship between namespaces and modules. >> - What about a module that overrides some view scripts of another >> module that would simply be injecting some view path (or something >> along those lines; think themes)? >> >> I'd love to be proved wrong on this one, trust me! I'm all ears if >> there's an elegant solution that allows for truly loading modules >> on-demand. The problem anyone trying will likely run into (aside from >> the "chicken or the egg" problem with route configurations) is making >> the solution actually outperform that of just loading the configs and >> autoloaders of all the modules. Really, if you look at the current >> module manager/loader, you'll notice that the actual tasks that are >> performed on every module, every time are really not expensive. Really >> it only includes / instantiates ONE object per module (Foo\Module) and >> calls an init() method on that object IF the init method exists (it's >> optional). In my examples, I used this init method for setting up the >> module's autoloader (which can be cached and skipped). There should be >> very little code that _actually_ needs to be ran during this init. >> Other than that, it's just the getConfig and config->merge() which >> would also be cached in production. To beat a dead horse: try to >> remember in production we'd be caching classmaps and the merged >> configs, eliminating a large chunk of that overhead. > > Im not sure how a big di with 20 different autoloaders (for 20 different modules) getting registered is performing compared to a di setup with (with more complex config setup things). Please remember, that if we implement caching of merged classmaps, there would only be one large classmap autoloader to register, _not_ 20 module-specific classmap autoloaders that must be looped through for every class to be resolved. The only time you may actually have 20 different autoloaders registered in this case would be during development. -- Evan Coury -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
Administrator
|
In reply to this post by Stewart Lord
-- Stewart Lord <[hidden email]> wrote
(on Monday, 19 September 2011, 02:10 PM -0700): > On 11-09-19 1:57 PM, Matthew Weier O'Phinney wrote: > >-- Stewart Lord<[hidden email]> wrote > >(on Monday, 19 September 2011, 01:34 PM -0700): > >>On 11-09-19 10:49 AM, Evan Coury wrote: > >>>0) Will it be acceptable for a module to provide controllers under > >>>more than one namespace > >>>(modules/Foo/src/Foo/Controller/IndexController.php _AND_ > >>>modules/Foo/src/Bar/Controller/IndexController.php), perhaps a module > >>>that provides a front-end and an admin interface? If so, then is the > >>>routing simply based on the namespace under modules/Foor/src/? (This > >>>is sort of a discussion in it's own right, but relevant none-the-less) > >> > >> > >>I think modules should provide a single namespace and preferably the > >>module namespace should correspond to the module name. This seems > >>like the simplest and most straightforward approach to me. > > > >During the IRC meeting last week, the following points were made: > > > > * We should not dictate the filesystem structure of modules > > * We should not restrict what a module may contain > > * There are use cases for having multiple namespaces under a given > > module > > * There are use cases for code-only modules (i.e., without MVC > > artifacts) > > * There are use cases for asset-only modules (e.g., containing only > > CSS, JS, images, etc.) > > * We *should* provide a recommended structure > > > >So, while a single namespace matching the module namespace may be the > >most straight-forward, there should be nothing restricting other use > >cases. > > > >BTW, the recommended structure is in the summary from last > >week's meeting log: > > > > http://framework.zend.com/wiki/display/ZFDEV2/2011-09-14+Meeting+Log > > > >The rationale is to allow for a separation of code from configuration > >from tests from public assets, etc. As you can see, with this structure, > >there's absolutely nothing preventing serving additional namespaces from > >the given module. And since it's up to the module's Module class to > >setup autoloading, then it really doesn't matter. > > > >The only place it _would_ matter is for automating some sort of > >optimistic configuration/DI initialization setup. Even so, I'd expect > >that we'd provide more of a rules-based setup than a conventions based > >one. > > > Thanks! That makes sense. Looks like I need to catch up on the > meeting notes. It might be too late, but it would be nice if the > recommended structure were not so deeply nested. > > If we think that most modules will have a single namespace and that > the namespace will correspond to the module name, then we could > eliminate the 'SpinDoctor' folder under src and tests. Again, recommended != requirement. We can likely show off several; the point of the structure proposed is that: * It clearly separates code from configuration from assets * It allows for multiple namespaces when required * It makes the packaging story (regardless of installation mechanism) easier I tried a structure like you suggest. I ended up with something like this: Foo/ autoload_classmap.php autoload_function.php autoload_register.php phpunit.xml Module.php Controller/ BlahController.php Test/ Controller/ BlahControllerTest.php configs/ module.config.php public/ css/ foo.css js/ foo.js views/ blah/ action.phtml The problem I had above was that the "assets" -- configs, view scripts, CSS/JS -- were all jumbled in with the code. Additionally, it means mixing in things like testing infrastructure with the code, which gets messy really quickly. Semantically, it felt wrong, and when I started thinking about packaging, I realized that while I _could_ package it, it would require a more complex effort to do so. While the nesting of the recommendation is not much fun, it _does_ answer all of the above requirements, and it's not terrible (in practice, I found I'm rarely going more than two-levels deep under the src/ directory). > Presumably we will have an abstract Module.php class that users can > extend to get auto-loading, etc. for free if they follow our > recommended directory structure? That's the idea. Ideally, you'll have a classmap, and potentially a self-contained autoloading mechanism as well, so it can act as a standalone bit of code, independent of the framework (unless it has dependencies on the framework, that is). (The "autoload_*.php" classes above serve that purpose.) > Is the 'Controller' suffix actually something we intend to carry > forward, or just shown here by force of habit? It's useful when you import elsewhere -- that way you don't have to alias. I'm actually considering proposing we do similarly for valiators and filters, as I've found I have to alias them typically to make sure the names used are semantic (e.g., "AlnumFilter" vs. "Alnum"; the former makes it clear it's a filter, and not a validator). -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
In reply to this post by EvanDotPro
On Mon, Sep 19, 2011 at 7:49 PM, Evan Coury <[hidden email]> wrote:
> Some time last week, I spoke to Artur (Thinkscape) on IRC about this > and he had an idea along the lines of: extend the classmap concept to > contain Class Name -> File Name -> Module Name, then in the classmap > autoloader (or an extended version), you would only run the module's > init stuff once the first class from the module has been called. > (Artur: please correct me if I have misinterpreted your idea here.) I > brought up that essentially that's the same as a cached merged > classmap, but he responded by saying it could be optimized on a > per-namespace basis so the map only resolves namespace -> module, then > the module's autoloaders are set up as-needed, and any module with > classes that are never called would not be set up at all. > > There are 2 types of resources: 1. On-demand: Resources that can be loaded/init on demand, at runtime, for modules that are needed in current request (context). 2. Predefined: Resources that have to be available for every request and should be merged. Examples for the first group (loaded on-demand): * classmaps * php classes with Services * php classes with Models * module-specific resources (Application\Resource) or equivalent (service-locator) * module-specific configuration for the above * host-specific routes * other namespace-bound php classes Examples for the second group (predefined, have to be available for each request) * intra-module dependencies configuration * DI configuration * routes * route-classes * navigation (pages) * static assets (png, jpg, js, txt, etc.) Every module should be able to do the following: 1. Provide a registry of resources that are to be merged (appended, overridden, extended) with other modules' resources 2. Provide a registry of on-demand resources it provides. Of course each module has to be able to install itself at runtime. By installation I understand the following process: 1. Module Manager scans user pre-defined modules' directories in the order provided (this includes local app modules and shared-dir holding modules) 2. Module Manager orders the dependency tree and loads resources in proper order. 3. Module Manager merges all resources and stores the result in a writable cache/ directory. Merged resources include: * a namespace->module map is created * module classmaps are created (or a global classmap is created) * static assets are selected and files are linked/copied to app's public/ directory * all routes are merged and a global routes config is created (cache, serialized/var_exported array() ) * DI defs are merged and a cache is stored (serialized/var_exported array() ) * navigation containers are merged and a cache (global navig. tree) is stored (serialized/var_exported array() ) Using cli (zend_tool) developer can warm the cache by manually invoking Module Manager and its scanning procedure. If cli is not used, Module Manager has to be able to determine changes to any of the supplied modules directories (i.e. a module is installed or removed). Possible solutions include filemtime(DIR), md5(serialize(glob( DIR . '/*' ) ) ); Once a change has been detected, cache/ is emptied and is re-generated. For on-demand resources I proposed the following: 1. For all PHP classes, including controller Actions, Models, Adapters etc -- we have agreed that these should live inside a namespace. Furthermore, a single module can provide 2 or more namespaces with multiple php classes. This means we could use a module autoloader. For example: <?php $adapter = new Firebird\FirebirdAdapter(); a) ModuleAutoloader::__autoload() b) $registry = include CACHE_DIR . "/modules-classes.php"; modules-classes.php: return array( 'Acme' => '/var/www/shared/ZF2/modules/AcmeModule', // share-dir module 'Seo' => APPLICATION_PATH . "/modules/Seo", // local module 'Firebird' => APPLICATION_PATH . "/modules/ExtraDbAdapters", // local module ); c) $modulePath = $registry[$namespace]; d) if( ! $initModules[ $modulePath ] ){ e) .... if"ExtraDbAdapters" module is not init, it will now be bootstrapped, configs will be read, classmaps loaded etc. f) pass-thru to next autoloader (classmap?) -- or -- PSR-0-compatible load of $modulePath . "/src/". $namespace . "/". $className A. -- __ /.)\ +48 695 600 936 \(./ [hidden email] |
In reply to this post by weierophinney
On 11-09-20 6:29 AM, Matthew Weier O'Phinney wrote:
> Again, recommended != requirement. We can likely show off several; the > point of the structure proposed is that: Understood, but the recommended structure is what will likely be adopted by most people, so it should cater to most people. > I tried a structure like you suggest. I ended up with something like > this: That's not quite what I had in mind. I was only suggesting we drop the SpinDoctor folder under src and tests: SpinDoctor/ Module.php autoload_classmap.php autoload_function.php autoload_register.php configs/ spin-doctor.ini routes.ini public/ images/ css/ spin-doctor.css js/ spin-doctor.js src/ Controller/ SpinDoctorController.php DiscJockeyController.php Form/ Request.php tests/ bootstrap.php phpunit.xml Controller/ SpinDoctorControllerTest.php DiscJockeyControllerTest.php Basically this layout assumes that one namespace per module will be more common than multiple namespaces. I think we should encourage a 1:1 mapping of namespace to module name. > While the nesting of the recommendation is not much fun, it _does_ > answer all of the above requirements, and it's not terrible (in > practice, I found I'm rarely going more than two-levels deep under the > src/ directory). Every level of nesting imposes a penalty on developers traversing the code in their IDE. Take a look at Django 'apps' and you'll find they have almost no folder structure to them. >> Is the 'Controller' suffix actually something we intend to carry >> forward, or just shown here by force of habit? > > It's useful when you import elsewhere -- that way you don't have to > alias. I'm actually considering proposing we do similarly for valiators > and filters, as I've found I have to alias them typically to make sure > the names used are semantic (e.g., "AlnumFilter" vs. "Alnum"; the former > makes it clear it's a filter, and not a validator). To confirm, are you talking about when you use/as import the class? Or something else specific to the proposed module system? Stew -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
Administrator
|
-- Stewart Lord <[hidden email]> wrote
(on Tuesday, 20 September 2011, 09:03 AM -0700): > On 11-09-20 6:29 AM, Matthew Weier O'Phinney wrote: > > Again, recommended != requirement. We can likely show off several; the > > point of the structure proposed is that: > > Understood, but the recommended structure is what will likely be > adopted by most people, so it should cater to most people. I'd argue it caters to the largest number of use cases. > > I tried a structure like you suggest. I ended up with something like > > this: > > That's not quite what I had in mind. I was only suggesting we drop > the SpinDoctor folder under src and tests: > > SpinDoctor/ > Module.php > autoload_classmap.php > autoload_function.php > autoload_register.php > configs/ > spin-doctor.ini > routes.ini > public/ > images/ > css/ > spin-doctor.css > js/ > spin-doctor.js > src/ > Controller/ > SpinDoctorController.php > DiscJockeyController.php > Form/ > Request.php > tests/ > bootstrap.php > phpunit.xml > Controller/ > SpinDoctorControllerTest.php > DiscJockeyControllerTest.php > > Basically this layout assumes that one namespace per module will be > more common than multiple namespaces. I think we should encourage a > 1:1 mapping of namespace to module name. See, to me, the above breaks the 1:1 mapping, as the code under src no longer follows PSR-0 (i.e., no 1:1 mapping of the module name to the source tree). It also makes it harder to determine at a glance whether a module has sub-namespaces, or allows multiple namespaces. I think the recommended structure should make these scenarios very, very clear -- and the above does not. > > While the nesting of the recommendation is not much fun, it _does_ > > answer all of the above requirements, and it's not terrible (in > > practice, I found I'm rarely going more than two-levels deep under the > > src/ directory). > > Every level of nesting imposes a penalty on developers traversing > the code in their IDE. Take a look at Django 'apps' and you'll find > they have almost no folder structure to them. Can you elaborate? I don't really see the penalty myself... is it click time for expanding folders? And this is a single additional level from what you proposed; I'm curious how much perceived penalty that is, and what it means for development. If it's a lot, maybe we should look at an almost flat structure. > > > Is the 'Controller' suffix actually something we intend to carry > > > forward, or just shown here by force of habit? > > > > It's useful when you import elsewhere -- that way you don't have to > > alias. I'm actually considering proposing we do similarly for valiators > > and filters, as I've found I have to alias them typically to make sure > > the names used are semantic (e.g., "AlnumFilter" vs. "Alnum"; the former > > makes it clear it's a filter, and not a validator). > > To confirm, are you talking about when you use/as import the class? > Or something else specific to the proposed module system? The former -- it's not module-specific in the least. As an example, consider the following without aliasing: namespace Foo; use Zf2Mvc\Controller\Action; class My extends Action { } What is "Action"? what is "My"? When we use natural language, it's hard to tell what they are. With aliasing, you might do this: namespace Foo; use Zf2Mvc\Controller\Action as ActionController; class My extends ActionController { } Which is slightly better, but what is "Foo\My"? Even if we put it in a "Controller" namespace, what if we have other helper classes in that namespace (such as event listeners)? Additionally, we're also having to explicitly define the alias, which adds verbosity and typing. So, if we simply suffix, we get something a bit more verbose than the original example, but semantically clear: namespace Foo; use Zf2Mvc\Controller\ActionController; class MyController extends ActionController { } It's the same issue in the main library as well -- filters and validators have the same name, so if you want to use the same ones in the same code area, you _have_ to alias them. Doctrine has actually standardized on this already: https://github.com/doctrine/doctrine2/tree/master/lib/Doctrine/ORM/Persisters https://github.com/doctrine/doctrine2/tree/master/lib/Doctrine/ORM/Event https://github.com/doctrine/doctrine2/tree/master/lib/Doctrine/ORM/Mapping/Driver When I first saw this, I disliked it... until I started running into the same issues that drove the decision in the first place. :) -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
On 11-09-20 9:46 AM, Matthew Weier O'Phinney wrote:
> I'd argue it caters to the largest number of use cases. That's valid. It might be making it a bit harder for the common case though. > See, to me, the above breaks the 1:1 mapping, as the code under src no > longer follows PSR-0 (i.e., no 1:1 mapping of the module name to the > source tree). > > It also makes it harder to determine at a glance whether a module has > sub-namespaces, or allows multiple namespaces. I think the recommended > structure should make these scenarios very, very clear -- and the above > does not. I can see that. Those are both good points. > Can you elaborate? I don't really see the penalty myself... is it click > time for expanding folders? And this is a single additional level from > what you proposed; I'm curious how much perceived penalty that is, and > what it means for development. If it's a lot, maybe we should look at an > almost flat structure. Yes, it is the click time and additional thought required to find the file you want to work on. Personally, I find it tedious navigating deeply nested source trees. If I have to dig for a source file, it breaks my train of thought. Thank goodness for control-clicking in NetBeans/Eclipse! That said, I don't know how flat we can or should make it. Django gets away with it because they put all the models in one file, all the views in one file, etc. It's actually probably a joy to work on (haven't spent time with it myself), but we have different requirements of course. Basically I looked at the proposed structure and asked, what can we eliminate? The additional nesting under src and tests was the first thing to jump to mind. You could also drop the src folder if you wanted to, but that seems less palatable to me. > What is "Action"? what is "My"? When we use natural language, it's hard > to tell what they are. > [snip] > When I first saw this, I disliked it... until I started running into the > same issues that drove the decision in the first place. :) This seems like a very slippery slope. You could make this same argument for forms and models (e.g. how do I disambiguate the Woozle form from the Woozle model? Tack on Form and Model of course!) It appears to introduce a inconsistency in class naming conventions. Regards, Stew -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
Administrator
|
-- Stewart Lord <[hidden email]> wrote
(on Tuesday, 20 September 2011, 10:34 AM -0700): > On 11-09-20 9:46 AM, Matthew Weier O'Phinney wrote: <snip> > > What is "Action"? what is "My"? When we use natural language, it's hard > > to tell what they are. > > [snip] > > When I first saw this, I disliked it... until I started running into the > > same issues that drove the decision in the first place. :) > > This seems like a very slippery slope. You could make this same > argument for forms and models (e.g. how do I disambiguate the Woozle > form from the Woozle model? Tack on Form and Model of course!) Okay, consider this, then, as it's also a very real use case I ran into: User/ Controller/ User.php Form/ User.php Model/ User.php Let's look inside User/Controller/User.php: namespace User\Controller; use User\Form\User, User\Model\User, Zf2Mvc\Controller\ActionController; class User extends ActionController { ... } It should be obvious immediately that this won't work. So, now we need to alias: namespace User\Controller; use User\Form\User as UserForm, User\Model\User as UserModel, Zf2Mvc\Controller\ActionController; class User extends ActionController That works. I'd argue that for the simplest use case, we shouldn't have to alias -- and yet, if we don't suffix with the type, then in our most common use case, we end up needing the aliases just to get the code running. This would be much easier: namespace User\Controller; use User\Form\UserForm, User\Model\UserModel, Zf2Mvc\Controller\ActionController; class UserController extends ActionController We don't need to jump through hoops or know what namespaces each class is in to know what each refers to -- we know which class represents a form, from a model, from the controller itself, based simply on the class name. > It appears to introduce a inconsistency in class naming conventions. How so? Namespaces are merely names used to group related functionality; the class names still need to be semantically correct. -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
On 11-09-20 10:56 AM, Matthew Weier O'Phinney wrote:
> Okay, consider this, then, as it's also a very real use case I ran into: > [snip] > It should be obvious immediately that this won't work. So, now we need > to alias: > > namespace User\Controller; > > use User\Form\UserForm, > User\Model\UserModel, > Zf2Mvc\Controller\ActionController; > > That works. I'd argue that for the simplest use case, we shouldn't > have to alias -- and yet, if we don't suffix with the type, then in > our most common use case, we end up needing the aliases just to get the > code running. This would be much easier: > > namespace User\Controller; > > use User\Form\UserForm, > User\Model\UserModel, > Zf2Mvc\Controller\ActionController; > > class UserController extends ActionController > > We don't need to jump through hoops or know what namespaces each class > is in to know what each refers to -- we know which class represents a > form, from a model, from the controller itself, based simply on the > class name. Yup, that's a pickle. I think I prefer the aliasing solution. As a third option, couldn't we import 'User' and then refer to the form as Form\User and the model as Model\User? It seems like PHP namespaces give us the tools we need to disambiguate this and the end developer can choose how to resolve these scenarios. To me the suffix seems like a step backwards. This is probably something we should get more input on. >> It appears to introduce a inconsistency in class naming conventions. > > How so? Namespaces are merely names used to group related functionality; > the class names still need to be semantically correct. Because now we suffix some classes with their parent namespace, and others not. As a user I will need to be aware of when to do this and when not to do this. Stew -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
On 20 Sep 2011, at 19:11, Stewart Lord wrote: > On 11-09-20 10:56 AM, Matthew Weier O'Phinney wrote: >> Okay, consider this, then, as it's also a very real use case I ran into: >> [snip] >> It should be obvious immediately that this won't work. So, now we need >> to alias: >> >> namespace User\Controller; >> >> use User\Form\UserForm, >> User\Model\UserModel, >> Zf2Mvc\Controller\ActionController; >> >> That works. I'd argue that for the simplest use case, we shouldn't >> have to alias -- and yet, if we don't suffix with the type, then in >> our most common use case, we end up needing the aliases just to get the >> code running. This would be much easier: >> >> namespace User\Controller; >> >> use User\Form\UserForm, >> User\Model\UserModel, >> Zf2Mvc\Controller\ActionController; >> >> class UserController extends ActionController >> >> We don't need to jump through hoops or know what namespaces each class >> is in to know what each refers to -- we know which class represents a >> form, from a model, from the controller itself, based simply on the >> class name. > > Yup, that's a pickle. I think I prefer the aliasing solution. As a third option, couldn't we import 'User' and then refer to the form as Form\User and the model as Model\User? > > It seems like PHP namespaces give us the tools we need to disambiguate this and the end developer can choose how to resolve these scenarios. To me the suffix seems like a step backwards. > > This is probably something we should get more input on. At first glance, I prefer to avoid the appending of the type onto a class name. I would have used the third option and imported User as I find it clearer and requires less use statements when you're using a lot of bits from a given namespace hierarchy. I can see the convenience of having the appended type, but if we're going to do that, then we may as well remove the folder in the middle: namespace User; use User\UserForm, User\UserModel, Zf2Mvc\Controller\ActionController; class UserController extends ActionController {} *shrug* May get a bit hairy if there are a lot of Forms, Models and Controllers though. Regards, Rob… > >>> It appears to introduce a inconsistency in class naming conventions. >> >> How so? Namespaces are merely names used to group related functionality; >> the class names still need to be semantically correct. > > Because now we suffix some classes with their parent namespace, and others not. As a user I will need to be aware of when to do this and when not to do this. > > Stew > > -- > List: [hidden email] > Info: http://framework.zend.com/archives > Unsubscribe: [hidden email] > > -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
On Tue, Sep 20, 2011 at 9:26 PM, Rob Allen <[hidden email]> wrote:
> At first glance, I prefer to avoid the appending of the type onto a class > name. I would have used the third option and imported User as I find it > clearer and requires less use statements when you're using a lot of bits > from a given namespace hierarchy. > > +1 on this. Symfony2 does the appending of the "types". It annoyed the hell out of me. Luckily, I'm out of that nightmare now :P Actually, the suffix-less way can be used already (well, could, the last time I played with zf2 :(), thanks to Zend\Di. As long the suffix is not a requirement, but only a recommendation, I can live with that; I'll just omit the suffix and use it the way it suits me :) -- ~Robert Basic; http://robertbasic.com/ |
In reply to this post by Artur Bodera
For those proposing "optimistic loading" of modules:
Can you _please_ look at the actual code in my prototype and point to where exactly you see a performance bottleneck. Preferably post a working example on GitHub that we can profile with Xdebug to show what exactly needs optimized. Based on profiling via xdebug, loading modules appears to be one of the lightest operations in the overall execution, especially when the merged config is cached. I think that you may be over-estimating the per-module cost involved here. For example, module loading accounts for under 0.7% of the total execution time, benchmarked against the finished product of the tutorial posted in the OP. So please, before we continue on over-complicating the module system for extremely tiny performance gains, let's see some benchmarks showing _what_ areas need improvement or pose a performance problem. --- Evan Coury -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
In reply to this post by robertbasic
Hi Matthew,
Any further thoughts on whether or not to suffix classes with their 'type'? What do you think about the alternative I presented (e.g. use User and resolve via Form\User, Model\User)? Stew On 11-09-20 10:40 PM, Robert Basic wrote: > On Tue, Sep 20, 2011 at 9:26 PM, Rob Allen<[hidden email]> wrote: > >> At first glance, I prefer to avoid the appending of the type onto a class >> name. I would have used the third option and imported User as I find it >> clearer and requires less use statements when you're using a lot of bits >> from a given namespace hierarchy. >> >> > +1 on this. Symfony2 does the appending of the "types". It annoyed the hell > out of me. Luckily, I'm out of that nightmare now :P > > Actually, the suffix-less way can be used already (well, could, the last > time I played with zf2 :(), thanks to Zend\Di. As long the suffix is not a > requirement, but only a recommendation, I can live with that; I'll just omit > the suffix and use it the way it suits me :) -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
Administrator
|
-- Stewart Lord <[hidden email]> wrote
(on Monday, 10 October 2011, 08:29 PM -0700): > Any further thoughts on whether or not to suffix classes with their > 'type'? What do you think about the alternative I presented (e.g. > use User and resolve via Form\User, Model\User)? Well, that won't work. :) namespace User\Controller; use User; At that point, two things will happen: * "PHP Warning: The use statement with non-compound name 'User' has no effect" * You end up having to qualify the names starting with "User": User\Form\User. Alternately, you could do this: namespace User\controller; use User\Form, User\Model; at which point you can do Form\User, Model\User. I personally would prefer within my method bodies not to use the namespace separator. The namespace is superfluous to what I'm doing; I simply want to use classes. "UserForm" is simply a class. I don't care where it came from (that's what imports are for). I do care that the name is descriptive of its purpose. All this said, it's likely a matter of personal preference within application code. The question is how we approach it in the ZF2 library. One issue we've run into is that in some cases, the class names when stripped of a vendor prefix clash with PHP keywords -- good examples are the "Int" validators and filters, and various places where we used the word "Array" as a final class segment (such as an Array adapter). With those, we then were forced to suffix with the type -- making them different from the rest. To me, this is an additional argument for type suffixing. Thoughts? > On 11-09-20 10:40 PM, Robert Basic wrote: > >On Tue, Sep 20, 2011 at 9:26 PM, Rob Allen<[hidden email]> wrote: > > > >>At first glance, I prefer to avoid the appending of the type onto a class > >>name. I would have used the third option and imported User as I find it > >>clearer and requires less use statements when you're using a lot of bits > >>from a given namespace hierarchy. > >> > >> > >+1 on this. Symfony2 does the appending of the "types". It annoyed the hell > >out of me. Luckily, I'm out of that nightmare now :P > > > >Actually, the suffix-less way can be used already (well, could, the last > >time I played with zf2 :(), thanks to Zend\Di. As long the suffix is not a > >requirement, but only a recommendation, I can live with that; I'll just omit > >the suffix and use it the way it suits me :) > -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
On 11-10-11 6:54 AM, Matthew Weier O'Phinney wrote:
> Well, that won't work. :) I'm very sorry about that! I should have tested it first. > Alternately, you could do this: > > namespace User\controller; > > use User\Form, > User\Model; > > at which point you can do Form\User, Model\User. I like this usage. As you say, a matter of personal taste. > One issue we've run into is that in some cases, the class names when > stripped of a vendor prefix clash with PHP keywords -- good examples are > the "Int" validators and filters, and various places where we used the > word "Array" as a final class segment (such as an Array adapter). With > those, we then were forced to suffix with the type -- making them > different from the rest. To me, this is an additional argument for type > suffixing. > > Thoughts? This is indeed a slippery a slope! The problem is similar to the issue of naming classes 'Abstract' or 'Interface'. By this reasoning, shouldn't we suffix all final class segments with the type as reserved words could occur in any namespace? BTW, I don't think 'int' is a reserved word. I can have a class called Int, but I cannot have a class named Array. Regards, Stew -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
Free forum by Nabble | Edit this page |