WordPress插件開發(fā)教程手冊 — 插件基礎(chǔ)教程

本教程手冊詳細(xì)介紹了WordPress插件開發(fā)的基礎(chǔ)知識,包括如何創(chuàng)建插件目錄、編寫插件頭注釋、使用Action和Filter鉤子以及利用WordPress API。適合初學(xué)者快速入門WordPress插件開發(fā)。

WordPress插件開發(fā)基礎(chǔ)

插件開發(fā)入門

簡單來說,一個 WordPress插件是一個帶有 WordPress插件頭注釋的 PHP 文件,我們強(qiáng)烈建議為插件創(chuàng)建一個目錄,以便保持插件文件整齊有序、便于維護(hù)。

要創(chuàng)建一個新的 WordPress插件,請按照以下步驟進(jìn)行。

  1. 切換到 WordPress 站點(diǎn)的 wp-content/plugins 目錄
  2. 創(chuàng)建一個新目錄,并將其命名為插件的名稱,如(plugin-name)
  3. 切換到你新建的目錄
  4. 創(chuàng)建一個 PHP 文件(插件名稱最好和目錄名稱保持一致。當(dāng)然,其他名稱也是可以的)

下面是類 Unix 系統(tǒng)上,在命令行中完成上面步驟的過程

wordpress$ cd wp-content/plugins
plugins$ mkdir plugin-name
plugins$ cd plugin-name
plugin-name$ vi plugin-name.php

在上面的例子中,vi 是文本編輯器的名稱,你可以使用自己喜歡的任何編輯器。

打開了上面創(chuàng)建的 PHP 文件之后,我們就可以開始開發(fā) WordPress插件了,首先,我們需要為插件添加一個插件頭注釋,這是一個特殊格式的 PHP 塊注釋,其中包含了插件的元數(shù)據(jù),例如插件名稱和作者。頭注釋至少需要包含插件的名稱,插件目錄中只有一個文件可以包含插件頭注釋,如果你的插件有多個 PHP 文件,其他文件都不要包含這個頭注釋。

<?php
/*
Plugin Name: YOUR PLUGIN NAME
*/

保存上面的文件,然后打開 WordPress插件列表界面,我們就可以在 WordPress 已安裝的插件中看到我們創(chuàng)建的插件了。

鉤子:Action 和 Filter

WordPress 鉤子可以讓我們在特定的時機(jī)介入 WordPress 的代碼執(zhí)行流程,不需要編輯任何核心文件就可以改變 WordPress 的行為,。

WordPress 中有兩種類型的鉤子,Action 和 Filter,Action 可以讓我們添加或修改 WordPress 功能,而 Filter 可以讓我們修改用戶提交的或展示給用戶的內(nèi)容。

除了在 WordPress插件中使用,鉤子也被廣泛應(yīng)用于 WordPress 核心的許多功能中,一些鉤子只是在 WordPress 埋下了一些占位符,以便我們開發(fā)的時候使用,這就是 WordPress 如此靈活的原因。

插件開發(fā)的基礎(chǔ)鉤子

創(chuàng)建插件時需要的 3 個基礎(chǔ)鉤子是  register_activation_hook(),register_deactivation_hook()  和 register_uninstall_hook()。

  • register_activation_hook 我們激活插件時會運(yùn)行,我們可以使用這個鉤子掛載一個函數(shù)來設(shè)置我們的插件,例如在數(shù)據(jù)表中添加一些默認(rèn)設(shè)置。
  • register_deactivation_hook 在我們禁用插件時運(yùn)行,我們可以掛載一個清理插件數(shù)據(jù)的函數(shù)來清理一些臨時數(shù)據(jù)。
  • register_uninstall_hook 在我們卸載插件時運(yùn)行,我們可以掛載一個清理插件所有數(shù)據(jù)的函數(shù)來清理數(shù)據(jù)庫中不再需要的插件數(shù)據(jù)。

添加自定義鉤子

我們可以使用 do_action() 函數(shù)來添加我們自己的鉤子,通過我們自己的自定義鉤子,其他開發(fā)者可以通過擴(kuò)展或修改我們的插件來適應(yīng)他們的需求。

移除掛載到鉤子上的函數(shù)

我們可以使用  remove_action() 來移除掛載到某個鉤子上的函數(shù),比如,如果一個插件是另外一個插件的擴(kuò)展,我們可以使用 remove_action 來移除擴(kuò)展插件添加到這個鉤子上的回調(diào)函數(shù),然后添加我們自己的回調(diào)函數(shù),這種情況下,需要特色關(guān)注插件 action 的優(yōu)先級,因為 remove_action() 需要在初始的 add_action() 之后運(yùn)行。

從鉤子中刪除 action 或改變 action 的優(yōu)先級時,我們應(yīng)該非常小心,因為我們很難看出這些改變會如何影響掛載在同一鉤子上的其他操作。使用這個操作的時候,強(qiáng)烈建議多做一些測試。

我們可以在本手冊的鉤子章節(jié)了解更多關(guān)于創(chuàng)建鉤子、與鉤子進(jìn)行交互的信息。

WordPress API

你知道嗎?WordPress 提供了很多 應(yīng)用程序接口 (APIs)? 這些 API 可以大大減少我們在開發(fā)插件時需要寫代碼。我們不想重復(fù)發(fā)明輪子,特別是現(xiàn)有的輪子經(jīng)過了很多開發(fā)和測試、已經(jīng)足夠穩(wěn)定了之后。

這其中最常見的是 選項 API,它可以幫助我們很輕松的把數(shù)據(jù)保存到數(shù)據(jù)庫中。如果您需要在插件中使用 cURL,那么您可能會對 HTTP API 感興趣。

由于我們正在討論怎么開發(fā) WordPress插件,學(xué)習(xí)一下 插件API 是有必要的,其中的很多功能可以幫我們更快速的開發(fā)插件。

WordPress 怎么加載插件?

當(dāng)我們打開 WordPress 后臺的已安裝插件列表時,WordPress 會搜索 wp-content/plugins 目錄(及其子目錄,也就是插件自己的目錄),來查找?guī)в?WordPress插件頭文件的 PHP 文件,如果我們的插件只是一個 PHP文件,如 Hello Dolly,該文件可以直接放在 wp-content/plugins 目錄的根目錄中。但更常見的是做法是:插件會有自己的目錄,插件文件存放在自己的目錄中,以目錄名稱做為插件文件名稱。

分享你的插件

有時候,我們僅為自己的站點(diǎn)開發(fā)插件,但更多人喜歡分享自己的插件到 WordPress 社區(qū)。在分享插件之前,我們需要選擇一個許可證,許可證可以讓用戶知道他們被允許如何使用我們的代碼,為了兼容 WordPress 核心的許可證,建議選擇適用于 GNU 通用公共許可證(GPLv2 +)的許可證。

頭文件要求

正如入門中所介紹的,插件頭文件告訴了 WordPress 這是一個什么樣的插件。頭文件至少需要包含插件名稱,也可以選擇性的包含以下幾個部分(通常應(yīng)該包含):

  • 插件名稱:必需)你的插件名稱,會顯示在 WordPress 后臺的插件列表中。
  • 插件 URI:插件主頁,應(yīng)該是唯一的URL,最好在你自己的網(wǎng)站上。對于你的插件來說,必須是獨(dú)一無二的,不能使用 WordPress.org 上的網(wǎng)址。
  • 描述:插件的簡短描述,在 WordPress插件管理界面顯示,不要超過 140 個字符。
  • 版本:插件的當(dāng)前版本號,例如 1.0 或 1.0.3。
  • 作者:插件作者名字,如果插件有多個作者,作者之間可以使用逗號分隔開。
  • 作者URI:作者網(wǎng)站或其他網(wǎng)站上的個人資料,如 WordPress.org。
  • 許可證:插件許可證簡稱(slug)(例如GPL2)。有關(guān)許可的更多信息可以在WordPress.org 指南中找到。
  • 許可證URI:許可證的全文鏈接(例如 https://www.gnu.org/licenses/gpl-2.0.html)。
  • 文本域:插件的 Gettext 文本域。更多信息可以在如何國際化您的插件頁面的文本域部分找到。
  • 域名路徑:域名路徑告訴 WordPress 在哪里可以找到翻譯。更多信息可以在如何國際化您的插件 頁面的域路徑部分找到。

插件頭注釋的正確格式可以參考如下示例:

<?php
/*
Plugin Name: WordPress.org Plugin
Plugin URI: https://developer.wordpress.org/plugins/the-basics/
Description: Basic WordPress Plugin Header Comment
Version: 20160911
Author: WordPress.org
Author URI: https://developer.wordpress.org/
License: GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: wporg
Domain Path: /languages
*/

包含軟件許可證

大多數(shù) WordPress插件都是使用 GPL 許可證發(fā)布的,WordPress 內(nèi)核使用的也是這個許可證,當(dāng)然,我們也可以選擇其他許可證,不管使用哪個許可證,發(fā)布插件時,最好都明確指出插件許可證。

在頭文件要求章節(jié),我們簡單說明了如何在插件頭文件注釋中指明插件許可證,另一個常見和鼓勵的做法是在插件主文件頂部,包含一個許可證塊注釋,示例如下:

/*
{Plugin Name} is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
any later version.

{Plugin Name} is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with {Plugin Name}. If not, see {URI to Plugin License}.
*/

與插件頭注釋一起使用時,看起來應(yīng)該像下面的樣子。

<?php
/*
Plugin Name: WordPress.org Plugin
Plugin URI:  https://developer.wordpress.org/plugins/the-basics/
Description: Basic WordPress Plugin Header Comment
Version:     20160911
Author:      WordPress.org
Author URI:  https://developer.wordpress.org/
Text Domain: wporg
Domain Path: /languages
License:     GPL2
 
{Plugin Name} is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
any later version.
 
{Plugin Name} is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with {Plugin Name}. If not, see {License URI}.
*/

激活/禁用鉤子

激活和禁用鉤子可以讓我們在激活或禁用插件時進(jìn)行一些操作。

在激活時,我們可以掛載一個函數(shù)來添加 URL 重寫規(guī)則,或者添加插件設(shè)置到數(shù)據(jù)庫中。

禁用時,我們可以掛載一個函數(shù)來刪除臨時數(shù)據(jù),如緩存和臨時文件和目錄。

禁用鉤子有時候會和卸載鉤子混淆,卸載鉤子適合永久刪除插件產(chǎn)生的,不再需要的數(shù)據(jù)。如插件設(shè)置或插件添加的自定義數(shù)據(jù)表。

激活

如果需要添加一個函數(shù)到激活鉤子上,使用 register_activation_hook() 函數(shù)。

register_activation_hook( __FILE__, 'pluginprefix_function_to_run' );

禁用

如果需要添加一個函數(shù)到禁用鉤子上,使用  register_deactivation_hook() 函數(shù)。

register_deactivation_hook( __FILE__, 'pluginprefix_function_to_run' );

每個函數(shù)中的第一個參數(shù)都指向插件的主文件(也就是包含插件頭注釋的文件),這兩個函數(shù)通常在插件主文件中被觸發(fā),當(dāng)然,我們也可以把這兩個函數(shù)放在其他文件中,這中情況下,我們必須更新第一個參數(shù)到正確位置。

示例

激活鉤子最常見的用途之一就是在插件注冊自定義文章類型時,刷新 WordPress 固定鏈接緩存,這樣做可以讓我們避免遇到 404 錯誤。示例如下:

function pluginprefix_setup_post_type() {
    // 注冊 book 自定義文章類型
    register_post_type( 'book', ['public' => 'true'] );
}
add_action( 'init', 'pluginprefix_setup_post_type' );
 
function pluginprefix_install() {
    // 觸發(fā)注冊自定義文章類型操作
    pluginprefix_setup_post_type();
 
    // 注冊文章類型之后,刷新固定鏈接緩存
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'pluginprefix_install' );

如果不知道怎么注冊自定義文章類型,不用擔(dān)心,我們稍后會介紹,上面的例子雖然簡單,但很常見。

上面的示例是激活插件時的操作,我們來看一下如何在插件禁用時,撤銷上面的操作。

inprefix_deactivation() {
    // 反注冊文章類型
    unregister_post_type( 'book' );
    // 刷新固定鏈接緩存
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'pluginprefix_deactivation' );

有關(guān)插件激活和禁用鉤子的更多信息,請參考以下鏈接:

卸載方法

如果我們的插件添加了一些設(shè)置到數(shù)據(jù)庫中,或者在用戶使用插件時生成了一些緩存文件,當(dāng)用戶卸載插件時,這些設(shè)置和文件很可能已經(jīng)沒用了。我們需要在用戶卸載插件時刪除這些數(shù)據(jù)。下面的表格說明了停用和卸載鉤子之間的區(qū)別。

操作禁用鉤子卸載鉤子
刷新插件產(chǎn)生的緩存
刷新 Url 重寫規(guī)則緩存
從 {$wpdb->prefix}_options 數(shù)據(jù)表中移除插件添加的數(shù)據(jù)
從 wpdb 中移除數(shù)據(jù)表

方法 1:register_uninstall_hook

掛載卸載函數(shù)到 register_uninstall_hook() 鉤子上。

register_uninstall_hook(__FILE__, 'pluginprefix_function_to_run');

方法 2:uninstall.php

使用此方法,我們需要在插件根目錄中創(chuàng)建一個名為 uninstall.php 的文件,這個文件中的函數(shù)會在用戶卸載插件時自動運(yùn)行。

例如:?/plugin-name/uninstall.php

使用 uninstall.php 時,在執(zhí)行之前應(yīng)先檢查常量 WP_UNINSTALL_PLUGIN 以防止直接訪問。此常量在 uninstall.php 調(diào)用期間由 WordPress 定義。由 register_uninstall_hook() 執(zhí)行卸載時,常量不會被定義。

最佳實踐

以下是關(guān)于 WordPress插件開發(fā)的一些最佳實踐,可以幫助我們在開發(fā)插件時更合理的組織代碼。

避免命名沖突

當(dāng)我們的插件和其他主題或插件使用了同一個函數(shù)或類名時,就會發(fā)生命名沖突。幸運(yùn)的是,我們可以通過下面的方法來避免命名沖突。

為什么會產(chǎn)品命名沖突

默認(rèn)情況下,所有變量、函數(shù)和類全部在全局命名空間中定義,也就是說,一個插件或主題可以覆蓋另外一個插件的變量、函數(shù)和類(在函數(shù)或類中定義的變量不會被覆蓋)。

為所有定義加上前綴

所有變量、函數(shù)和類都應(yīng)該有一個唯一前綴,前綴可以幫助我們避免和其他插件使用同一個變量、函數(shù)和類名,也可以避免這些定義被其他插件或主題覆蓋。

檢查所有的定義

PHP 提供了許多函數(shù)來驗證變量、函數(shù)、類和常量是否存在,如果這些定義存在,這些函數(shù)將返回 true

示例

<?php
//Create a function called wporg_init if it doesn't already exist
if ( !function_exists( 'wporg_init' ) ) {
    function wporg_init() {
        register_setting( 'wporg_settings', 'wporg_option_foo' );
    }
}
 
//Create a function called wporg_get_foo if it doesn't already exist
if ( !function_exists( 'wporg_get_foo' ) ) {
    function wporg_get_foo() {
        return get_option( 'wporg_option_foo' );
    }
}

OOP 面向?qū)ο缶幊?/h3>

解決命名空間沖突更簡單的辦法是使用類來組織插件的代碼,使用這個方法時,我們?nèi)匀恍枰獧z查類名是否已經(jīng)被其他插件或主題使用,相對于非 OOP 變成來說,我們只需要檢查類名即可。

示例

<?php
if ( !class_exists( 'WPOrg_Plugin' ) ) {
    class WPOrg_Plugin
    {
        public static function init() {
            register_setting( 'wporg_settings', 'wporg_option_foo' );
        }
 
        public static function get_foo() {
            return get_option( 'wporg_option_foo' );
        }
    }
 
    WPOrg_Plugin::init();
    WPOrg_Plugin::get_foo();
}

組織插件文件

插件根目錄應(yīng)該包含一個名為插件名稱的 plugin-name.php 文件,如果需要在卸載時執(zhí)行一些操作,還可以包含 uninstall.php 文件,其他文件盡可能組織到插件的子目錄中,子目錄名稱應(yīng)該盡量符合語義化規(guī)則。

目錄結(jié)構(gòu)

一個清晰的目錄結(jié)構(gòu)應(yīng)該把類型或功能相似的文件保存在同一個目錄中,下面是一個示例目錄結(jié)構(gòu)。

/ plugin-name
plugin-name.php
uninstall.php
/ languages
/ includes
/ admin
/ js
/ css
/ images
/ public
/ js
/ css
/ images

插件結(jié)構(gòu)

為插件選擇什么樣的架構(gòu)或者代碼組織風(fēng)格,取決于插件的大小。

對于與 WordPress 內(nèi)核、主題或其他插件交互有限的小型單一用途插件,使用一個文件就可以了。使用類這種復(fù)雜的結(jié)構(gòu)沒有任何好處,除非我們知道這個插件將來會有很多擴(kuò)展。

對于有大量代碼的大型插件,我們應(yīng)該參考上面的目錄結(jié)構(gòu),把樣式、JavaScript 腳本獨(dú)立出來,實現(xiàn)插件功能的不同函數(shù)或類也盡量獨(dú)立出來,放在單獨(dú)的子目錄,這將有助于保持插件代碼清晰和長期維護(hù)。

按需加載

將插件的管理代碼和公共代碼分開是很有必要的,我們可以使用 WordPress 條件函數(shù) is_admin 來實現(xiàn),例如:

<?php
if ( is_admin() ) {
    // we are in admin mode
    require_once( dirname( __FILE__ ) . '/admin/plugin-name-admin.php' );
}

架構(gòu)模式

雖然有很多結(jié)構(gòu)模式,但是大體上可以分為 3 種

  • 單個文件,包含很多函數(shù)
  • 單核插件文件,包含一個類,然后實例化這個類
  • 有一個主插件文件,包含一個或多個類文件

入門樣板插件

如果直接從頭開始寫一個插件,會做很多不必要的重復(fù)工作,我們可以使用樣板插件來開發(fā)每個新插件。使用樣板文件的一個優(yōu)點(diǎn)是在我們的插件中保持一致性。如果插件的用戶已經(jīng)熟悉了插件樣板,他們?yōu)椴寮暙I(xiàn)代碼的時候,也更加輕松。下面是幾個常用的 WordPress 樣板插件項目。

當(dāng)然,我們也可以根據(jù)自己的需要和風(fēng)格,定義自己的樣板插件。

我們提供 WordPress主題和插件定制開發(fā)服務(wù)

本站長期承接 WordPress主題、插件、基于 WooCommerce 的商店商城開發(fā)業(yè)務(wù)。 我們有 10 年WordPress開發(fā)經(jīng)驗,如果你想 用WordPress開發(fā)網(wǎng)站, 請聯(lián)系微信: iwillhappy1314,或郵箱: [email protected] 咨詢。

發(fā)表回復(fù)

您的郵箱地址不會被公開。 必填項已用 * 標(biāo)注

*