说到 php,很多开发人员喜欢这种语言,很多开发人员讨厌这种语言,而且很多开发人员通常只是用它来完成他们的工作。
就其价值而言,我属于后者。我认为PHP很好。像任何东西一样,它也不是没有问题,但我很喜欢使用它,并将其视为完成工作的一种方式,而不是某种类型的发展乌托邦的空想语言。
开发人员喜欢 PHP 的一些东西——它的特性和灵活性——正是我们经常遇到的问题。该列表很长,但在 wordpress 世界中,最常见的混淆点之一是包含外部文件的正确方法。
PHP 提供了四种方法来做到这一点,WordPress 甚至提供了自己的变体。
在本文中,我们将调查 PHP 提供的四种包含文件的方法,查看每种方法的使用指南,并查看 WordPress 包含文件的功能。
使用 PHP 包含文件
一般来说,使用 PHP 包含文件是指将另一个脚本包含到您当前正在处理的脚本的上下文中的操作。
您可以将其视为导入文件,这样当文件从服务器返回时,脚本会按照它们被包含的顺序组合,然后解释为单个文件。
首先,我们将研究在 PHP 中包含文件的方法以及每种方法的含义。在文章的最后,我们将回顾何时应该这样做。
使用 include()
根据PHP手册:
include() 将包含并评估指定的文件。如果未找到该文件,将引发 PHP 警告。
简而言之,这意味着 PHP 将查找您尝试包含的文件。如果找到它,那么它将被添加到您的脚本中您声明它的确切位置。
理解这一点很重要。例如,假设您正在编写一组函数,这些函数依赖于先前的一组函数。在这种情况下,您需要确保首先包含另一个文件。
另一方面,如果您希望在现有函数的中间引入一组函数或一个外部文件,那么您可以将它准确地包含在您需要的位置。
其次,注意如果文件丢失,PHP 会抛出警告。根据服务器配置,您可能会看到它呈现给浏览器,或者您可能会看到它写入日志文件(或两者兼而有之)。
尽管如此,警告只是——它们不被认为是致命的,并且通常不会停止执行,但它们很重要,因为它们通常意味着你的部分工作没有被正确加载和/或解释。
最后,请注意,当使用 加载文件时 include(),它将可以访问先前在现有脚本中定义的所有变量。
例如,假设您正在处理一个函数,并且在函数执行到一半时,您将包含一个单独的文件。该单独文件将有权访问之前在包含它的函数中定义的变量。
尽管您可能认为这很方便,但它使外部脚本有点不清楚,因为它不一定表明它依赖于外部定义的变量。这可能会令人困惑,尤其是在与团队合作时。
使用 include_once()
直接取自 PHP 手册:
include_once() 将执行与 include() 相同的行为,但如果文件已被包含,则不会再次包含该文件。
显然,没有必要花太多时间谈论 的一般要点 ,但是如何 工作和如何 工作include_once()之间存在一些关键区别 。include_once()include()
首先,虽然 include_once() 性能与 基本相同 include(),但它 不允许您再次包含该脚本。这意味着,如果您的项目中的其他位置包含了外部文件,那么这就是包含该文件的最终位置 。
那么这样做有什么好处呢?除了确保只有一个地方包含脚本之外,它还确保变量和函数不一定会被重新定义。回想一下,当使用 时include(),脚本可以访问在它们上面定义的函数和变量。
如果您选择在文件中定义一组新的变量或函数并将其包含在另一个脚本中,并且您不使用 include_once(),那么您将面临重新定义函数和变量的风险,这可能会导致代码执行出现重大问题.
使用 PHP 请求文件
要求文件类似于包含文件,因为它是另一种可以将脚本包含到当前正在编写的脚本中的方式,但它带有一组关于错误和安全性的自身含义。
尽管您可以以与包含文件大致相同的方式来考虑请求文件的行为,但它确实暗示它更强大 - 即,外部文件是 执行时需要 的。
正如我们将看到的,这正是这种情况。
使用 require()
再一次,直接来自 PHP 手册:
require() 与 include() 执行相同,但如果找不到文件,则会抛出 PHP 致命错误。
所以这里是这样的 :它会执行与将外部脚本导入你正在使用的脚本的上下文require()相同的操作 ,但如果它无法找到文件,它会抛出一个错误并完全停止执行include().
这意味着您的应用程序将停止。使用 include(),您将收到警告,并且它会尝试继续运行。
在某种程度上,似乎需要文件是正确的方法。毕竟,你为什么要冒险包含一些东西,只是为了警告应用程序中的潜在故障?
但这一切都取决于您正在从事的工作的性质。有时,简单的 PHP 警告是可以的——比如忘记初始化数组的索引——其他时候,你需要一个错误。
require什么时候使用vs.没有硬性规定include,但要批判性地思考你正在做的事情的性质以及如果它失败了它所带来的影响。
使用 require_once()
最后,来自 PHP 手册:
require_once() 执行与该文件相同 require() 但不会再次包含该文件(如果已包含该文件)。
这可能是最容易理解的,因为我们已经相对详细地介绍了最后三个函数。简单地说, require_once()执行与 require 相同的功能,但如果文件已经加载到您的脚本中,它不会再次尝试包含文件。
经验法则
除了批判性地思考哪种功能最适合您的项目性质,在使用 include() and 时还需要考虑以下两个额外的经验法则require():
require_once()对于较大的站点来说更好,因为它会在较低级别执行一些影响安全性和性能的额外工作。
include_once()速度更快,通常被较小的站点接受。
很简单,但是 WordPress 辅助函数呢?
包括跨目录的文件
当您处理一个包含许多文件分布在多个目录中的项目时,事情可能会变得混乱。请记住,您要包含的文件的路径是相对于直接父文件解析的。
例如,考虑以下目录结构。
--website --index.php --contact.php --inc --header.php --footer.php --functions.php --social --facebook --post.php --page.php --twitter --tweet.php --share.php
这是 header.php 文件中的代码:
<?php require_once("functions.php"); ?>
这是 functions.php 文件中的代码:
<?php function current_date() { echo 'Today is '.date('F j, Y').'.'; } ?>
这是 share.php 文件中的代码:
<?php require_once("../inc/header.php"); current_date(); ?>
刚开始时,通常认为share.php的代码 会抛出错误,因为 functions.php与share.php 不在 同一目录中 。但是,该 require_once("functions.php") 语句位于 headers.php中,因此解释器将在 headers.php 所在 的目录中查找functions.php 文件。
这是因为 PHP 会 在header.php 的上下文中 解析functions.php。由于它们都位于同一目录中,因此该函数将按预期包含在我们的文件中。
包含文件的变量和函数范围
当您在父文件中包含文件时,包含文件中定义的变量范围将与该特定行的变量范围相同。但是,您在包含文件中定义的任何函数和类都将具有全局范围。让我们通过一个例子来理解它。
我们的第一个名为 inc.php的文件 具有以下代码:
<?php function current_date() { echo 'Today is '.date('F j, Y').'.'; $current_day = date('l'); function current_time() { echo 'Current time is '.date('h:i:s A').'.'; } } $day_of_the_year = date('z'); ?>
我们的第二个名为 main.php的文件 具有以下代码:
<?php require_once('inc.php'); // Today is April 10, 2021. current_date(); // Undefined Variable echo $current_day; // Current time is 11:33:51 AM. echo current_time(); // 99 echo $day_of_the_year; ?>
$current_day 我们在函数内部 定义了一个变量 current_date()。所以它不能在我们的主文件中访问,因为它的范围仅限于current_date() 函数。另一方面, 我们可以访问current_time() 内部定义的函数 current_date() ,因为它具有全局范围。
您应该考虑阅读本教程以了解 PHP 中的变量范围, 以了解 PHP 中的变量范围。
使用 WordPress 包含文件
综上所述,有 比include()在 WordPress 项目中使用 和 require() 包含模板 更好的方法 。
例如,假设您有多个循环文件,包括一个用于发布格式的文件:
循环标准.php
循环图像.php
循环引用.php
每当您在主题的单个帖子页面上工作时,您都需要将它们包含在 single.php中。
在某个时间点,做这样的事情是可以接受的:
include_once( 'loop-standard.php' );
但这不再是最佳做法。
利用 get_template_part()
WordPress 现在提供了一个函数, get_template_part()它是本机api的一部分,专门用于通过您的主题重用代码的部分或模板(页眉、页脚和侧边栏除外)。
该函数接受两个参数:
第一个参数是模板的 slug。在上面的例子中,那将是 loop.
第二个参数是模板的名称。在上面的示例中,这将是 standard、 quote或 image。
继续上面的例子,假设我们在 循环中 ,我们想要包含报价后格式模板。在这种情况下,我们将执行以下操作:
if( 'quote' == get_post_format() ) { get_template_part( 'loop', 'quote' ); }
或者,假设您已将模板命名为与帖子格式类型匹配,您可以做一些更简洁的事情:
get_template_part( 'loop', get_post_format() );
干净,对吧?
您实际上可以更进一步。假设您已将分页代码抽象到其自己的名为pagination.php的模板文件中。使用 get_template_part(),您可以将其包含在整个站点中,例如 footer.php 或 index.php、 single.php、 archives.php等,只需添加:
get_template_part( 'pagination ');
容易多了,不是吗?
我什么时候应该使用什么?
所以在这一切之后,我们还没有真正讨论什么时候使用什么的指导方针。我绝不是这方面的权威,但这里是我遵循的经验法则:
在主题开发中,我总是使用 get_template_part().
在插件开发中,我几乎总是使用 include_once(),而且我一般在一个函数中使用一次。您可以在我的样板文件中看到这一点。
如果我正在编写的插件将在一个非常大的站点上使用,那么我使用 require_once().
就这样!
- 使用 include()
- 使用 include_once()
- 使用 require()
- 使用 require_once()
- 利用 get_template_part()