PHP包含语义


PHP include semantics

我正试图找出如何解释PHP的include结构,例如是否包含文本,当它被评估等。像往常一样,文档是非正式和模糊的。

根据实验,

似乎是语法糖。具体来说,结构

include 'Baz.php'

是一个表达式,可以用

代替。
eval('?>' . file_get_contents('Baz.php',  FILE_USE_INCLUDE_PATH))

正确吗?这个替换在一般情况下是正确的,还是只在我的测试中是正确的?

编辑:正如bwoebi所指出的,这通常是不正确的,因为eval估计的代码没有相同的__DIR____FILE__魔术常数。如果有办法设置它们,我们也可以建立模型。

编辑2:这个问题是这个问题的副本:相当于include使用eval。然而,所有的答案似乎都忽略了bwoebi关于文件路径上下文的观点。

是的,这应该是正确的。

唯一的区别是:

  • 文件上下文(现在是eval()'ed code,而不是来自该文件的代码)
  • 相对路径:当你在其他目录中包含文件并且它们使用自己的相对路径时,它指向的文件现在可能不再被找到
  • file_get_contents()不受allow_url_include ini设置的影响(尽管allow_url_fopen影响两者)

其他需要注意的是:

  • 这将破坏PHP操作码缓存,因为文件内容作为文本读取到内存中,然后解析/求值,如果您不期望它,则会对性能产生重大影响。如问题所述。
  • 代码中的解析错误对脚本的其余部分不会是致命的,它的副作用是允许脚本继续执行,即使预期发生的逻辑可能没有发生。(其他类型的错误也可能如此)。
  • 错误报告不会解析到正确的文件/行,因此,调试将变得困难。
  • 这将不支持_once结构,该结构允许严格地包含/要求文件一次。这意味着重复的类/函数声明将是致命的和/或行为异常。

我确信还有其他的考虑也使这是不可取的。在不知道你想要的功能或你需要这样做的原因的情况下,给你一个有用的答案是很困难的。

使用eval最好的部分是从错误中恢复(如果你可以称之为"最好的"事情)。但是,如果这是您想要利用的好处,那么这是您唯一的选择....不幸的是…