PHP属性Decellation接受数组,不接受编译过程中可能计算的任何其他表达式

PHP属性Decellation接受数组,不接受编译过程中可能计算的任何其他表达式,php,oop,properties,Php,Oop,Properties,在研究PHP中的oop时,我注意到属性声明接受数组作为值,如本文所述 我注意到文件上说: 该声明可能包含一个初始化,但该初始化必须是一个常量值——也就是说,它必须能够在编译时进行计算,并且必须不依赖于运行时信息才能进行计算 在阅读了文章以了解编译过程是如何工作的之后,我意识到在编译过程中,如果可能的话,一些表达式将被评估和优化,如下面的代码片段: var x = strlen ("testing") => int(7); 如果在声明属性时使用数组作为值是有效的,因为它是在编译过程中求值的

在研究PHP中的oop时,我注意到属性声明接受数组作为值,如本文所述

我注意到文件上说:

该声明可能包含一个初始化,但该初始化必须是一个常量值——也就是说,它必须能够在编译时进行计算,并且必须不依赖于运行时信息才能进行计算

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

var x = strlen ("testing") => int(7);
如果在声明属性时使用数组作为值是有效的,因为它是在编译过程中求值的,那么如果在逻辑上它们都可以在编译过程中求值,并且这是初始化类中属性的条件,那么为什么下面的初始化不起作用呢

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

您的问题的简短答案是
strlen()
是一个函数,而
array()
是一个函数

要理解的关键区别在于,关键字总是引用相同的内容,而与上下文无关

从php.net:

这些词在PHP中有特殊的含义。其中一些表示的东西看起来像函数,一些看起来像常量,等等——但实际上它们不是:它们是语言结构。不能将以下任何单词用作常量、类名、函数或方法名

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

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

在这个文件中,我将用另一个函数覆盖内置的
strlen()
函数。这是可能的,因为我的函数是在命名空间中定义的(在本例中,
myproject\u命名空间

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

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


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

如果名称空间中定义了另一个
strlen
函数,该怎么办?@u\u mulder:请您澄清一下,因为我是OOP初学者。有时调用内部函数可以在编译过程中进行优化,他们会的,但不总是这样。这就是为什么声明只接受常量值。手册可能应该读“例如”或“至少”,而不是“那是”。但我不知道有多少人认为任何可以分析/优化的东西都是声明的有效语法。@jh1711&u_mulder:你们都是对的。谢谢你的澄清。谢谢你简单明了的信息,你回答了我所有的想法,谢谢你的时间。
     Class Test {
          public $vars=strlen("random"); // Fails
     }
//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...
} 
//Test.php
namespace My_Project_Namespace;

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