Quantcast

ZF2 modules tutorial (with screenshots!)

classic Classic list List threaded Threaded
43 messages Options
123
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

EvanDotPro
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Jurian Sluiman

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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Mischosch
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Stewart Lord
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

weierophinney
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Stewart Lord
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

EvanDotPro
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

weierophinney
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Artur Bodera
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.
>
>
Ok, here goes a simplified version of my concept:

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]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Stewart Lord
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

weierophinney
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Stewart Lord
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

weierophinney
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Stewart Lord
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

akrabat

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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

robertbasic
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/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

EvanDotPro
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Stewart Lord
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

weierophinney
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]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 modules tutorial (with screenshots!)

Stewart Lord
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]


123
Loading...