Closure en objecten
Opmerking: PHP 5.3 Beta heeft geen ondersteuning meer voor $this binnen een closure omdat men het niet eens kon worden over de werking. De hieronder beschreven werking slaat op de alfa versies van PHP 5.3
Hoe zit het met $this binnen closures, en waar zitten de caveats?
Vandaag op het programma:
Code (php)
Foo::$greet is de closure die gebruik maakt van protected Foo::$greeting. Dit mag, want de closure wordt in een object-context gemaakt. $this hoef je niet te importeren, net zoals je dat niet hoeft in __construct. Daarnaast zijn wijzigingen die je doet op $this direct wijzigingen op $foo, zoals verwacht.
Hoe roep je nu $foo->greet aan? Eerste idee wat bij mij opkomt is dan:
WTF?!: Boooh! Dat werkt niet. De klasse Foo heeft geen method genaamd 'greet'. Maar een reference (reference? Zie volgende pagina!) maken werkt wel.
* Magic Method __invoke *
Maar wat is een closure nu werkelijk binnen PHP?
Code (php)
Vergelijk dat met de oude create_function:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
var_dump(create_function('$x, $y', 'return $x * $y;'));
/* resultaat:
string(9) "lambda_1"
*/
?>
var_dump(create_function('$x, $y', 'return $x * $y;'));
/* resultaat:
string(9) "lambda_1"
*/
?>
Een closure is een object in PHP. Vandaar dat ik een pagina terug ook sprak over een reference. Een closure kopieer je niet (sterker nog, clone werkt niet) maar verwijs je naar zoals standaard is bij objecten in PHP 5.
Maar als Closure een klasse is, kan je hem ook extenden? Nee helaas, Closure is een final class, wat inhoudt dat je hem niet kan uitbreiden. Je kan hem ook niet direct vanuit PHP instantiƫren:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
$x = new Closure();
/* Resultaat:
PHP Fatal error: Instantiation of 'Closure' is not allowed
*/
?>
$x = new Closure();
/* Resultaat:
PHP Fatal error: Instantiation of 'Closure' is not allowed
*/
?>
Maaaarrrr... Closure heeft wel een method genaamd '__invoke'! Guess what:
Code (php)
En het wordt leuker!
Code (php)
Dit betekent dat je voortaan instanties van klassen met een __invoke-method direct kan aanroepen of kan opgeven als callback: Dit zal werken zonder gemekker:
.. het doet alleen niets nuttigs :)
« vorige pagina | volgende pagina »
Inhoudsopgave
- Je eerste closure
- Variabelen importeren in een closure
- De scope van 'use'
- Closure en objecten
- WTF?! - de opsomming
- Disclaimer