Bár nem tegnap történt, hogy az 5.3-as sorozat első verziója kijött, gondoltam kicsit körbejárom a névtelen függvények témakörét az ősidőktől napjainking. Az ősidő alatt itt természetesen a 4-es verziót értem, amikor még csak a call_user_func állt a rendelkezésünkre. Lássuk, hogyan is ment ez.

A create_function módszer (attól tekintsünk el, hogy a __FUNCTION__ varázskonstans csak a 4.3-as verzióban jelent meg):

$f = create_function('', 'echo __FUNCTION__ . "\n";');
call_user_func($f);

A függvény neve stringként módszer:

$f = 'myFunction';
call_user_func($f);

Az osztály és a statikus metódus neve tömbként:

$f = array('MyClass', 'myStaticFunction');
call_user_func($f);

Az objektum és a metódus neve tömbként:

$c = new MyClass();
$f = array($c, 'myFunction');
call_user_func($f);

Az osztály és a statikus metódus neve stringként (5.2.3-as PHP-tól):

$f = 'MyClass::myStaticFunction';
call_user_func($f);

Az objektum meghívása (5.3.0-s PHP-tól):

$c = new MyClass();
call_user_func($c);

És ezzel el is érkeztünk a jelenhez. Az 5.3.0-s verzióval megjelentek a closure-ök (az újfajta névtelen függvények), amolyan JavaScript-es definiálással:

$f = function () {
};

Természetesen a teljes visszafelé kompatibilitásról ne is álmodjunk ezért kezdjük is el végignézni az előző módokat, hogy mi működik továbbra is:

A create_function módszer megy továbbra is (emlékeim szerint 5.3 előtt is működött így, ezért ez nem túl meglepő):

$f = create_function('', 'echo __FUNCTION__ . "\n";');
$f();

A függvény neve stringként módszer (működik):

$f = 'myFunction';
$f();

Itt sajnos meg is állhatunk. A tömbös rendszerek (PHP Fatal error: Function name must be a string) és az osztály+statikus metódus neve stringként (PHP Fatal error: Call to undefined function MyClass::myStaticFunction()) nem működik.

Maradt még az objektum direkt meghívása, ami működik, de ez sem túl nagy meglepetés, mivel az 5.3.0-s verzióbal vezették be hozzá az új varázsmetódust:

$c = new MyClass();
$c();

Ilyenkor (és a call_user_func-os esetben is) az osztály __invoke() metódusa hívódik meg.

Ezzel azt hiszem nagyjából ki is veséztük a különböző callback típusok és névtelen függvények hívhatóságát. Maradt még némi scope kérdés, de az házi feladat (annyit megsúgok, hogy a use a kulcsszó). Egy kis segítség hozzá: