命名空间和自动加载不是使用WordPress插件时通常讨论的主题。
其中一些与周围的社区有关,一些与WordPress支持的PHP版本有关,其中一些与没有多少人在谈论它有关。
在某种程度上,这还可以。
名称空间和自动加载都不是创建插件所绝对需要的主题。 但是,它们可以提供一种更好的方式来组织和构造代码,并减少插件使用的require
, require_once
, include
或include_once
语句的数量。
在本系列文章中,我们将确切地了解什么是PHP名称空间,为什么有益,以及如何使用它们。 然后,我们将研究如何使用自动加载器自动加载所需的文件,而不必在代码中手动加载它们。
开始之前
首先,您需要以下工具:
- 一个本地开发环境,包括PHP 5.6.20,Apache Web服务器和MySQL数据库服务器。
- WordPress 4.6所在的目录。
- 您很喜欢使用文本编辑器或IDE来编写插件。
- WordPress插件API的使用知识。
一旦所有这些都准备就绪,让我们开始构建插件。 请注意,如果以上任何内容对您来说都是新鲜事物,请不要犹豫 在我的个人资料页面上查看我以前的任何教程。
此外,您可以在@tommcfarlin的 博客和/或Twitter上关注我,在其中我谈论了WordPress上下文中的软件开发。
话虽如此,让我们开始吧。
我们将要建立的
在本系列中,我们将构建一个简单的插件,主要用来演示名称空间和自动加载在PHP中的工作方式。 但是要做到这一点,始终有助于以实用的方式应用这些概念。
为此,我们将构建一个插件,该插件可轻松在插件中加载样式表和JavaScript样式,并显示一个meta框,提示用户一个问题,以帮助他们集思广益。
不,这不是您可能要提交到WordPress插件存储库的东西,也不是您可能会在此特定演示之外使用的东西。 但是请记住,本系列文章的目的是演示名称空间和自动加载的工作方式。
通过这个示例,我们将要做到这一点。
构建插件
如果您已经阅读了我以前的任何教程,那么您知道我想做的一件事就是在开始编写任何代码之前,计划好我们将要构建的内容。 因此,对于此插件的第一次迭代,这是我们知道需要做的事情:
- 定义用于启动插件的引导文件。
- 为将呈现元框的所有文件设置目录。
- 创建一个目录来容纳将加载我们的依赖项的类。
- 为我们的插件准备样式表和JavaScript。
看起来很简单,对吧? 如果没有,就不用担心。 我将引导您完成整个过程,包括代码,注释,屏幕截图和说明。
让我们开始吧。
创建插件目录
从一开始,我们就知道我们将需要一个文件作为插件的引导程序。 我们也知道我们将需要一个目录来进行管理。
让我们继续创建它:
显然,我们有一个空文件和一个admin目录。 让我们继续进行设置,以使其显示在WordPress插件激活屏幕的上下文中。
为此,我们需要在插件文件的顶部添加以下代码块:
<?php
/**
* The plugin bootstrap file
*
* This file is read by WordPress to generate the plugin information in the
* plugin admin area. This file also includes all of the dependencies used by
* the plugin, registers the activation and deactivation functions, and defines
* a function that starts the plugin.
*
* @link http://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1
* @since 0.1.0
* @package tutsplus_namespace_demo
*
* @wordpress-plugin
* Plugin Name: Tuts+ Namespace Demo
* Plugin URI: http://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1
* Description: Learn how to use Namespaces and Autoloading in WordPress.
* Version: 0.1.0
* Author: Tom McFarlin
* Author URI: https://tommcfarlin.com/
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/
然后,当您导航到管理区域中的WordPress插件页面时,您应该看到它显示在插件列表中。 如果您选择激活它,那么由于我们还没有编写任何代码,因此什么也不会发生。
在这一点上,我们可以继续并开始定义类,该类将在 添加新帖子页面。
添加元框
本教程的这一部分将假定您精通创建元框。 如果没有,请不要犹豫地回顾本系列中的概念,然后在完成后返回本部分。
首先,让我们在插件的admin
目录中创建一个名为class-meta-box-display.php
的文件。 该代码应包括以下内容。 请务必查看评论,以确保您了解此类负责的所有事情。
<?php
/**
* Defines the functionality required to render the content within the Meta Box
* to which this display belongs.
*/
/**
* Defines the functionality required to render the content within the Meta Box
* to which this display belongs.
*
* When the render method is called, the contents of the string it includes
* or the file it includes to render within the meta box.
*/
class Meta_Box_Display {
/**
* Renders a single string in the context of the meta box to which this
* Display belongs.
*/
public function render() {
echo 'This is the meta box.';
}
}
从上面的代码,您应该能够确定此类将负责在meta框内显示内容。 但是,现在,我们只是让它回显该视图的声明。
我们将在本教程的后面部分对此进行更改。
接下来,我们需要引入一个代表元框本身的类。 因此,在我们插件的admin
目录中创建一个class-meta-box.php
文件。 这是执行此操作的代码。 再次检查代码,然后我将解释该类下发生的事情:
<?php
/**
* Represents a meta box to be displayed within the 'Add New Post' page.
*/
/**
* Represents a meta box to be displayed within the 'Add New Post' page.
*
* The class maintains a reference to a display object responsible for
* displaying whatever content is rendered within the display.
*/
class Meta_Box {
/**
* A reference to the Meta Box Display.
*
* @access private
* @var Meta_Box_Display
*/
private $display;
/**
* Initializes this class by setting its display property equal to that of
* the incoming object.
*
* @param Meta_Box_Display $display Displays the contents of this meta box.
*/
public function __construct( $display ) {
$this->display = $display;
}
/**
* Registers this meta box with WordPress.
*
* Defines a meta box that will render inspirational questions at the top
* of the sidebar of the 'Add New Post' page in order to help prompt
* bloggers with something to write about when they begin drafting a post.
*/
public function init() {
add_meta_box(
'tutsplus-post-questions',
'Inspiration Questions',
array( $this->display, 'render' ),
'post',
'side',
'high'
);
}
}
此类维护一个属性,该属性是对其显示的引用。 这意味着该类负责定义元框(该元框又调用显示对象以呈现消息)。
该显示作为在构造函数中设置的私有属性进行维护。 在调用init
方法之前,实际上不会定义元框(我们将在本教程后面的插件的引导程序中看到该框)。
至此,我们已具备在“ 添加新帖子页面 ”上显示基本元框所需的一切。 但是首先,我们需要设置插件的引导程序。
在以前的教程中,我已经做了很多事情,所以我将仅包括所需的代码(因为我已经定义了上面的标头)。 我添加了注释,但我还要确保解释代码后的情况。
这一点特别相关,因为我们的自动装带器最终会消除对您将要看到的某些东西的需求。
<?php
// If this file is accessed directory, then abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
// Include the files for rendering the display.
include_once( 'admin/class-meta-box.php' );
include_once( 'admin/class-meta-box-display.php' );
add_action( 'plugins_loaded', 'tutsplus_namespace_demo' );
/**
* Starts the plugin by initializing the meta box, its display, and then
* sets the plugin in motion.
*/
function tutsplus_namespace_demo() {
$meta_box = new Meta_Box( new Meta_Box_Display() );
$meta_box->init();
}
首先,我们确保该文件不能直接访问,并且只能由WordPress本身运行。
接下来,我们将include_once
到目前为止已创建的类。 接下来,我们实例化Meta_Box
并将其实例传递给Meta_Box_Display
的构造函数。
最后,我们调用位于Meta_Box
类中的init
方法。
假设一切顺利,我们应该能够激活插件,并在“ 添加新帖子”页面(或者实际上也是“ 更新帖子”页面)上看到meta框。
至此,我们有了一个功能良好的插件,但除了创建元框并显示文本字符串外,它实际上没有做任何其他事情。
让我们至少让它显示一些鼓舞人心的报价,并在每次加载页面时显示随机的报价。
显示灵感语录
首先,我们需要找到灵感引号的文本文件。 幸运的是,Internet提供了很多我们可以在我们的项目中使用的工具( 它们是免费提供的 )。 为此,我在admin
中创建了一个data
子目录,用于存放我的questions.txt
文件。
接下来,我们将需要创建一个类,该类将:
- 打开文件。
- 将随机行读入字符串。
- 关闭文件。
- 将字符串返回给调用者。
让我们继续创建该类。 因为这是一个实用程序,它将在插件的管理方面使用,所以让我们在admin
创建一个util
子目录。 接下来,让我们创建一个名为class-question-reader.php
的文件。
我们稍后将为该类指定代码,但返回到插件的引导文件,并记住包括该文件。 产生的代码应如下所示:
<?php
// Include the files for rendering the display.
include_once( 'admin/class-meta-box.php' );
include_once( 'admin/class-meta-box-display.php' );
include_once( 'admin/util/class-question-reader.php' );
如您所见,我们必须手动包含的文件数量越来越多。 想象一下,如果我们正在开发一个大型插件! 不过,我们将在本系列的后面部分再次讨论。
现在,让我们将注意力转向问题阅读器。 该类的代码应如下所示:
<?php
/**
* Reads the contents of a specified file and returns a random line from the
* file.
*/
/**
* Reads the contents of a specified file and returns a random line from the
* file.
*
* This class is used to populate the contents of the meta box with questions
* that prompt the user for ideas about which to write.
*
* Note this class is only for demo purposes. It has no error handling and
* assumes the specified file always exists.
*/
class Question_Reader {
/**
* Retrieves a question from the specified file.
*
* @param string $filename The path to the file that contains the question.
* @return string $question A single question from the specified file.
*/
public function get_question_from_file( $filename ) {
$question = '';
$file_handle = $this->open( $filename );
$question = $this->get_random_question( $file_handle, $filename );
$this->close( $file_handle );
return $question;
}
/**
* Opens the file for reading and returns the resource to the file.
*
* @access private
* @param string $filename The path to the file that contains the question.
* @return resource A resource to the file.
*/
private function open( $filename ) {
return fopen( $filename, 'r' );
}
/**
* Closes the file that was read.
*
* @access private
* @param string $file_handle The resource to the file that was read.
*/
private function close( $file_handle ) {
fclose( $file_handle );
}
/**
* Opens the file for reading and returns the resource to the file.
*
* @access private
* @param string $file_handle The resource to the file that was read.
* @param string $filename The path to the file containing the question.
* @return string $question The question to display in the meta box.
*/
private function get_random_question( $file_handle, $filename ) {
$questions = fread( $file_handle, filesize( $filename ) );
$questions = explode( "\n", $questions );
// Look for a question until an empty string is no longer returned.
$question = $questions[ rand( 0, 75 ) ];
while ( empty( $question ) ) {
$question = $questions[ rand( 0, 75 ) ];
}
return $question;
}
}
请注意,此代码相对简单,但是如果您不熟悉PHP中的一些基本文件操作,则可以执行以下操作:
- 我们使用
fopen
打开文件,这将为我们提供读取文件的资源。 - 接下来,我们将读取文件的内容,然后读取文件的每一行并将其写入数组的索引。
- 之后,我们从问题数组中选择一个随机数,并将其返回给调用它的方法。 如果返回空字符串,我们将再次查找直到找到问题。
- 然后,我们将资源关闭到文件中。
最终,要使用此类,您只需要实例化它,知道充满问题的文件的路径,然后调用get_question_from_file
方法。
注意:此类不会进行任何错误处理。 这是处理文件时的标准做法。 例如,如果文件不存在该怎么办? 如果格式不正确,应该怎么办?如果无法关闭资源怎么办?
所有这些都是很好的问题,但它们超出了本教程的范围。 所有这些信息都可以在PHP手册(以及整个Envato Tuts +网络中的其他一些教程)中找到。
不过,就目前而言,我们关注的是读取已知存在的文件,并且关注在结果框中显示结果。
到目前为止我们所拥有的
此时,我们可以开始将所有内容放在一起。 假设我们已正确完成所有操作,那么我们应该能够将Question_Reader
的实例传递给Meta_Box_Display
,询问问题,然后将其显示在meta框中。
首先,让我们更新引导文件:
<?php
function tutsplus_namespace_demo() {
$meta_box = new Meta_Box(
new Meta_Box_Display(
new Question_Reader()
)
);
$meta_box->init();
}
在上面的代码中,请注意, Meta_Box_Display
现在将问题阅读器的实例Meta_Box_Display
其构造函数中。 这意味着我们需要引入一个新的属性,我们现在将做它:
<?php
/**
* Defines the functionality required to render the content within the Meta Box
* to which this display belongs.
*/
/**
* Defines the functionality required to render the content within the Meta Box
* to which this display belongs.
*
* When the render method is called, the contents of the string it includes
* or the file it includes to render within the meta box.
*/
class Meta_Box_Display {
/**
* A reference to the object responsible for retrieving a question to display.
*
* @access private
* @var Question_Reader $question_reader
*/
private $question_reader;
/**
* Initializes the class by setting the question reader property.
*
* @param Question_Reader $question_reader The object for retrieving a question.
*/
public function __construct( $question_reader ) {
$this->question_reader = $question_reader;
}
/**
* Renders a single string in the context of the meta box to which this
* Display belongs.
*/
public function render() {
$file = dirname( __FILE__ ) . '/data/questions.txt';
$question = $this->question_reader->get_question_from_file( $file );
echo wp_kses( $question );
}
}
请注意,此文件使用该文件添加到数据子目录中的问题的路径。 除了要进行硬编码的路径之外,此类还取决于Question_Reader
的实例。
出于我们正在努力的演示目的(即名称空间和自动加载),没关系。 在未来的项目中,我们希望这些项目之间的耦合更少。 也许这将是将来教程的主题。
但是,上面代码的主要Meta_Box_Display
是Meta_Box_Display
类现在可以向用户显示问题。
此外,在将数据呈现给用户之前,请注意使用wp_kses
来wp_kses
数据。
刷新“ 添加新帖子”页面应显示如下图像:
如果刷新页面,则可以看到正在加载的新问题。
我们从这里去哪里?
显然,我们还没有真正解决名称空间和自动加载的问题,但这没关系! 重要的是,我们为不使用它们的插件奠定基础。 这样一来,当我们实现这些,我们可以看到他们携带的好处。
此外,我们还有其他工作要做:我们需要引入JavaScript和CSS以及资产加载器。 这将使我们更全面地了解将文件打包到命名空间中的好处。
记住,您可以在个人资料页面上找到我以前的所有教程,也可以在我的博客或Twitter 上关注我。
与往常一样,如果您正在寻找其他实用程序来帮助您构建不断增长的WordPress工具集,或者例如要学习和变得更精通WordPress的代码,请不要忘记看看我们在Envato中提供的功能市场 。
话虽如此,我们将从本系列的下一篇教程开始准备下载该插件的工作版本。 如果您想使用上面教程中的代码,请不要犹豫,尝试一下。 此外,请随时在评论中提出任何问题。