Php 用额外的步骤从字符串初始化类?
我一直在研究用PHP中的字符串来证实一个新的类实例。这似乎是一个可以接受的过程,但是我很好奇为什么不能用函数调用的返回来完成。我在下面发布了一个简短的测试,结果表明,如果存在一个变量中介,即$bar=new$foo->callBar,那么它就可以工作;当$x=$foo->callBar时,不工作$bar=新的$x;是的 警告:未捕获错误:类名必须是有效的对象或字符串 在php shell代码中:1堆栈跟踪: 第1行php外壳程序代码中抛出0{main}Php 用额外的步骤从字符串初始化类?,php,string,class,initialization,Php,String,Class,Initialization,我一直在研究用PHP中的字符串来证实一个新的类实例。这似乎是一个可以接受的过程,但是我很好奇为什么不能用函数调用的返回来完成。我在下面发布了一个简短的测试,结果表明,如果存在一个变量中介,即$bar=new$foo->callBar,那么它就可以工作;当$x=$foo->callBar时,不工作$bar=新的$x;是的 警告:未捕获错误:类名必须是有效的对象或字符串 在php shell代码中:1堆栈跟踪: 第1行php外壳程序代码中抛出0{main} 我很想知道为什么会这样,或者如果我错了,那
我很想知道为什么会这样,或者如果我错了,那么正确的解释是什么?我知道使用new创建类实例有四种方法: 直接命名类:$bar=newbar; 直接使用变量:$barName='Bar'$bar=新的$barName; 使用对象属性:$obj=object['barName'=>'Bar']$bar=新的$obj->barName; 使用现有实例:$bar1=新条$bar2=新的$bar1; 您的问题的前半部分答案是PHP解析器:它禁止许多可以用来构建黑客的东西,比如new Foo和new Foo
第二部分可能隐藏在PHP源代码中:这会引发异常。我知道,使用new创建类实例有四种选择: 直接命名类:$bar=newbar; 直接使用变量:$barName='Bar'$bar=新的$barName; 使用对象属性:$obj=object['barName'=>'Bar']$bar=新的$obj->barName; 使用现有实例:$bar1=新条$bar2=新的$bar1; 您的问题的前半部分答案是PHP解析器:它禁止许多可以用来构建黑客的东西,比如new Foo和new Foo
第二部分可能隐藏在PHP源代码中:这会引发异常。如PHP手册中所述,new关键字接受字符串或对象作为类名。您可以选择在末尾的括号中为构造函数提供参数 这意味着语法大致预期:
new [string|object] ()
// ^^ keyword ^^ name ^^ optional parentheses
另一个重要的事实是,关键字new在所有运算符中具有最高的优先级
将这两个事实结合在一起意味着我们不能使用括号来增加new关键字操作的优先级。如果我们使用括号,PHP会将其视为新语法的可选部分。像这样的事情是行不通的
$bar = new ($foo->callBar());
// ^ missing class name
没有明确的方法告诉PHP解析器以其他方式处理这个问题
还有另一个值得记住的警告,爱德华·苏洛夫在他的回答中部分提到了这一点。类名可以来自字符串或实例的任何变量。
以下代码将创建Bar类的对象:
那么,让我们来解释一下代码的作用
new $foo->callBar ()
// ^^ keyword ^^ name ^^ optional parentheses
因为您的Foo类没有属性调用栏,所以它将触发通知消息,但PHP将检查它是否可以用作类名。因为它不存在,所以不能是字符串或实例,这就是为什么您会看到错误
这在PHP8中已经修复。
委员会讨论了这个问题。现在,您可以在创建类的实例时使用表达式。唯一需要注意的是运算符的优先级。调用函数/方法时,应使用它来表示优先级。例如:
$bar = new ( $foo->callBar() ) ();
// ^^ expression ^^ optional parentheses
正如PHP手册中所述,new关键字接受字符串或对象作为类名。您可以选择在末尾的括号中为构造函数提供参数 这意味着语法大致预期:
new [string|object] ()
// ^^ keyword ^^ name ^^ optional parentheses
另一个重要的事实是,关键字new在所有运算符中具有最高的优先级
将这两个事实结合在一起意味着我们不能使用括号来增加new关键字操作的优先级。如果我们使用括号,PHP会将其视为新语法的可选部分。像这样的事情是行不通的
$bar = new ($foo->callBar());
// ^ missing class name
没有明确的方法告诉PHP解析器以其他方式处理这个问题
还有另一个值得记住的警告,爱德华·苏洛夫在他的回答中部分提到了这一点。类名可以来自字符串或实例的任何变量。
以下代码将创建Bar类的对象:
那么,让我们来解释一下代码的作用
new $foo->callBar ()
// ^^ keyword ^^ name ^^ optional parentheses
因为您的Foo类没有属性调用栏,所以它将触发通知消息,但PHP将检查它是否可以用作类名。因为它不存在,所以不能是字符串或实例,这就是为什么您会看到错误
这在PHP8中已经修复。
委员会讨论了这个问题。现在,您可以在创建类的实例时使用表达式。唯一需要注意的是运算符的优先级。调用函数/方法时,应使用它来表示优先级。例如:
$bar = new ( $foo->callBar() ) ();
// ^^ expression ^^ optional parentheses
相关的:相关的: