Yii, как вызвать функцию рекурсивно - PullRequest
0 голосов
/ 30 августа 2018

Как я могу вызвать рекурсивно test()? Я пробовал оба пути, и это не сработало.

namespace app\controllers;

use Yii;
use yii\web\Controller;

class SiteController extends Controller {

    public function actionIndex() {

        $test= $this->test(5);

        }
        return $this->render('index');
    }

    private function test($res) {
        $test1 = parent::test(1);
        $test2 = $this->test(1);
    }

}

Я пробовал с $test1 = parent::test(1); И $test2 = $this->test(1);.

1 Ответ

0 голосов
/ 31 августа 2018

Синтаксическая ошибка

public function actionIndex() {

    $test= $this->test(5);

    } //<--- this should not be here as it closes the actionIndex method
    return $this->render('index');
}

Это выдаст что-то вроде unexpected T_RETURN Ошибка разбора.

Песочница

И это

  <b>Parse error</b>:  syntax error, unexpected 'return' (T_RETURN), expecting function (T_FUNCTION) or const (T_CONST) in

Кроме того, вы, вероятно, не можете вызвать метод родительского теста от ребенка, потому что он закрытый, и вы можете получить доступ только к закрытому методу из класса, который его объявляет. Даже при использовании parent вы не можете разрешить область видимости. Единственный способ, которым я могу назвать это, - это использовать отражение (в частности, ReflectionMethod), а затем установить для него доступность. Это будет считаться довольно уродливым хаком.

class foo{
    private function test($var){
        echo $var;
    }
}


class bar extends foo{
  public function actionIndex($var){
      $this->test($var);
  }

  private function test($var){
      $R = new ReflectionMethod(parent::class, 'test');
      $R->setAccessible(true);
      $R->invoke(new parent, $var);
      //$this->test($var); //recursive
  }
}

(new bar)->actionIndex('Hello from parent');

выход

Hello from parent

Песочница

Проблема, с которой вы столкнетесь, заключается в том, что вам нужен экземпляр parent для вызова метода, которого у вас нет, и при вызове new вы потеряете любое состояние дочернего объекта. Поэтому любые свойства, установленные в дочернем элементе, не будут передаваться, даже если они определены в родительском объекте (если они не заданы в конструкторе и т. Д.). Это может быть или не быть приемлемым.

Чтобы сделать его рекурсивным, довольно просто, просто добавьте $this->test() в методе потомка после части отражения. Конечно, это создаст бесконечный цикл, но что угодно.

...