Have you ever thought some day how to iterate a list of functions in php. In this tutorial i will show a feature in PHP 5.4 and above related to Closures and arrays which is how to create arrays that contain a Closures. With This feature in place you can iterate an array of functions and execute them one by one.
Let’s demonstrate this with examples
<?php
$fns = [
"hello" => function($name, $name2 = false) {
echo empty($name2) ? "Hello $name" : "Hello $name and $name2";
},
"bye" => function($name) {
echo "Bye $name";
}
];
Now let’s say i want to iterate over all these functions with another function that accepts a variable number of arguments:
function say() {
global $fns;
foreach ($fns as $fn) {
call_user_func_array($fn, func_get_args());
}
}
This works pretty well:
say("foo");
// 'Hello foo';
// 'Bye foo'
say ("foo", "bar");
// 'Hello foo and bar';
// 'Bye foo'
Remember to use this feature in a class you have to define the array in the constructor:
<?php
class Say {
private $fns;
function __construct() {
$this->fns = [
"hello" => function($name, $name2 = false) {
echo empty($name2) ? "Hello $name" : "Hello $name and $name2";
},
"bye" => function($name) {
echo "Bye $name";
}
];
foreach ($this->fns as $fn) {
call_user_func_array($fn, func_get_args());
}
}
}
$say = new Say("foo");
$say = new Say("foo", "bar");
Or (slightly better in terms of readable code) define the functions in the class and reference them from the array
class Say {
private $fns = ['hello', 'bye'];
function __construct() {
foreach ($this->fns as $fname) {
$fn = array($this, $fname);
call_user_func_array($fn, func_get_args());
}
}
public function hello($name, $name2 = false) {
echo empty($name2) ? "Hello $name" : "Hello $name and $name2";
}
public function bye($name) {
echo "Bye $name";
}
}
$say = new Say("foo");
$say = new Say("foo", "bar");
If you don’t want to write out all the methods by hand in the $fns array you could use this dirty trick to get all function names in the class without the ‘magic’ methods like __construct and __autoload:
class Say {
function __construct() {
$fnames = array_filter(get_class_methods($this), function($name) {
return $name[0] != "_";
});
foreach ($fnames as $fname) {
$fn = array($this, $fname);
call_user_func_array($fn, func_get_args());
}
}
public function hello($name, $name2 = false) {
echo empty($name2) ? "Hello $name" : "Hello $name and $name2";
}
public function bye($name) {
echo "Bye $name";
}
}
$say = new Say("foo");
$say = new Say("foo", "bar");


