PHP属性decleration接受数组,不接受可在编译过程中评估的任何其他表达式

问题描述 投票:4回答:1

在PHP学习oop时,我注意到属性声明接受一个数组作为这里提到的值PHP documentation

class Test{
      public $var7 = array(true, false);
}     

我注意到文档说:

此声明可能包括初始化,但此初始化必须是常量值 - 也就是说,它必须能够在编译时进行评估,并且必须不依赖于运行时信息才能进行评估。

在阅读this文章以了解编译过程如何工作之后,我意识到在编译过程中,如果有可能像下面的代码片段那样评估和优化一些表达式:

var x = strlen ("testing") => int(7);

如果在声明属性的过程中使用数组作为值,因为它在编译过程中被计算,那么为什么在编译过程中可以在逻辑上对它们进行评估时,下面的初始化不起作用,这是初始化属性的条件。类?

     Class Test {
          public $vars=strlen("random"); // Fails
     }
php oop properties
1个回答
3
投票

对你的问题的简短回答是strlen()是一个函数,而array()keyword

要理解的关键区别在于,无论上下文如何,关键字始终引用相同的内容。

来自php.net:

这些词在PHP中具有特殊意义。其中一些代表看起来像函数的东西,一些看起来像常量,等等 - 但它们不是,真的:它们是语言结构。您不能将以下任何单词用作常量,类名,函数或方法名称。

另一方面,函数可以根据您调用它们的位置进行不同的定义。

考虑这个简单的例子:首先我们称之为“functions.php”的文件。

//functions.php
namespace My_Project_Namespace;

function strlen($string){
    return 10;  //In my project, all strings are length 10! 10 is a nice round number...
} 

在这个文件中,我用另一个覆盖了内置的strlen()函数。这是可能的,因为我的函数是在namespace(在本例中为My_Project_Namespace)中定义的。

现在考虑一下你的文件,但是这一次让它放在我们的命名空间中(你应该将所有函数和类命名为间距)

//Test.php
namespace My_Project_Namespace;

Class Test {
    public $vars=strlen("random"); // Fails
}

strlen()有2个定义,具体取决于命名空间。由于知道当前命名空间取决于运行时信息,因此编译器无法知道在类中初始化使用哪个。即使您没有定义自定义strlen()函数,您仍然无法执行此操作,因为知道没有其他版本strlen()也取决于运行时信息!

array()是一个完全不同的野兽。它是一个关键字,你不能为array()定义另一个含义,所以编译器不必担心一个现有的。

© www.soinside.com 2019 - 2024. All rights reserved.