PHP7 在条件 (if) 中的 require(外部文件)中定义的 const 有效 - 为什么?

PHP7 const defined within a require (external file) within a conditional (if) is working - why?

在调试大量代码时,我遇到了以下与我的调试完全无关的代码。我确实花了很多时间 Google 寻找一个合理的解释:

声明const,在function,在条件(if),在require包含的外部文件。 注意:这未定义为 class 结构的一部分!!

由于这个 const 是在条件上下文中定义的,所以它是 运行 时间? vs compile/parse-time,这应该(恕我直言)给出了错误,但不仅没有错误,而且代码已经 运行 完美地投入生产超过三年!

很想听听专家的解释,甚至是我明显遗漏了什么的线索!

Q1。为什么常量 _DEFITEM 不报错?

Q2。为什么常量 _DEFITEM 可以工作,即使它不是使用 define 定义的?

在此先感谢您,尤其是 JS,感谢这个社区在过去十年中所做的出色工作!

参考:

PHP Manual

If an include() is conditional, will PHP include the file even if the condition is not met?

https://wordpress.stackexchange.com/questions/143439/conditionally-include-files-in-functions-php

CODE:带有被调用函数的简单存根,检查“SAVE”的按值传递参数,有条件地包括(始终可用)保存模块文件,然后调用它的main函数。包含的(需要)保存模块文件在顶部有 const 声明。

Contrived, but accurate code representation below! Ellipses represent other code

//  main_stub3.php     php file processing client request (included within a main page/script)
<?php
function list_view_save_proc_stub3 (fn_param1, fn_param2...)  {
...
if ("VIEW" === fn_param2)  {
   ...
}
else
if ("SAVE" === fn_param2)  {
   ...
   require _INC . proj_save_module_file.php;           //  _INC is a global constant (path)
   sv_mod_fn ();
}
else
   ...
}  //  END fn list_view_save_proc_stub3
//  END main_stub3.php


//  proj_save_module_file.inc   include file that contains a const declaration and a function
const _DEFITEM = [ 'it_id' => 0, 'it_name' => '', ... ];   //  about ~50 items in array

function sv_mod_fn ()  {
//  some std error checking, building of a row, db connectivity and insertion +
//  message output to client
...
}

人们经常谈论 PHP 作为一种“脚本”甚至“解释”语言,但像大多数现代语言一样,它确实有不同的 编译执行步。很多细节通常不相关,但对您在这里的误解至关重要。

PHP 在第一次需要时编译文件;它还可以(通过 the OpCache extension)缓存此编译的结果。重要的是,它总是一次编译一个文件,无论该文件的使用方式如何。因此,在编译时发生的一切都基于仅查看该单个文件就可以知道的内容。

一旦文件被编译,它就可以被执行任意次数(在同一个请求中,或者稍后从 OpCache 内存中获取)。所以在执行时发生的一切都可以知道它在 运行 中的当前上下文的一切。

要理解你的代码,你只需要知道两件事:

  • const 在编译时求值
  • require 在执行时计算

手册中说 const 不能用在条件语句中的意思是,当文件被编译时,定义无条件地成为编译代码的一部分。该文件所属的每个程序都将包含该常量定义。这与 define 不同,后者的编译有点像函数调用——它变成了一个标记,表示“当程序执行到这一点时,定义这个常量”。

但是,编译该文件并不会使其成为您程序的一部分。要真正使其成为您程序的一部分,您可以在执行时使用 require(或其亲戚),

只有当 require 行被执行时,编译后的文件才会成为您的 运行 程序的一部分。它可能会在执行时及时编译,或者从几小时前编译的 OpCache 中获取,但无论哪种方式,只有在实际达到 require 时才会 执行 require 可以是可选的,因此您可以根据星期几、随机地或根据用户输入决定包含不同的文件。

就 PHP 而言,const 定义被 无条件编译 成一个代码单元 有条件地包含在您的程序中.