Как указано в руководстве по PHP, ключевое слово new
принимает строку или объект в качестве имени класса.При желании вы можете указать аргумент для конструктора в скобках в конце.
Это означает, что синтаксис приблизительно ожидает:
new [string|object] ()
// ^^ keyword ^^ name ^^ optional parentheses
Другим важным фактом является то, что ключевое слово new
имеетвысший приоритет всех операторов.
Объединение двух фактов вместе означает, что мы не можем использовать скобки, чтобы увеличить приоритет операции с ключевым словом new
.Если мы используем круглые скобки, PHP будет рассматривать их как необязательную часть синтаксиса new
.Что-то вроде этого не сработает.
$bar = new ($foo->callBar());
// ^ missing class name
Нет просто однозначного способа сказать PHP-парсеру, чтобы он воспринимал это иначе.
Есть еще одна оговорка, о которой стоит помнить, о которой Эдуард Суров частично упомянул в своем ответе.Имя класса может происходить из любой переменной , которая является строкой или экземпляром.
Следующий код создаст объект класса Bar
, который, по-видимому, нарушает приоритет оператора.На данный момент я до сих пор не понимаю это поведение.
$obj = ['a'=>'Bar'];
$bar = new $obj['a'];
// or
$obj = (object) ['a'=>'Bar'];
$bar = new $obj->a;
Итак, давайте объясним, что делает ваш код.
new $foo->callBar ()
// ^^ keyword ^^ name ^^ optional parentheses
Поскольку ваш класс Foo
не имеет свойства callBar
, он вызовет сообщение Notice, но PHPпроверит, может ли оно быть использовано в качестве имени класса в любом случае.А поскольку он не существует, он не может быть строкой или экземпляром, поэтому вы видите ошибку.