我读到的关于更好的 PHP 编码实践的所有内容都在说不要使用 require_once
因为速度。
为什么是这样?
与 require_once
做同样事情的正确/更好的方法是什么?如果重要的话,我正在使用 PHP 5。
原文由 Uberfuzzy 发布,翻译遵循 CC BY-SA 4.0 许可协议
我读到的关于更好的 PHP 编码实践的所有内容都在说不要使用 require_once
因为速度。
为什么是这样?
与 require_once
做同样事情的正确/更好的方法是什么?如果重要的话,我正在使用 PHP 5。
原文由 Uberfuzzy 发布,翻译遵循 CC BY-SA 4.0 许可协议
它没有使用不好的功能。在整个代码库中,这是对如何以及何时使用它的错误理解。我将为这个可能被误解的概念添加更多上下文:
人们不应该认为 require_once 是一个缓慢的函数。您必须以一种或另一种方式包含您的代码。 require_once()
与 require()
的速度不是问题。这是关于性能阻碍可能导致盲目使用它的警告。如果在不考虑上下文的情况下广泛使用,可能会导致大量内存浪费或代码浪费。
我所看到的非常糟糕的是,当巨大的单体框架以所有错误的方式使用 require_once()
时,尤其是在复杂的面向对象 (OO) 环境中。
以在许多库中看到的每个类的顶部使用 require_once()
为例:
require_once("includes/usergroups.php");
require_once("includes/permissions.php");
require_once("includes/revisions.php");
class User{
// User functions
}
所以 User
类被设计为使用所有其他三个类。很公平!
但是现在,如果访问者正在浏览该站点并且甚至没有登录并且框架加载: require_once("includes/user.php");
对于每个请求。
它包括在该特定请求期间永远不会使用的 1+3 个 不必要 的类。这就是臃肿的框架最终使用 40 MB 每个请求而不是 5 MB 或更少的原因。
它可能被滥用的其他方式是当一个类被许多其他人重用时!假设您有大约 50 个类使用 helper
函数。为了确保在加载这些类时 helpers
可用于这些类,您将获得:
require_once("includes/helpers.php");
class MyClass{
// Helper::functions(); // etc..
}
这里本身没有错。但是,如果一个页面请求恰好包含 15 个类似的类。您正在运行 require_once
15 次,或者为了获得漂亮的视觉效果:
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
除了必须解析那些不必要的行之外,使用 require_once() 在技术上会影响运行该函数 14 次的性能。只有 10 个其他高度使用的类具有类似的问题,它可以解释 100 多行这种相当无意义的重复代码。
有了这个,在你的应用程序或框架的引导程序中使用 require("includes/helpers.php");
可能是值得的。但由于一切都是相对的, 这完全取决于 helpers
类的重量与使用频率是否值得节省 require_once()
的 15-100 行。但是,如果在任何给定请求上不使用 helpers
文件的可能性为零,那么 require
绝对应该在您的主类中。在每个类中分别 require_once
会浪费资源。
require_once
函数在必要时很有用,但它不应被视为在任何地方用于加载所有类的单一解决方案。
原文由 hexalys 发布,翻译遵循 CC BY-SA 4.0 许可协议
1 回答4.1k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
2 回答2.2k 阅读✓ 已解决
1 回答1.4k 阅读✓ 已解决
2 回答2.2k 阅读
1 回答592 阅读✓ 已解决
792 阅读
require_once
和include_once
都要求系统记录已经包含/需要的内容。每个*_once
调用都意味着检查该日志。所以肯定 有一些 额外的工作在那里完成,但足以损害整个应用程序的速度?…我真的 很 怀疑…除非您使用的是 非常 旧的硬件或经常这样做,否则不会。
如果您 正在 做数以千计的
*_once
,您可以以更轻松的方式自己完成工作。对于简单的应用程序,只需确保 只 包含一次就足够了,但如果您仍然遇到重新定义错误,您可以这样做:我个人会坚持使用
*_once
声明,但在愚蠢的百万通过基准测试中,您可以看到两者之间的区别:使用
require_once
慢 10-100 倍,奇怪的是require_once
在hhvm
--- 中似乎更慢。同样,这仅在您运行*_once
数千次时才与您的代码相关。