【问题标题】:What's the point of having both include and require constructs in PHP?在 PHP 中同时包含 include 和 require 结构有什么意义?
【发布时间】:2011-05-14 23:24:29
【问题描述】:

我是第一次编写 PHP 应用程序(除了玩具和练习),我不明白为什么 PHP 会同时包含 includerequire 构造。

在你写一个解释两者之间差异的答案之前,让我先说我确实理解差异 - include 产生一个警告并继续前进,require 产生一个致命错误。我的问题是:您什么时候想包含但不需要文件?

也许这是我的想象力失败,但我的应用程序中似乎没有任何文件,如果它们不存在,我不想尖叫。奇怪的是,这让我想使用require,因为似乎无法正确处理失败的require,所以我使用了一个辅助函数(警告:空气代码):

public static function include($filename) {
  if (is_readable($filename)) {
    if (!@include($filename)) {
      throw new FileNotFoundException("File deleted after readable check");
    }
  } else {
    throw new FileNotFoundException("File missing or unreadable");
  }
}

我想我要问的是:

  • 您真正希望可选在应用程序中包含哪些类型的文件?
  • 无论您希望文件是必需还是可选,您为什么不直接在函数中处理它,比如我编写的代码的修改版本上面?

【问题讨论】:

  • @Gordon -- 我会链接到你的答案,我发现它比接受的答案更有用:) stackoverflow.com/questions/2418473/…
  • @Agent 可能的示例:require 'defaultSettings.php'; include 'userProvidedOverloadForDefaultSettings.php'; 基本上,可以包括任何覆盖现有值或在未给出时不会立即破坏您的应用程序的内容。我同意大多数时候你会想要使用require
  • @Agent IMO,尝试处理无法处理的情况或在无论如何都无法捕获时抛出异常是没有意义的。缺少核心库是无法处理的。你能做的最好的就是告诉用户。但为此,您可以只使用register_shutdown_functionerror_get_last() 来查看是否有错误并发送一个500 标题和一个漂亮的页面。但是话又说回来,是的,对于那些无法处理的情况,您也可以使用 include 和 set_exception_handler。我不会想太多。务实。使用有效的方法。
  • @Gordon:这是有道理的。在他的回答下与@deceze 进行了一番交谈后,我意识到我的整个问题是多么愚蠢。如果它达到了一个重要的类或模板文件完全丢失的地步,要么我搞砸了,我需要承认和道歉,要么服务器发生了一些疯狂的事情,在这种情况下,它超出了我的控制范围,我有托管公司的完美替罪羊;)我真的需要接受“现在有效”的理念。我不断陷入过早优化和建筑航天的陷阱。

标签: php include language-design require


【解决方案1】:

我会使用require 来加载应用程序本身所必需的文件,即require 'database_config.php'require 'core.php'。如果这失败了,你希望它尽可能快速、艰难和无情地失败,因为你的应用程序安装显然有问题。在这种状态下,它甚至不能保证它可以正确处理抛出的异常,require 会在没有任何额外代码的情况下生成非常清晰的错误消息。

include 应该用于模板文件之类的内容,您希望在应用程序已经启动并运行并且可以优雅地处理自己的错误时使用它们。


例子:

include 'error_handler.php';
set_error_handler('error_handler');

/* something bad happens */

Warning: 'error_handler.php' not found!
Error: Specified error handler "error_handler" doesn't exist.

在某些时候,您只是依赖基本文件,即使它只是您的错误处理程序。你必须引入额外的代码来优雅地处理丢失的错误处理程序,即使那样你能做的最好的就是输出一些错误和die(除非你想优雅地进入捕获错误的游戏,即使你的错误处理程序不存在)。最好直接require 'error_handler.php';如果你愿意,你可以include 和自定义处理这之后的所有事情。

【讨论】:

  • 对我来说,缺少模板文件似乎是一件非常关键的事情。它向我表明应用程序部署不正确或某些关键的东西(我确实认为“实际显示给用户的东西”是关键的)神秘地消失了,使应用程序处于不稳定状态。我宁愿在我的函数中捕获所有这些并抛出一个警告我的异常,而不是仅仅向用户抛出一个丑陋的die() 消息。也许我还远远没有找到我认为不重要的文件。
  • @Agent 我敢肯定@deceze 在说优雅时并不是指die ;)
  • @Agent 当然,缺少模板文件是一件可怕的事情。这就是为什么您尝试include 并记录错误、发送电子邮件并在找不到 404 页面时优雅地提供它的原因。当找不到基本的required 文件时,应用程序无法执行所有这些操作,这就是为什么您使用includerequire 的原因。
  • @Gordon:在我的问题中,我说我反对require。我宁愿在任何地方都使用include(或include_once),包裹在一个函数/助手类中,这在所有情况下都是优雅的,但是当事情真正发生时,我知道如何正确地抱怨扇子。我并不是要暗示我认为@deceze 是在倡导die()
  • @deceze:您在评论中有点为我辩护,因为您在危急情况下提倡include,这正是我的观点。我认为include 对所有情况都足够了,并在其周围进行了适当的错误处理,因此即使在关键的需要使用的情况下也很有用。
【解决方案2】:

你真的想要什么样的文件 希望有选择地包含在 申请?

我通常将include 与静态HTML 块(页眉、页脚、菜单、搜索框、调查表...)一起使用,将require 与PHP 函数或类一起使用。页脚块不太可能消失,但是,我想当我查看代码时,这是一个很好的视觉线索。

你是否想要一个文件 必需或可选,你为什么不呢 只需在一个函数中处理它 我写的代码的修改版本 上面?

据说@操作符很贵,反正我觉得包含外部文件是基本的操作,应该被基本语言覆盖。您的代码还添加了一个新依赖项:如果您将其存储在 required 块中,您的可选块将不再是 100% 可选的;-)

【讨论】:

  • 我不知道@到底有多贵。我只是进行了一些检查,当我实际直接写入数据时,错误抑制功能始终比未抑制版本更快(相当大的差距)。我在开头添加了ob_start,在所有处理后添加了ob_clean,未压缩的版本稍快(每次迭代25k后0.04秒)。我将 ob_clean 调用移动到每个包含函数中(即,缓冲区将在每次包含后立即被清理)并得到类似的结果。单个数据点,确实如此,但 @ 可能不会造成那么严重的伤害。
  • @Agent Please heed the Warning in the PHP Manual。您应该不惜一切代价避免使用错误抑制运算符。您不想盲目地对未来的 50k LOC 应用程序进行故障排除 :)
猜你喜欢
  • 1970-01-01
  • 2015-11-30
  • 2022-01-22
  • 2010-10-10
  • 2012-07-17
  • 2011-02-12
  • 2010-09-24
  • 2021-04-21
  • 1970-01-01
相关资源
最近更新 更多