php 为什么 require_once 不好用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/186338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:50:32  来源:igfitidea点击:

Why is require_once so bad to use?

phpperformancerequire-once

提问by Uberfuzzy

Everything I read about better PHP coding practices keeps saying don't use require_oncebecause of speed.

我读到的关于更好的 PHP 编码实践的所有内容都在说不要require_once因为速度而使用。

Why is this?

为什么是这样?

What is the proper/better way to do the same thing as require_once? If it matters, I'm using PHP 5.

做同样事情的正确/更好的方法是什么require_once?如果重要的话,我使用的是 PHP 5。

采纳答案by Oli

require_onceand include_onceboth require that the system keeps a log of what's already been included/required. Every *_oncecall means checking that log. So there's definitely someextra work being done there but enough to detriment the speed of the whole app?

require_once并且include_once两者都要求系统记录已包含/需要的内容。每次*_once调用都意味着检查该日志。所以肯定有一些额外的工作在那里完成,但足以损害整个应用程序的速度?

... I really doubt it... Not unless you're on reallyold hardware or doing it a lot.

......我真的很怀疑......除非你是在真正的老硬件或做一个不少

If you aredoing thousands of *_once, you could do the work yourself in a lighter fashion. For simple apps, just making sure you've only included it once shouldsuffice but if you're still getting redefine errors, you could something like this:

如果你正在做成千上万的工作*_once,你可以以更轻松的方式自己完成这项工作。对于简单的应用程序,只是确保你只包括一次应该足够了,但如果你仍然得到重新定义错误,你可以是这样的:

if (!defined('MyIncludeName')) {
    require('MyIncludeName');
    define('MyIncludeName', 1);
}

I'll personally stick with the *_oncestatements but on silly million-pass benchmark, you can see a difference between the two:

我个人会坚持这些*_once陈述,但在愚蠢的百万通过基准测试中,您可以看到两者之间的区别:

                php                  hhvm
if defined      0.18587779998779     0.046600103378296
require_once    1.2219581604004      3.2908599376678

10-100× slower with require_onceand it's curious that require_onceis seemingly slower in hhvm. Again, this is only relevant to your code if you're running *_oncethousands of times.

用 慢 10-100 倍,require_once奇怪的require_once是在hhvm. 同样,如果您运行*_once数千次,这仅与您的代码相关。



<?php // test.php

$LIMIT = 1000000;

$start = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    if (!defined('include.php')) {
        require('include.php');
        define('include.php', 1);
    }

$mid = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    require_once('include.php');

$end = microtime(true);

printf("if defined\t%s\nrequire_once\t%s\n", $mid-$start, $end-$mid);


<?php // include.php

// do nothing.

回答by Edward Z. Yang

This thread makes me cringe, because there's already been a "solution posted", and it's, for all intents and purposes, wrong. Let's enumerate:

这个线程让我感到畏缩,因为已经有一个“解决方案发布”,而且无论出于何种意图和目的,它都是错误的。我们来一一列举:

  1. Defines are reallyexpensive in PHP. You can look it upor test it yourself, but the only efficient way of defining a global constant in PHP is via an extension. (Class constants are actually pretty decent performance wise, but this is a moot point, because of 2)

  2. If you are using require_once()appropriately, that is, for inclusion of classes, you don't even need a define; just check if class_exists('Classname'). If the file you are including contains code, i.e. you're using it in the procedural fashion, there is absolutely no reason that require_once()should be necessary for you; each time you include the file you presume to be making a subroutine call.

  1. 在 PHP 中定义非常昂贵。您可以自行查找或测试,但在 PHP 中定义全局常量的唯一有效方法是通过扩展。(类常量实际上在性能方面相当不错,但这是一个有争议的问题,因为 2)

  2. 如果你使用require_once()得当,也就是说,为了包含类,你甚至不需要定义;只需检查是否class_exists('Classname')。如果您包含的文件包含代码,即您以程序方式使用它,则绝对没有理由require_once()对您来说是必要的;每次包含文件时,您都认为是在进行子程序调用。

So for a while, a lot of people did use the class_exists()method for their inclusions. I don't like it because it's fugly, but they had good reason to: require_once()was pretty inefficient before some of the more recent versions of PHP. But that's been fixed, and it is my contention that the extra bytecode you'd have to compile for the conditional, and the extra method call, would by far overweigh any internal hashtable check.

所以有一段时间,很多人确实使用这种class_exists()方法来处理他们的夹杂物。我不喜欢它,因为它很丑,但他们有充分的理由:require_once()在某些较新版本的 PHP 之前效率非常低。但这已经解决了,我的观点是,您必须为条件编译的额外字节码和额外的方法调用远远超过任何内部哈希表检查。

Now, an admission: this stuff is tough to test for, because it accounts for so little of the execution time.

现在,承认:这个东西很难测试,因为它只占执行时间太少。

Here is the question you should be thinking about: includes, as a general rule, are expensive in PHP, because every time the interpreter hits one it has to switch back into parse mode, generate the opcodes, and then jump back. If you have a 100+ includes, this will definitely have a performance impact. The reason why using or not using require_once is such an important question is because it makes life difficult for opcode caches. An explanation for thiscan be found here, but what this boils down to is that:

这是您应该考虑的问题:作为一般规则,包含在 PHP 中的开销很大,因为每次解释器命中一个时,它都必须切换回解析模式,生成操作码,然后跳回。如果您有 100 多个包含,这肯定会对性能产生影响。为什么使用或不使用 require_once 是一个如此重要的问题,因为它使操作码缓存变得困难。对此解释可以在这里找到,但这归结为:

  • If during parse time, you know exactly what include files you will need for the entire life of the request, require()those at the very beginning and the opcode cache will handle everything else for you.

  • If you are not running an opcode cache, you're in a hard place. Inlining all of your includes into one file (don't do this during development, only in production) can certainly help parse time, but it's a pain to do, and also, you need to know exactly what you'll be including during the request.

  • Autoload is very convenient, but slow, for the reason that the autoload logic has to be run every time an include is done. In practice, I've found that autoloading several specialized files for one request does not cause too much of a problem, but you should not be autoloading all of the files you will need.

  • If you have maybe 10 includes (this is a veryback of the envelope calculation), all this wanking is not worth it: just optimize your database queries or something.

  • 如果在解析期间,您确切地知道在请求的整个生命周期中需要哪些包含文件,require()那些在开始时的包含文件和操作码缓存将为您处理其他所有内容。

  • 如果您没有运行操作码缓存,那么您将处于困境。将所有包含内联到一个文件中(不要在开发期间这样做,只能在生产中这样做)当然可以帮助解析时间,但这样做很痛苦,而且,您需要确切地知道在要求。

  • 自动加载非常方便,但速度很慢,因为每次包含时都必须运行自动加载逻辑。在实践中,我发现为一个请求自动加载多个专用文件不会造成太大问题,但是您不应该自动加载您需要的所有文件。

  • 如果你可能有 10 个包含(这是一个非常落后的计算),所有这些都是不值得的:只需优化你的数据库查询或其他东西。

回答by terson

I got curious and checked out Adam Backstrom's link to Tech Your Universe. This article describes one of the reasons that require should be used instead of require_once. However, their claims didn't hold up to my analysis. I'd be interested in seeing where I may have misanalysed the solution. I used PHP 5.2.0 for comparisons.

我很好奇并查看了 Adam Backstrom 与Tech Your Universe的链接。本文描述了应该使用 require 而不是 require_once 的原因之一。然而,他们的说法并不符合我的分析。我很想知道我可能在哪里错误地分析了解决方案。我使用 PHP 5.2.0 进行比较。

I started out by creating 100 header files that used require_once to include another header file. Each of these files looked something like:

我首先创建了 100 个头文件,这些头文件使用 require_once 来包含另一个头文件。这些文件中的每一个看起来都类似于:

<?php
    // /home/fbarnes/phpperf/hdr0.php
    require_once "../phpperf/common_hdr.php";

?>

I created these using a quick Bash hack:

我使用快速 Bash hack 创建了这些:

for i in /home/fbarnes/phpperf/hdr{00..99}.php; do
    echo "<?php
    // $i" > $i
    cat helper.php >> $i;
done

This way I could easily swap between using require_once and require when including the header files. I then created an app.php to load the one hundred files. This looked like:

这样我就可以在包含头文件时轻松地在使用 require_once 和 require 之间切换。然后我创建了一个 app.php 来加载一百个文件。这看起来像:

<?php
    // Load all of the php hdrs that were created previously
    for($i=0; $i < 100; $i++)
    {
        require_once "/home/fbarnes/phpperf/hdr$i.php";
    }

    // Read the /proc file system to get some simple stats
    $pid = getmypid();
    $fp = fopen("/proc/$pid/stat", "r");
    $line = fread($fp, 2048);
    $array = split(" ", $line);

    // Write out the statistics; on RedHat 4.5 with kernel 2.6.9
    // 14 is user jiffies; 15 is system jiffies
    $cntr = 0;
    foreach($array as $elem)
    {
        $cntr++;
        echo "stat[$cntr]: $elem\n";
    }
    fclose($fp);
?>

I contrasted the require_once headers with require headers that used a header file looking like:

我将 require_once 标头与使用头文件的 require 标头进行了对比,如下所示:

<?php
    // /home/fbarnes/phpperf/h/hdr0.php
    if(!defined('CommonHdr'))
    {
        require "../phpperf/common_hdr.php";
        define('CommonHdr', 1);
    }
?>

I didn't find much difference when running this with require vs. require_once. In fact, my initial tests seemed to imply that require_once was slightly faster, but I don't necessarily believe that. I repeated the experiment with 10000 input files. Here I did see a consistent difference. I ran the test multiple times, the results are close but using require_once uses on average 30.8 user jiffies and 72.6 system jiffies; using require uses on average 39.4 user jiffies and 72.0 system jiffies. Therefore, it appears that the load is slightly lower using require_once. However, the wall clock time is slightly increased. The 10,000 require_once calls use 10.15 seconds to complete on average and 10,000 require calls use 9.84 seconds on average.

使用 require 和 require_once 运行它时,我没有发现太大区别。事实上,我最初的测试似乎暗示 require_once 稍微快一点,但我不一定相信。我用 10000 个输入文件重复了这个实验。在这里,我确实看到了一致的差异。我多次运行测试,结果很接近,但使用 require_once 平均使用 30.8 个用户 jiffies 和 72.6 个系统 jiffies;使用 require 平均使用 39.4 个用户 jiffies 和 72.0 个系统 jiffies。因此,使用 require_once 时负载似乎略低。但是,挂钟时间略有增加。10,000 个 require_once 调用平均使用 10.15 秒完成,10,000 个 require 调用平均使用 9.84 秒。

The next step is to look into these differences. I used straceto analyse the system calls that are being made.

下一步是研究这些差异。我使用strace来分析正在进行的系统调用。

Before opening a file from require_once the following system calls are made:

在从 require_once 打开文件之前,会进行以下系统调用:

time(NULL)                              = 1223772434
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0
lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=88, ...}) = 0
time(NULL)                              = 1223772434
open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

This contrasts with require:

这与 require 形成对比:

time(NULL)                              = 1223772905
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0
lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
time(NULL)                              = 1223772905
open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

Tech Your Universe implies that require_once should make more lstat64 calls. However, they both make the same number of lstat64 calls. Possibly, the difference is that I am not running APC to optimize the code above. However, next I compared the output of strace for the entire runs:

Tech Your Universe 意味着 require_once 应该进行更多的 lstat64 调用。但是,它们都进行了相同数量的 lstat64 调用。可能,不同之处在于我没有运行 APC 来优化上面的代码。但是,接下来我比较了整个运行的 strace 输出:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out
  190709 strace_1000r.out
  210707 strace_1000ro.out
  401416 total

Effectively there are approximately two more system calls per header file when using require_once. One difference is that require_once has an additional call to the time() function:

实际上,当使用 require_once 时,每个头文件大约多两个系统调用。一个区别是 require_once 额外调用了 time() 函数:

[fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out
strace_1000r.out:20009
strace_1000ro.out:30008

The other system call is getcwd():

另一个系统调用是 getcwd():

[fbarnes@myhost phpperf]$ grep -c getcwd strace_1000r.out strace_1000ro.out
strace_1000r.out:5
strace_1000ro.out:10004

This is called because I decided to relative path referenced in the hdrXXX files. If I make this an absolute reference, then the only difference is the additional time(NULL) call made in the code:

之所以这么叫是因为我决定在 hdrXXX 文件中引用相对路径。如果我将此作为绝对引用,那么唯一的区别是代码中进行的额外 time(NULL) 调用:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out
  190705 strace_1000r.out
  200705 strace_1000ro.out
  391410 total
[fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out
strace_1000r.out:20008
strace_1000ro.out:30008

This seems to imply that you could reduce the number of system calls by using absolute paths rather than relative paths. The only difference outside of that is the time(NULL) calls which appear to be used for instrumenting the code to compare what is faster.

这似乎意味着您可以通过使用绝对路径而不是相对路径来减少系统调用的数量。除此之外的唯一区别是 time(NULL) 调用,它似乎用于检测代码以比较更快的速度。

One other note is that the APC optimization package has an option called "apc.include_once_override" that claims that it reduces the number of system calls made by the require_once and include_once calls (see the PHP documentation).

另一个注意事项是,APC 优化包有一个名为“apc.include_once_override”的选项,声称它减少了 require_once 和 include_once 调用的系统调用次数(请参阅PHP 文档)。

回答by nickf

Can you give us any links to these coding practices which say to avoid it? As far as I'm concerned, it's a complete non-issue. I haven't looked at the source code myself, but I'd imagine that the only difference between includeand include_onceis that include_onceadds that filename to an array and checks over the array each time. It'd be easy to keep that array sorted, so searching over it should be O(log n), and even a medium-largish application would only have a couple of dozen includes.

您能给我们提供这些编码实践的任何链接吗?就我而言,这完全不是问题。我自己没有查看过源代码,但我认为include和之间的唯一区别include_onceinclude_once将该文件名添加到数组中并每次检查该数组。保持该数组排序很容易,因此搜索它应该是 O(log n),即使是中等规模的应用程序也只有几十个包含。

回答by Greg

A better way to do things is to use an object-oriented approach and use __autoload().

更好的处理方式是使用面向对象的方法并使用__autoload()

回答by hexalys

It's not using the function that is bad. It's an incorrect understanding of how and when to use it, in an overall code base. I'll just add a bit more context to that possibly misunderstood notion:

它没有使用不好的功能。在整个代码库中,这是对如何以及何时使用它的错误理解。我只会为这个可能被误解的概念添加更多背景信息:

People shouldn't think that require_once is a slow function. You have to include your code one way or another. require_once()vs. require()'s speed isn't the issue. It's about the performance hindering caveats that may results for using it blindly. If used broadly without consideration for context, it can lead to huge memory waste or wasteful code.

人们不应该认为 require_once 是一个缓慢的函数。您必须以一种或另一种方式包含您的代码。require_once()vs.require()的速度不是问题。这是关于性能阻碍警告可能导致盲目使用它。如果不考虑上下文而广泛使用,可能会导致大量内存浪费或代码浪费。

What I have seen that's really bad, is when huge monolithic frameworks use require_once()in all the wrong ways, especially in a complex object-oriented (OO) environment.

我所看到的非常糟糕的是,当巨大的单体框架require_once()以所有错误的方式使用时,尤其是在复杂的面向对象 (OO) 环境中。

Take the example of using require_once()at the top of every class as seen in many libraries:

以在require_once()每个类的顶部使用 using 为例,如在许多库中所见:

require_once("includes/usergroups.php");
require_once("includes/permissions.php");
require_once("includes/revisions.php");
class User{
  // User functions
}

So the Userclass is designed to use all three other classes. Fair enough!

因此,User该类旨在使用所有其他三个类。很公平!

But now what if a visitor is browsing the site and not even logged in and the framework loads: require_once("includes/user.php");for every single request.

但是现在如果访问者正在浏览站点甚至没有登录并且框架加载了:require_once("includes/user.php");对于每个请求。

It's including 1+3 unnecessaryclasses it won't ever use during that particular request. This is how bloated frameworks end up using 40 MB per request as opposed to 5 MB or less.

它包括 1+3个在该特定请求期间永远不会使用的不必要的类。这就是臃肿的框架最终每个请求使用 40 MB 而不是 5 MB 或更少的原因。



The other ways it can be misused, is when a class is re-used by many others! Say you have about 50 classes that use helperfunctions. To make sure helpersare available for those classes when they are loaded, you get:

它可能被滥用的另一种方式是当一个类被许多其他人重用时!假设您有大约 50 个使用helper函数的类。为确保helpers这些类在加载时可用,您将获得:

require_once("includes/helpers.php");
class MyClass{
  // Helper::functions(); // etc..
}

There is nothing wrong here per se. However if one page request happens to include 15 similar classes. You are running require_once15 times, or for a nice visual:

这里本身没有错。但是,如果一页请求恰好包含 15 个类似的类。您正在运行require_once15 次,或者为了一个漂亮的视觉效果:

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");

The use of require_once() technically affects performance for running that function 14 times, on top of having to parse those unnecessary lines. With just 10 other highly used classes with that similar problem, it could account for 100+ lines of such rather pointless repetitive code.

使用 require_once() 在技术上会影响运行该函数 14 次的性能,此外还必须解析那些不必要的行。只有 10 个其他高度使用的类具有类似的问题,它可以解释 100 多行这样毫无意义的重复代码。

With that, it's probably worth using require("includes/helpers.php");at the bootstrap of your application or framework, instead. But since everything is relative, it all dependsif the weight versus usage frequency of the helpersclass is worth saving 15-100 lines of require_once(). But if the probability of not using the helpersfile on any given request is none, then requireshould definitely be in your main class instead. Having require_oncein each class separately becomes a waste of resources.

有了它,它可能值得require("includes/helpers.php");在您的应用程序或框架的引导程序中使用。但由于一切都是相对的,这完全取决于类的权重与使用频率helpers是否值得节省 15-100 行require_once(). 但是,如果helpers在任何给定请求上不使用该文件的可能性为零,那么require绝对应该在您的主类中。分别require_once在每个类中会浪费资源。



The require_oncefunction is useful when necessary, but it shouldn't be regarded as a monolithic solution to use everywhere for loading all classes.

require_once函数在必要时很有用,但不应将其视为在任何地方都用于加载所有类的整体解决方案。

回答by Steve Clay

The PEAR2 wiki (when it existed) used to list good reasons for abandoning allthe require/include directives in favor of autoloading, at least for library code. These tie you down to rigid directory structures when alternative packaging models like pharare on the horizon.

PEAR2 wiki(当它存在时)曾经列出了放弃所有require/include 指令以支持自动加载的充分理由,至少对于库代码。当诸如phar 之类的替代包装模型出现时,这些将您束缚在严格的目录结构中。

Update: As the web archived version of the wiki is eye-gougingly ugly, I've copied the most compelling reasons below:

更新:由于维基的网络存档版本非常丑陋,我复制了以下最令人信服的原因:

  • include_path is required in order to use a (PEAR) package. This makes it difficult to bundle a PEAR package within another application with its own include_path, to create a single file containing needed classes, to move a PEAR package to a phar archive without extensive source code modification.
  • when top-level require_once is mixed with conditional require_once, this can result in code that is uncacheable by opcode caches such as APC, which will be bundled with PHP 6.
  • relative require_once requires that include_path already be set up to the correct value, making it impossible to use a package without proper include_path
  • include_path 是使用(PEAR)包所必需的。这使得在另一个应用程序中捆绑一个 PEAR 包和它自己的 include_path、创建包含所需类的单个文件、将 PEAR 包移动到 phar 存档而无需大量源代码修改变得困难。
  • 当顶级 require_once 与条件 require_once 混合使用时,这可能导致代码无法被操作码缓存(如 APC)缓存,后者将与 PHP 6 捆绑在一起。
  • 相对 require_once 要求已经将 include_path 设置为正确的值,从而无法使用没有正确 include_path 的包

回答by Annika Backstrom

The *_once()functions statevery parent directory to ensure the file you're including isn't the same as one that's already been included. That's part of the reason for the slowdown.

*_once()功能STAT每个父目录,以确保您包括文件是不一样的一个一个已经被列入。这是放缓的部分原因。

I recommend using a tool like Siegefor benchmarking. You can try all the suggested methodologies and compare response times.

我建议使用像Siege这样的工具进行基准测试。您可以尝试所有建议的方法并比较响应时间。

More on require_once()is at Tech Your Universe.

更多信息请require_once()访问Tech Your Universe

回答by NeuroXc

Even if require_onceand include_onceareslower than requireand include(or whatever alternatives might exist), we're talking about the smallest level of micro-optimization here. Your time is much better spent optimizing that poorly written loop or database query than worrying about something like require_once.

即使require_onceinclude_once慢于requireinclude(或任何可能存在的替代品),我们在这里讨论的微优化的最小水平。与担心诸如require_once.

Now, one could make an argument saying that require_onceallows for poor coding practices because you don't need to pay attention to keeping your includes clean and organized, but that has nothing to do with the function itselfand especially not its speed.

现在,有人可以提出一个论点,说require_once允许糟糕的编码实践,因为你不需要注意保持你的包含干净和有组织,但这与函数本身无关,尤其是与它的速度无关。

Obviously, autoloading is better for the sake of code cleanliness and ease of maintenance, but I want to make it clear that this has nothing to do with speed.

显然,出于代码清洁和易于维护的考虑,自动加载更好,但我想明确一点,这与速度无关。

回答by Lucas Oman

Yes, it is slightly more expensive than plain ol' require(). I think the point is if you can keep your code organized enough to not duplicate includes, don't use the *_once() functions, as it will save you some cycles.

是的,它比普通的 ol' require() 稍贵。我认为关键是如果你能保持你的代码足够组织而不重复包含,不要使用 *_once() 函数,因为它会节省你一些周期。

But using the _once() functions isn't going to kill your application. Basically, just don't use it as an excuse to not have to organize your includes. In some cases, using it is still unavoidable, and it's not a big deal.

但是使用 _once() 函数不会杀死您的应用程序。基本上,只是不要以此为借口不必组织您的包含。在某些情况下,使用它仍然是不可避免的,这没什么大不了的。