An alternative to an array of functions? An alternative to an array of functions? php php

An alternative to an array of functions?


Closures are expensive for performance and memoryusage in php. Procedural coding provoked a big ball of mud, spaghetti code and other anti patterns. Switch structures are very hard to test and it's a violation of OCP.

You should prefer OOP in SOLID way to avoid redundancy, improving scalability and maintainablity. That is the best practice to provide a set of functions which are reuseable.You can also seperate your code in layers and modules to reduce complexity and improve interchangability.

In your case your classes can implement __invoke to call it as invokable and your keys could be the fullqualified namespaces for these classes, so you can call it like a function.From now on you can also use inheritence, polymorphism or design patterns like composite, decorator etc. to reuse other functions or to add functions.

Here a simple Example..

<?phpuse Foo\Bar;class This{    public function __invoke()    {        $this->execute();    }    public function execute()    {        /* ... */    } }class That extends This{    public function execute()    {        /* ... */    } }$namespaces = array("\Foo\Bar\This", "\Foo\Bar\That"); foreach ($namespaces as $fullQualifiedNamespace) {    /** @var callable $fullQualifiedNamespace */    $fullQualifiedNamespace(); }

This behavior is also reachable by implementing a specific interface to This and That.Within iteration you can check the interface to call the defined contract. Or you build a Process Class where you can add objects which implements this interface. The Process class can execute all attached objects (Chain of Responsibility).

I would prefer the Chain of Responsibility Pattern this is understandable by most developers and not so magic like PHP's __invoke interceptor. In a factory you can define your chain and you are able to define other dependencies to the chain or to the attached chain objects.


You can do it in a cleaner way, that is, encapsulate all of these functions into a class. They can be static or dynamic, it doesn't matter much I guess in this case. I'll show both examples...

1. dynamic approach

class MyFunctions{    public function doThis()    {        /* implement do this here */    }    public function doThat()    {        /* implement do that here */    }    /* ... */}/* then somewhere else */$program = ["doThis", "doThat", "doThis"];$myFunctions = new MyFunctions;foreach ($program as $method) {    $myFunctions->$method();}

2. static approach

class MyFunctions{    public static function doThis()    {        /* implement do this here */    }    public static function doThat()    {        /* implement do that here */    }    /* ... */}/* then somewhere else */$program = ["doThis", "doThat", "doThis"];foreach ($program as $method) {    MyFunctions::$method();}

IMHO this is cleaner than implementing those functions in an array of closures... And better than implementing a switch as You still have to call this in a loop - so why slowing down with another switch?


I'm all in favor of what Mamuz describes in his answer, but I do want to give you a "quick fix":

$functions = [];$functions['do this'] = function () {    // does this};$functions['do call'] = function () use ($functions) {    // calls 'do this'    $functions['do this']();}$functions['do manipulation'] = function () use (&$functions) {    // manipulates $functions    $functions['do something else'] = function () {        // does something else    };}

I think this is pretty self explanatory.