Utilisation de use sur les closures et le $this

Petit nouveau ! | 1 Messages

18 févr. 2015, 22:42

Bonjour,

J'utilise depuis peu le PHP pour développer un site web mais je pense avoir pas mal intégrer pas de mal ses "concepts" entre autre la POO...

En revanche il y a encore un bon nombre de points qui m'échappe et entre autre, celui qui fait l'objet de ma question...

Pour poser les choses, j'ai créé une classe dans laquelle au niveau du constructeur, j'instancie une application "Slim " (cf le framework)... Je récupère donc mon application Slim que j'affecte à un joli "$this->app".

Jusqu'ici tout va bien sauf à partir du moment où je commence à vouloir utiliser ce "$this->app" pour faire ce que l'on a à faire avec Slim quand on paramètre par exemple les routes.
Dans sa "logique", Slim utilise le système des fonctions anonymes pour paramétrer le code à affecter à chaque "route"...

Donc au départ, j'ai écrit un truc du genre :

$this->app->get('/', function () use ($this) {
$this->response->SetStatus(204);
});

Avec le $this dans le "use" pour pouvoir passer le contexte à la fonction anonyme.

Mais là, PHP m'envoie balader en me disant grosso modo que le $this n'est pas un object... J'ai mis un moment à comprendre pourquoi... Mais j'ai fini par réaliser que comme je passais le "$this" à la fonction anonyme alors que j'étais encore dans le constructeur de la classe... Bah nécessaire a priori, l'objet n'était pas encore bien instancié... Mais ce n'est pas ça qui me surprend... Ce qui me surprend c'est la manière dont j'ai contourné le problème de façon assez hasardeuse....

$that = $this->app;
$this->app->get('/', function () use ($that) {
$that->response->SetStatus(204);
});

Alors... déjà, oui je définis $that comme $this->app et non comme $this... Je fais ça pour contourner le problème qui est que je suis dans le constructeur de ma classe... Mais cela dit, je ne comprends pas bien, pourquoi dans le constructeur, je peux faire référence à moi-même mais je ne peux pas passer ce "pointeur" à la fonction anonyme.... J'ai même essayé un "&$this" dans le use mais sans succès.

Y a-t-il quelqu'un qui pourrait m'expliquer ce qui m'interdit de "me" passer "moi-même" dans le "use" de la fonction anonyme ?

La question est sûrement tordue... j'en conviens mais comme je cherche à comprendre la logique du PHP afin de coder au mieux et la manière la plus élégante possible, je voudrais comprendre pourquoi je suis contraint à la seconde syntaxe qui m'apparaît vraiment pas pratique et visuellement assez laide....

Il se peut que j'ai loupé un truc important aussi...

Alors merci d'avance de vos réponses.

Bonne soirée !

ViPHP
xTG
ViPHP | 7331 Messages

19 févr. 2015, 14:22

L'objet est déjà créé quand tu accèdes au constructeur.
PHP ne te fournit qu'une callback suite à la création pour que tu configures ton objet comme tu le souhaites.

Donc oui $this est tout à fait utilisable.

Par contre je n'ai pas la réponse à pourquoi cela ne fonctionne pas dans ton exemple.

Après je trouve l'écriture très moche.
Pour ma part j'aurai passé $this en paramètre de la fonction. Les changement de scope c'est terrible quand c'est mal utilisé, on accède à tout depuis n'importe où et pour n'importe quoi.
Et j'aurai rédigé la fonction de manière à ne pas avoir de fonction anonyme. C'est moche je trouve, appelons un chat un chat....

ViPHP
ViPHP | 928 Messages

20 févr. 2015, 01:37

Depuis PHP 5.4 tu peux utiliser $this dans les Closure, mais il ne faut pas l'utiliser avec use.

Donc tout simplement :
$this->app->get('/', function () {
   $this->response->SetStatus(204);
});
$this est assez particulier, il s'agit du contexte. Tu peux utiliser bindTo sur ta closure pour changer le contexte : http://php.net/manual/fr/closure.bindto.php

++