web-dev-qa-db-fra.com

L'argument passé à function doit être appelable, tableau donné

J'essaie d'exécuter une méthode sur chaque élément d'une collection. C'est une méthode objet résidant dans la même classe:

protected function doSomething()
{
    $discoveries = $this->findSomething();
    $discoveries->each([$this, 'doSomethingElse']);
}

protected function doSomethingElse($element)
{
    $element->bar();
    // And some more
}

Si je fais précéder l'appel sur Collection::each avec le contrôle is_callable([$this, 'doSomethingElse']), il retourne la valeur true, il est donc apparemment appelable. L'appel lui-même lève cependant une exception:

Type error: L'argument 1 transmis à Illuminate\Support\Collection :: each () doit être appelable, tableau donné, appelé dans ---. php on line 46

La méthode qui tente d’être appelée peut être trouvée ici .

Je contourne cela en passant simplement une fermeture qui elle-même appelle simplement cette fonction, mais cela constituerait certainement une solution beaucoup plus propre et je ne peux pas savoir pourquoi cela provoque l'erreur.

12
Padarom

Changez la visibilité de votre méthode de rappel en public.

protected function doSomething()
{
    $discoveries = $this->findSomething();
    $discoveries->each([$this, 'doSomethingElse']);
}

public function doSomethingElse($element)
{
    $element->bar();
    // And some more
}
16
BKB

Depuis PHP 7.1, vous pouvez laisser votre fonction protégée. Maintenant vous pouvez écrire: 

protected function doSomething()
{
    $discoveries = $this->findSomething();
    $discoveries->each(\Closure::fromCallable([$this, 'doSomethingElse']));
}

protected function doSomethingElse($element)
{
    $element->bar();
    // And some more
}

La source

5
Shadrix

PHP> = 5.4

Je n'ai pas été en mesure de reproduire votre erreur, mais je suppose que vous devriez utiliser $discoveries au lieu de $this dans le tableau de rappel, comme suit:

$discoveries->each([$discoveries, 'doSomethingElse']);

Même si $discoveries et $this appartiennent à la même classe et peuvent donc accéder aux méthodes protégées et privées de l'autre, il est possible que la fonctionnalité d'indication de type ne vérifie pas que l'objet du tableau de rappel est la même classe que la classe actuelle. Cependant, la méthode is_callable() le vérifiera, ce qui peut expliquer pourquoi il renvoie true lorsque vous l'appelez depuis l'intérieur de la méthode each().

PHP <5.4

Il n'y a pas de type nommé callable; par conséquent, lorsque vous l'utilisez comme indicateur de type, il fait référence à un class nommé callable. Voir cette réponse.

0
GreeKatrina