Configuration merging and callables

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Configuration merging and callables

demiankatz
I've just run into an odd situation - wondering if I'm doing something wrong or if anyone has a recommended workaround.

For a long time, my application has had tons of closures in its module.config.php file. Since this is bad practice, I've refactored everything to rely on static factory methods, and I've replaced all the closures with callable arrays... e.g. array('VuFind\Driver\Factory', 'getMyDriver').

So far, so good.

The problem is that for my local instance of my application, I have a custom module which overrides some of the factories from the base module. I just updated this to also use callable arrays instead of closures, and the configuration merging code is merging the arrays together, so I end up with something like:

array('VuFind\Driver\Factory', 'getMyDriver', 'VuFindLocal\Factory', 'getMyLocalDriver')

and then, of course, is_callable() fails, and the whole process blows up.

I'm guessing I should be doing something differently somewhere. Any suggestion to which bit I should change?

thanks,
Demian
Reply | Threaded
Open this post in threaded view
|

Re: Configuration merging and callables

weierophinney
Administrator
On Mar 11, 2014 2:26 PM, "Demian Katz" <[hidden email]> wrote:
>
> I've just run into an odd situation - wondering if I'm doing something
wrong or if anyone has a recommended workaround.
>
> For a long time, my application has had tons of closures in its
module.config.php file. Since this is bad practice, I've refactored
everything to rely on static factory methods, and I've replaced all the
closures with callable arrays... e.g. array('VuFind\Driver\Factory',
'getMyDriver').
>
> So far, so good.
>
> The problem is that for my local instance of my application, I have a
custom module which overrides some of the factories from the base module. I
just updated this to also use callable arrays instead of closures, and the
configuration merging code is merging the arrays together, so I end up with
something like:
>
> array('VuFind\Driver\Factory', 'getMyDriver', 'VuFindLocal\Factory',
'getMyLocalDriver')
>
> and then, of course, is_callable() fails, and the whole process blows up.
>
> I'm guessing I should be doing something differently somewhere. Any
suggestion to which bit I should change?

Use classes that implement __invoke() instead, and reference the class
name. The SM is smart enough to autoload these when requested, making them
a more robust solution than array callbacks - particularly for the use car
of overriding.
Reply | Threaded
Open this post in threaded view
|

RE: Configuration merging and callables

demiankatz
That certainly works, but it seems to add an awful lot of clutter – a separate factory class for every service. My application offers a lot of different options, so this would add hundreds of files and require PHP to do twice as much autoloading (which I realize isn’t that expensive, but it has to add up at some point). I considered putting a static factory method in each class to cut down on clutter, but this doesn’t seem like good design – it couples things unnecessarily. Having stand-alone factory classes that group together related objects seems like the most attractive option from an organizational perspective. Sounds like it may not be practical, and I know you’re the expert – but I would be curious to hear if anyone else has successfully approached this from another angle. If not, I’ll get to work moving all my factories around a second time. ☺

- Demian

From: Matthew Weier O'Phinney [mailto:[hidden email]]
Sent: Tuesday, March 11, 2014 7:32 PM
To: Demian Katz
Cc: Zend Framework General
Subject: Re: [fw-general] Configuration merging and callables

Use classes that implement __invoke() instead, and reference the class name. The SM is smart enough to autoload these when requested, making them a more robust solution than array callbacks - particularly for the use car of overriding.
Reply | Threaded
Open this post in threaded view
|

RE: Configuration merging and callables

demiankatz
Actually, after looking more closely at the PHP manual for callables (thanks to the suggestion of a colleague), there is a simple alternative: just use callable strings instead of callable arrays…

so:

array(‘My\Factory’, ‘myStaticMethod’)

becomes:

‘My\Factory::myStaticMethod’

Easy! I'll still consider the possibility of using separate factory classes under some circumstances, but when it makes sense to group stuff together, it looks like this offers the option to do so without breaking overriding.

- Demian

> -----Original Message-----
> From: Demian Katz [mailto:[hidden email]]
> Sent: Wednesday, March 12, 2014 8:31 AM
> To: Matthew Weier O'Phinney
> Cc: Zend Framework General
> Subject: RE: [fw-general] Configuration merging and callables
>
> That certainly works, but it seems to add an awful lot of clutter – a separate
> factory class for every service. My application offers a lot of different
> options, so this would add hundreds of files and require PHP to do twice as
> much autoloading (which I realize isn’t that expensive, but it has to add up
> at some point). I considered putting a static factory method in each class to
> cut down on clutter, but this doesn’t seem like good design – it couples
> things unnecessarily. Having stand-alone factory classes that group together
> related objects seems like the most attractive option from an organizational
> perspective. Sounds like it may not be practical, and I know you’re the expert
> – but I would be curious to hear if anyone else has successfully approached
> this from another angle. If not, I’ll get to work moving all my factories
> around a second time. ☺
>
> - Demian
>
> From: Matthew Weier O'Phinney [mailto:[hidden email]]
> Sent: Tuesday, March 11, 2014 7:32 PM
> To: Demian Katz
> Cc: Zend Framework General
> Subject: Re: [fw-general] Configuration merging and callables
>
> Use classes that implement __invoke() instead, and reference the class name.
> The SM is smart enough to autoload these when requested, making them a more
> robust solution than array callbacks - particularly for the use car of
> overriding.