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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP属性decleration接受数组,不接受可在编译过程中评估的任何其他表达式相关的知识,希望对你有一定的参考价值。

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
     }
答案

对你的问题的简短回答是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()定义另一个含义,所以编译器不必担心一个现有的。

以上是关于PHP属性decleration接受数组,不接受可在编译过程中评估的任何其他表达式的主要内容,如果未能解决你的问题,请参考以下文章

为啥不接受 Map 构造函数的可迭代元组数组?

Vuetify Data-Table Header 数组不接受空子关联

python进阶之装饰器之2.定义一个可接受参数的装饰器如何定义一个属性可由用户修改的装饰器定义一个能接受可选参数的装饰器

asp.net的GridView控件的onrowdeleting属性怎么出错显示为找不到可接受类型。。。呢

如何将数组传递给接受带有 splat 运算符的属性的方法?

CentOS PHP curl 无法协商一组可接受的安全参数