[英]Why can you instantiate a class from a string variable but not a string in PHP?
解析器的實現不是通用的,因此在某些情況下,解析器會打擾引擎實際上可以處理的事情。 那里(仍然)甚至不是PHP的官方正式語法,這使得很難預測這樣的事情,而不是簡單地嘗試它們。 這是PHP世界的方式:)
PHP期望對象定義的變量或名稱引用,它只是不允許字符串。 你可以使用這個基於''空字符串命名變量的hack立即根據${false}
計算到${''}
的事實創建和使用,如下所示從字符串創建一個對象:
$obj = new ${!${''} = 'App\MyClass'}();
PHP語法在zend_language_parser.y中定義,它不會為new
運算符定義任何更復雜的表達式:
new_expr:
T_NEW class_name_reference ctor_arguments
{ $$ = zend_ast_create(ZEND_AST_NEW, $2, }
| T_NEW anonymous_class
{ $$ = $2; }
class_name_reference:
class_name { $$ = $1; }
| new_variable { $$ = $1; }
new_variable
允許一組有限的變量表達式:
new_variable:
simple_variable
{ $$ = zend_ast_create(ZEND_AST_VAR, $1); }
| new_variable '[' optional_expr ']'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| new_variable '{' expr '}'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| new_variable T_OBJECT_OPERATOR property_name
{ $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
| class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable
{ $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
| new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable
{ $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
// Copyright (c) 1998-2015 Zend Technologies Ltd., the Zend license 2.00
這就是為什么你不能在那里有字符串表達式。 (它從未被擴展,因為普通的實例化和$ classvarnames通常就足夠了。因此,當引入它時,允許的語法與PHP3中的大致相同。)
這是因為運算符優先級: http : //php.net/manual/en/language.operators.precedence.php
因為'new'的優先級高於''。 它首先被處理。
就你的代碼而言,編譯器看到的是:
$myClass = 'MyClass';
$object = new 'App\\';
$object = $object . $myClass;
對於問題的第二部分,為什么: $object = new 'App\\MyClass'
; 不起作用。 我不確定。
如果我不得不猜測我會說這是因為當你執行new 'App\\MyClass'
,解析器在遇到它時不知道它是一個字符串。 直到該行已被處理,它不知道它是否處理字符串,數字,對象等。它可以發現並正確地將其轉換為字符串,但我猜這會回到運算符優先級,它不會在處理'new'運算符之前,執行這些類型的強制轉換。
奇怪的是,我剛剛在Quercus PHP中測試它並運行良好。 正如其他人提到的那樣,php並不是一種完全定義的語言,所以像這樣的東西表現為實現之間的差異。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.