2015-03-19 3 views
0

Запуск PHP 5.4, так что я не ожидал этого, но я встречая следующее сообщение об ошибке:ошибка при использовании имени переменной класса и статический метод

Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM) 

Предположим, у вас есть переменная stdClass установки следующим образом :

$this->variable = new stdClass(); 

$this->variable->other = array('class' => 'helloworld'); 

Теперь предположим, что вы хотите получить доступ к статическим методом класса helloworld:

// Standard call 
$x = helloworld::my_static_method(); 

// Call with variable class name 
$x = $this->variable->other['class']::my_static_method(); 

Когда вы вызываете это, используя имя класса переменной, я получаю ошибку синтаксического анализа. Что странно, что если я делаю следующее, не представлено никакой ошибки:

$class = $this->variable->other['class']; 

$x = $class::my_static_method(); 

Мне это кажется очень странным, может кто-нибудь придумать причину, почему имя класса не разделяющим правильно при использовании первого примера против второго?

ответ

1

can anyone think of a reason why the class name isn't resolving correctly when using the first example versus the second?

Парсер PHP не поддерживает такой синтаксис, и это просто все. Это объясняется тем, что парсер исторически вырос. Я не могу дать больше оснований.

Это будет, что с PHP 7 вы можете увидеть некоторые изменения в этих деталях синтаксиса работает больше в ожидаемом направлении Uniform Variable Syntax:

($variable->other['class'])::my_static_method(); 

Но до тех пор, вы можете ходить, что с помощью call_user_func:

call_user_func([$variable->other['class'], 'my_static_method']); 
call_user_func($variable->other['class'] . '::my_static_method'); 

Или как вы написали свой собственный, создав переменную:

$class = $variable->other['class']; 
$class::my_static_method(); 

Или даже переменная, которая выглядит как что-то другое:

${(int)!${0}=$variable->other['class']}::my_static_method(); 

Материалы по теме:

+0

Спасибо за объяснение , Приятно видеть, что они будут поддерживать более экзотическое использование синтаксиса для PHP 7. –

+0

Я не буду говорить, что синтаксис PHP 7 является экзотическим, даже наоборот: он более последователен. И я рад, что с этим наконец занялись :) – hakre

1

Это не работает ($this->variable->other['class']::my_static_method()), поскольку он по сути использует строку в качестве имени класса напрямую. Он работает, когда вы сначала назначаете его переменной, так как тогда ее оценивают как имя класса.

Вы также можете использовать вызов ReflectionMethod, чтобы вызвать метод, и в этом случае вам не нужно было бы хранить имя класса в переменной перед его использованием. Вот документацию о том, что: http://php.net/manual/en/class.reflectionmethod.php и на методе invoke (вы передаете в NULL указать статический метод) http://php.net/manual/en/reflectionmethod.invoke.php

Вот несколько примеров способов вызывающими вашей функции:

class helloworld{ 
    public static function my_static_method($i = 0){ 
     echo "Here: ".$i; 
    } 
} 

class Foo{ 
    private $variable; 

    public function __construct(){ 
     //Create a new class 
     $this->variable = new stdClass(); 

     //Create a new property of the class, storing an array 
     $this->variable->other = array('class' => 'helloworld'); 

     //Call function statically 
     $x = helloworld::my_static_method(1); //Outputs: "Here: 1" 

     //Store class name in a variable before use 
     $class = $this->variable->other['class']; 
     $y = $class::my_static_method(2); //Outputs: "Here: 2" 

     //Using a ReflectionMethod, you can call the function this way, too 
     $z = new ReflectionMethod($this->variable->other['class'], 'my_static_method'); 
     $z->invoke(null, 3); //Outputs: "Here: 3" 
    } 
} 

//Instantiate new Foo class 
new Foo(); 
+0

Интересно - Я думаю, я просто любопытно, почему (в вашем примере) ' $ class' разрешает корректно, но '$ this-> variable-> other ['class']' does not? На мой взгляд, обе переменные разрешают строку «helloworld». В своем комментарии «...он по сути использует строку как имя класса напрямую. Он работает, когда вы сначала назначаете его переменной, так как тогда ее оценивают как имя класса. «Почему они не оцениваются с именем класса? –

+0

Это также интересно, потому что вызов' new $ this-> variable_> other ['class']() 'works ... не подпадает под ту же проблему? –

+1

Итак, интересно, когда вы используете' $ this-> variable-> other ['class' ] 'он оценивается как строка. Строки не имеют метода' :: '(т. е. парсер не распознает статический метод вызова строки), поэтому вам нужно использовать переменную (в этом случае синтаксический анализатор может оценивать содержимое переменной как класс, и работает статический вызов метода). Со вторым комментарием, поскольку вы больше не используете вызов статического метода, '$ this-> variable-> other ['class']() 'работает как ожидалось. –

Смежные вопросы