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.