PHP中的物件導向程式設計:WordPress開發的變革

PHP中的物件導向程式設計:WordPress開發的變革

物件導向程式設計(OOP)是軟體中的一種重要正規化,其核心是 “物件”–包括資料和行為而非 “動作” 的類例項。

以伺服器端指令碼著稱的 PHP 從 OOP 中受益匪淺。這是因為 OPP 支援模組化和可重複使用的程式碼,使其更易於維護。反過來,這也有利於更好地組織和擴充套件大型專案。

對於使用 WordPress 主題、外掛和定製解決方案的開發人員來說,掌握 OOP 非常重要。在本文中,我們將概述什麼是 PHP 中的 OOP 以及它對 WordPress 開發的影響。我們還將指導您如何在 PHP 中實現 OOP 原則。

先決條件

要學習本文的實踐部分,請確保您已具備以下條件:

OOP 在 PHP 開發中的優勢

通過增強模組性、可重用性、可擴充套件性、可維護性和團隊合作,OOP 極大地促進了 PHP 的開發。它通過將 PHP 程式碼劃分為物件來組織 PHP 程式碼,每個物件代表應用程式的特定部分。使用物件,您可以輕鬆地重複使用程式碼,從而節省時間並減少錯誤。

有鑑於此,讓我們深入探討一下 PHP 中 OOP 的兩個具體優勢,重點介紹它是如何改變開發流程的。

1. 程式碼重用和維護

由於具有繼承性和多型性,PHP 中的 OOP 使得程式碼的重用變得簡單易行。類可以使用其他類的屬性和方法。這樣,只需稍加改動,就能以新的方式使用舊的程式碼。

OOP 還能讓你更輕鬆地管理程式碼。封裝意味著物件保持其細節的私密性,只共享所需的內容,並使用稱為 getterssetters 的特殊方法。這種方法有助於防止應用程式中某個部分的更改導致其他部分出現問題,從而使程式碼的更新和維護更加簡單。

此外,由於物件本身是完整的,因此查詢和修復系統某些部分的錯誤也變得更加容易。這就提高了程式碼的整體質量和可靠性。

2. 增強清晰度和結構

使用類(classes)和物件(objects),OOP 使 PHP 程式碼更簡潔、更有條理。類就像物件的模板,將所有屬於同一個地方的東西放在一起。

OOP 還允許類使用其他類的功能,這意味著你不必重複編寫相同的程式碼。所有這些都有助於使程式碼更簡潔、更易修復、更有條理。

OOP 帶來的清晰程式碼有助於團隊更好地協同工作。每個人都更容易理解程式碼的作用,這意味著解釋的時間更少,工作的時間更多。它還能減少錯誤,幫助專案步入正軌。當程式碼整齊有序時,團隊中的新成員也能很快跟上進度。

在 PHP 中實現 OOP

在 PHP 的 OOP 中,您使用類和物件來組織程式碼,就像藍圖和房屋一樣。你可以為任何事物(如使用者或書籍)建立類,包括它們的特徵和動作。然後,使用繼承從現有的類建立新的類,這樣就不會重複程式碼,節省了時間。而且,由於封裝使類的某些部分保持私有,因此程式碼更加安全。

下面的章節將教你如何在 PHP 程式設計中有效地使用 OOP 原則。我們建立了一個內容管理系統(CMS)來管理文章。

1. 定義一個具有屬性和方法的類

首先建立一個包含標題、內容和狀態屬性的 Article 類,以及設定和顯示這些屬性的方法。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class Article {
private $title;
private $content;
private $status;
const STATUS_PUBLISHED = 'published';
const STATUS_DRAFT = 'draft';
public function __construct($title, $content) {
$this->title = $title;
$this->content = $content;
$this->status = self::STATUS_DRAFT;
}
public function setTitle($title) {
$this->title = $title;
return $this;
}
public function setContent($content) {
$this->content = $content;
return $this;
}
public function setStatus($status) {
$this->status = $status;
return $this;
}
public function display() {
echo "<h2>{$this->title}</h2><p>{$this->content}</p><strong>Status: {$this->status}</strong>";
}
}
class Article { private $title; private $content; private $status; const STATUS_PUBLISHED = 'published'; const STATUS_DRAFT = 'draft'; public function __construct($title, $content) { $this->title = $title; $this->content = $content; $this->status = self::STATUS_DRAFT; } public function setTitle($title) { $this->title = $title; return $this; } public function setContent($content) { $this->content = $content; return $this; } public function setStatus($status) { $this->status = $status; return $this; } public function display() { echo "<h2>{$this->title}</h2><p>{$this->content}</p><strong>Status: {$this->status}</strong>"; } }
class Article {
private $title;
private $content;
private $status;
const STATUS_PUBLISHED = 'published';
const STATUS_DRAFT = 'draft';
public function __construct($title, $content) {
$this->title = $title;
$this->content = $content;
$this->status = self::STATUS_DRAFT;
}
public function setTitle($title) {
$this->title = $title;
return $this;
}
public function setContent($content) {
$this->content = $content;
return $this;
}
public function setStatus($status) {
$this->status = $status;
return $this;
}
public function display() {
echo "<h2>{$this->title}</h2><p>{$this->content}</p><strong>Status: {$this->status}</strong>";
}
}

2. 建立物件並實現方法鏈

建立一個文章物件,並使用方法鏈設定其屬性:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$article = new Article("OOP in PHP", "Object-Oriented Programming concepts.");
$article->setTitle("Advanced OOP in PHP")->setContent("Exploring advanced concepts in OOP.")->setStatus(Article::STATUS_PUBLISHED)->display();
$article = new Article("OOP in PHP", "Object-Oriented Programming concepts."); $article->setTitle("Advanced OOP in PHP")->setContent("Exploring advanced concepts in OOP.")->setStatus(Article::STATUS_PUBLISHED)->display();
$article = new Article("OOP in PHP", "Object-Oriented Programming concepts.");
$article->setTitle("Advanced OOP in PHP")->setContent("Exploring advanced concepts in OOP.")->setStatus(Article::STATUS_PUBLISHED)->display();

3. 加強封裝和繼承

使用 getter 和 setter 方法加強封裝,並建立一個繼承自 ArticleFeaturedArticle 類:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class FeaturedArticle extends Article {
private $highlightColor = '#FFFF00'; // Default highlight color
public function setHighlightColor($color) {
$this->highlightColor = $color;
return $this;
}
public function display() {
echo "<div> style='background-color: {$this->highlightColor};'>";
parent::display();
echo "</div>";
}
}
$featuredArticle = new FeaturedArticle("Featured Article", "This is a featured article.");
$featuredArticle->setStatus(FeaturedArticle::STATUS_PUBLISHED)->setHighlightColor('#FFA07A')->display();
class FeaturedArticle extends Article { private $highlightColor = '#FFFF00'; // Default highlight color public function setHighlightColor($color) { $this->highlightColor = $color; return $this; } public function display() { echo "<div> style='background-color: {$this->highlightColor};'>"; parent::display(); echo "</div>"; } } $featuredArticle = new FeaturedArticle("Featured Article", "This is a featured article."); $featuredArticle->setStatus(FeaturedArticle::STATUS_PUBLISHED)->setHighlightColor('#FFA07A')->display();
class FeaturedArticle extends Article {
private $highlightColor = '#FFFF00'; // Default highlight color
public function setHighlightColor($color) {
$this->highlightColor = $color;
return $this;
}
public function display() {
echo "<div> style='background-color: {$this->highlightColor};'>";
parent::display();
echo "</div>";
}
}
$featuredArticle = new FeaturedArticle("Featured Article", "This is a featured article.");
$featuredArticle->setStatus(FeaturedArticle::STATUS_PUBLISHED)->setHighlightColor('#FFA07A')->display();

4. 介面和多型性

為可釋出內容定義一個介面,並在 Article 類中實現該介面,以演示多型性:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
interface Publishable {
public function publish();
}
class Article implements Publishable {
// Existing class code...
public function publish() {
$this->setStatus(self::STATUS_PUBLISHED);
echo "Article '{$this->title}' published.";
}
}
function publishContent(Publishable $content) {
$content->publish();
}
publishContent($article);
interface Publishable { public function publish(); } class Article implements Publishable { // Existing class code... public function publish() { $this->setStatus(self::STATUS_PUBLISHED); echo "Article '{$this->title}' published."; } } function publishContent(Publishable $content) { $content->publish(); } publishContent($article);
interface Publishable {
public function publish();
}
class Article implements Publishable {
// Existing class code...
public function publish() {
$this->setStatus(self::STATUS_PUBLISHED);
echo "Article '{$this->title}' published.";
}
}
function publishContent(Publishable $content) {
$content->publish();
}
publishContent($article);

5. 使用特質實現共享行為

PHP 允許使用特質為類新增功能,而無需從其他類繼承。使用下面的程式碼,引入一個用於記錄 CMS 中活動的特性:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
trait Logger {
public function log($message) {
// Log message to a file or database
echo "Log: $message";
}
}
class Article {
use Logger;
// Existing class code...
public function publish() {
$this->setStatus(self::STATUS_PUBLISHED);
$this->log("Article '{$this->title}' published.");
}
}
trait Logger { public function log($message) { // Log message to a file or database echo "Log: $message"; } } class Article { use Logger; // Existing class code... public function publish() { $this->setStatus(self::STATUS_PUBLISHED); $this->log("Article '{$this->title}' published."); } }
trait Logger {
public function log($message) {
// Log message to a file or database
echo "Log: $message";
}
}
class Article {
use Logger;
// Existing class code...
public function publish() {
$this->setStatus(self::STATUS_PUBLISHED);
$this->log("Article '{$this->title}' published.");
}
}

WordPress 開發中的 OOP

OOP 原則大大增強了 WordPress 的開發能力,尤其是在建立主題、外掛和小工具時。在 OOP 的幫助下,您可以為 WordPress 網站編寫更簡潔、可擴充套件和可維護的程式碼。

本節回顧瞭如何在 WordPress 開發中應用 OOP。我們將提供一些示例,您可以複製並貼上到 WordPress 部署中進行測試。

WordPress 主題中的 OOP:自定義文章型別註冊

為了演示如何在 WordPress 主題中使用 OOP,您需要建立一個類來處理自定義文章型別的註冊。

將以下程式碼放入主題的 functions.php 檔案中。您可以在 wp-content/themes 目錄中找到您的主題。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class CustomPostTypeRegistrar {
private $postType;
private $args;
public function __construct($postType, $args = []) {
$this->postType = $postType;
$this->args = $args;
add_action('init', array($this, 'registerPostType'));
}
public function registerPostType() {
register_post_type($this->postType, $this->args);
}
}
// Usage
$bookArgs = [
'public' => true,
'label' => 'Books',
'supports' => ['title', 'editor', 'thumbnail'],
'has_archive' => true,
];
new CustomPostTypeRegistrar('book', $bookArgs);
class CustomPostTypeRegistrar { private $postType; private $args; public function __construct($postType, $args = []) { $this->postType = $postType; $this->args = $args; add_action('init', array($this, 'registerPostType')); } public function registerPostType() { register_post_type($this->postType, $this->args); } } // Usage $bookArgs = [ 'public' => true, 'label' => 'Books', 'supports' => ['title', 'editor', 'thumbnail'], 'has_archive' => true, ]; new CustomPostTypeRegistrar('book', $bookArgs);
class CustomPostTypeRegistrar {
private $postType;
private $args;
public function __construct($postType, $args = []) {
$this->postType = $postType;
$this->args = $args;
add_action('init', array($this, 'registerPostType'));
}
public function registerPostType() {
register_post_type($this->postType, $this->args);
}
}
// Usage
$bookArgs = [
'public' => true,
'label'  => 'Books',
'supports' => ['title', 'editor', 'thumbnail'],
'has_archive' => true,
];
new CustomPostTypeRegistrar('book', $bookArgs);

這段程式碼動態註冊了一個自定義文章型別 book,其詳細資訊通過 bookArgs 陣列傳遞。您可以在 WordPress 管理側邊欄中看到新建立的自定義文章型別,標籤 Books

Books 自定義文章型別側邊欄元素

Books 自定義文章型別側邊欄元素

本示例說明了 OOP 如何封裝註冊自定義文章型別的功能,使其可重複用於不同型別的文章。

WordPress 外掛中的 OOP:簡碼處理程式

在一個外掛示例中,您需要開發一個類來處理用於顯示特殊資訊的簡碼。您可以將下面的簡碼新增到任何文章或頁面中,以測試此功能。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/**
* Plugin Name: OOP Shortcode Handler
* Description: Handles a custom shortcode with OOP.
* Version: 1.0
* Author: Name
*/
class OOPShortcodeHandler {
public function __construct() {
add_shortcode('oop_message', array($this, 'displayCustomMessage'));
}
public function displayCustomMessage($atts) {
$attributes = shortcode_atts(['message' => 'Hello, this is your OOP
message!'], $atts);
return "<div>{$attributes['message']}</div>";
}
}
new OOPShortcodeHandler();
<?php /** * Plugin Name: OOP Shortcode Handler * Description: Handles a custom shortcode with OOP. * Version: 1.0 * Author: Name */ class OOPShortcodeHandler { public function __construct() { add_shortcode('oop_message', array($this, 'displayCustomMessage')); } public function displayCustomMessage($atts) { $attributes = shortcode_atts(['message' => 'Hello, this is your OOP message!'], $atts); return "<div>{$attributes['message']}</div>"; } } new OOPShortcodeHandler();
<?php
/**
* Plugin Name: OOP Shortcode Handler
* Description: Handles a custom shortcode with OOP.
* Version: 1.0
* Author: Name
*/
class OOPShortcodeHandler {
public function __construct() {
add_shortcode('oop_message', array($this, 'displayCustomMessage'));
}
public function displayCustomMessage($atts) {
$attributes = shortcode_atts(['message' => 'Hello, this is your OOP     
message!'], $atts);
return "<div>{$attributes['message']}</div>";
}
}
new OOPShortcodeHandler();

將其儲存為 wp-content/plugins 目錄中的 my-oop-shortcode-handler.php。最後,啟用外掛。

外掛頁面上列出的我的 OOP 短程式碼處理程式

外掛頁面上列出的我的 OOP 短程式碼處理程式

接下來,在釋出或更新之前,在頁面或文章編輯器中使用 [oop_message][oop_message message="Custom Message Here"] 快捷程式碼,如下所示:

 

新增了自定義快捷程式碼資訊

編輯模式下的示例頁面,新增了自定義快捷程式碼資訊。

釋出或更新 page/post 後,您會看到簡碼顯示的資訊。

 

帶有自定義簡碼資訊的示例頁面

已釋出的帶有自定義簡碼資訊的示例頁面。

WordPress 小工具中的 OOP:動態內容小工具

通過在類中封裝小工具的功能,OOP 對 widget 也大有裨益。WordPress 核心本身就為小工具使用了 OOP。在這裡,您可以建立一個自定義小工具,讓使用者通過標題和文字區域顯示動態內容。

將以下程式碼新增到主題的 functions.php 檔案或外掛中。它定義了一個自定義小工具,用於顯示 “Hello World From My Custom Widget!” 訊息。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class My_Custom_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'my_custom_widget', // Base ID
'My Custom Widget', // Name
array('description' => __('A simple custom widget.',
'text_domain'),) // Args
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title',
$instance['title']) . $args['after_title'];
}
// Widget content
echo __('Hello World From My Custom Widget!', 'text_domain');
echo $args['after_widget'];
}
public function form($instance) {
// Form in WordPress admin
}
public function update($new_instance, $old_instance) {
// Processes widget options to be saved
}
}
function register_my_custom_widget() {
register_widget('My_Custom_Widget');
}
add_action('widgets_init', 'register_my_custom_widget');
class My_Custom_Widget extends WP_Widget { public function __construct() { parent::__construct( 'my_custom_widget', // Base ID 'My Custom Widget', // Name array('description' => __('A simple custom widget.', 'text_domain'),) // Args ); } public function widget($args, $instance) { echo $args['before_widget']; if (!empty($instance['title'])) { echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title']; } // Widget content echo __('Hello World From My Custom Widget!', 'text_domain'); echo $args['after_widget']; } public function form($instance) { // Form in WordPress admin } public function update($new_instance, $old_instance) { // Processes widget options to be saved } } function register_my_custom_widget() { register_widget('My_Custom_Widget'); } add_action('widgets_init', 'register_my_custom_widget');
class My_Custom_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'my_custom_widget', // Base ID
'My Custom Widget', // Name
array('description' => __('A simple custom widget.', 
'text_domain'),) // Args
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title',  
$instance['title']) . $args['after_title'];
}
// Widget content
echo __('Hello World From My Custom Widget!', 'text_domain');
echo $args['after_widget'];
}
public function form($instance) {
// Form in WordPress admin
}
public function update($new_instance, $old_instance) {
// Processes widget options to be saved
}
}
function register_my_custom_widget() {
register_widget('My_Custom_Widget');
}
add_action('widgets_init', 'register_my_custom_widget');

在使用管理區外觀下的自定義連結編輯活動主題時,您可以根據需要新增新的自定義小工具。

側邊欄上的自定義小工具

側邊欄上的自定義小工具設定和示例頁面上的小工具使用。

使用 WordPress 類

WordPress 提供了各種類,您可以用它們與內容管理系統的核心功能進行互動。其中兩個類是 WP_UserWP_Post ,它們分別代表使用者和文章。

擴充套件上文的 WordPress 外掛示例,結合這些類建立一個簡碼,顯示文章作者的資訊和帖子本身的詳細資訊。

將其儲存為 wp-content/plugins 目錄中的 my-oop-shortcode-handler-extended.php。最後,啟用外掛。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/**
* Plugin Name: Extended OOP Shortcode Handler
* Description: Extends the shortcode handler to display post and author
information.
* Version: 1.1
* Author: Your Name
*/
class ExtendedOOPShortcodeHandler {
public function __construct() {
add_shortcode('post_author_details', array($this,
'displayPostAuthorDetails'));
}
public function displayPostAuthorDetails($atts) {
global $post; // Accessing the global $post object to get current post
details
$attributes = shortcode_atts([
'post_id' => $post->ID, // Default to the current post ID
], $atts);
$postDetails = get_post($attributes['post_id']); // Getting the WP_Post
object
if (!$postDetails) {
return "Post not found.";
}
$authorDetails = new WP_User($postDetails->post_author); // Getting the
WP_User object
$output = "<div class='post-author-details'>";
$output .= "<h2>Author Information</h2>";
$output .= "<p>Name: " . esc_html($authorDetails->display_name) .
"</p>";
$output .= "<h2>Post Information</h2>";
$output .= "<p>Title: " . esc_html($postDetails->post_title) . "</p>";
$output .= "<p>Content: " .
esc_html(wp_trim_words($postDetails->post_content, 20, '...')) . "</p>";
$output .= "</div>";
return $output;
}
}
new ExtendedOOPShortcodeHandler();
<?php /** * Plugin Name: Extended OOP Shortcode Handler * Description: Extends the shortcode handler to display post and author information. * Version: 1.1 * Author: Your Name */ class ExtendedOOPShortcodeHandler { public function __construct() { add_shortcode('post_author_details', array($this, 'displayPostAuthorDetails')); } public function displayPostAuthorDetails($atts) { global $post; // Accessing the global $post object to get current post details $attributes = shortcode_atts([ 'post_id' => $post->ID, // Default to the current post ID ], $atts); $postDetails = get_post($attributes['post_id']); // Getting the WP_Post object if (!$postDetails) { return "Post not found."; } $authorDetails = new WP_User($postDetails->post_author); // Getting the WP_User object $output = "<div class='post-author-details'>"; $output .= "<h2>Author Information</h2>"; $output .= "<p>Name: " . esc_html($authorDetails->display_name) . "</p>"; $output .= "<h2>Post Information</h2>"; $output .= "<p>Title: " . esc_html($postDetails->post_title) . "</p>"; $output .= "<p>Content: " . esc_html(wp_trim_words($postDetails->post_content, 20, '...')) . "</p>"; $output .= "</div>"; return $output; } } new ExtendedOOPShortcodeHandler();
<?php
/**
* Plugin Name: Extended OOP Shortcode Handler
* Description: Extends the shortcode handler to display post and author 
information.
* Version: 1.1
* Author: Your Name
*/
class ExtendedOOPShortcodeHandler {
public function __construct() {
add_shortcode('post_author_details', array($this,   
'displayPostAuthorDetails'));
}
public function displayPostAuthorDetails($atts) {
global $post; // Accessing the global $post object to get current post  
details
$attributes = shortcode_atts([
'post_id' => $post->ID, // Default to the current post ID
], $atts);
$postDetails = get_post($attributes['post_id']); // Getting the WP_Post  
object
if (!$postDetails) {
return "Post not found.";
}
$authorDetails = new WP_User($postDetails->post_author); // Getting the 
WP_User object
$output = "<div class='post-author-details'>";
$output .= "<h2>Author Information</h2>";
$output .= "<p>Name: " . esc_html($authorDetails->display_name) . 
"</p>";
$output .= "<h2>Post Information</h2>";
$output .= "<p>Title: " . esc_html($postDetails->post_title) . "</p>";
$output .= "<p>Content: " . 
esc_html(wp_trim_words($postDetails->post_content, 20, '...')) . "</p>";
$output .= "</div>";
return $output;
}
}
new ExtendedOOPShortcodeHandler();

在此擴充套件版本中,您建立了一個簡碼: [post_author_details post_id="1"]

 

編輯模式下的示例頁面

新增了擴充套件自定義簡碼資訊的編輯模式下的示例頁面。

當新增到文章或頁面時,它會顯示文章作者(使用 WP_User 類)和文章本身(使用 WP_Post 類)的詳細資訊。

 

OOP 和 WordPress REST API

WordPress REST API 是 WordPress 的一個新功能,可以讓您以更可程式設計的方式與網站資料互動。它廣泛利用了 OOP,使用類來定義端點、響應和請求處理。這顯然是從傳統的程式根基轉向擁抱 OOP。

與 OOP 原則形成鮮明對比的是,WordPress的大部分核心內容,尤其是其早期元件,如主題和外掛API,都是以程序式程式設計風格編寫的。

例如,程式式方法可能會直接操作全域性變數,並依賴一系列函式來完成任務,而 REST API 中的 OOP 則將邏輯封裝在類中。因此,這些類中的特定方法可以處理獲取、建立、更新或刪除帖子等任務。

這就清楚地分離了關注點,使程式碼庫更易於擴充套件和除錯。

通過定義端點和處理請求的類,例如通過 GET /wp-json/wp/v2/posts 請求獲取文章,REST API 提供了一種結構化、可擴充套件的方式來與 WordPress 資料互動,並返回 JSON 格式的響應。

小結

正如您在本文中所看到的,OOP 為 PHP 和 WordPress 開發提供了無與倫比的靈活性、可擴充套件性和可維護性。

評論留言