ソフトウェアにおける重要なパラダイムとも言えるオブジェクト指向プログラミング(OOP)は、「アクション」の代わりにデータや機能を含むクラスのインスタンスである「オブジェクト」に焦点を当てたものです。

サーバーサイドのプログラミング言語として知られるPHPは、OOPから大きな恩恵を受けています。というのも、OPPはモジュール型の再利用可能なコードをサポートし、これによりコードの保守が容易になります。その結果、大規模なプロジェクトの組織化やスケーラビリティが向上します。

OOPをマスターすることは、WordPressのテーマやプラグイン、カスタムソリューションを扱う開発者にとって重要です。この記事では、PHPにおけるOOPとは何か、そしてそれがWordPress開発に与える影響について概説します。また、PHPでOOPの原則を実装する方法についてもご説明します。

前提条件

この記事のハンズオン形式の解説に従うには、以下が必要になります。

PHP開発におけるOOPの利点

OOPは、モジュール性、再利用性、スケーラビリティ、保守性、チームワークを向上させることで、PHP開発を大きく後押しします。OOPではPHPコードをオブジェクトに分割して整理し、それぞれがアプリケーションの特定の部分を表現します。オブジェクトを使用することで、コードを簡単に再利用することができ、 時間を節約しながら、エラーを減らすことができます。

このことを念頭に置いて、PHPにおけるOOPの2つの具体的な利点を扱い、それが開発プロセスをどのように変えるかを見てみましょう。

1. コードの再利用とメンテナンス

PHPのOOPでは、継承とポリモーフィズムのおかげで、コードの再利用が簡単になります。クラスは、他のクラスのプロパティやメソッドを使用することができます。これにより、古いコードをほとんど変更せずに新しい方法で使用できます。

OOPでは、コードの管理も簡単です。カプセル化が行われ、gettersetterと呼ばれる特別なメソッドを使って、オブジェクトがその詳細をプライベートに保ち、必要なものだけを共有することになります。このアプローチは、アプリケーションの一部分の変更が他の部分で問題を引き起こすのを防ぎ、コードの更新や保守をより簡単にすることにつながります。

また、オブジェクトはそれ自体で完結しているため、システムの特定の部分のバグを発見し、修正することが容易になります。これにより、コード全体の質と信頼性が向上します。

2. 明快さと構造の向上

OOP では、クラスオブジェクトを使用することでPHPコードをよりすっきりと整理することができます。クラスはオブジェクトのテンプレートのような役割を果たし、 一緒になるべきものをすべて一か所にまとめておくことができます。

つまり、同じコードを繰り返し書く必要がなくなります。これらはすべて、コードをすっきりさせ、修正しやすくし、整理しやすくするのに役立ちます。

OOPによる明瞭なコードは、チームワーク向上にも貢献します。というのも、コードについて説明する時間を減らし、仕事に集中する時間を増やすことができます。また、ミスが減り、プロジェクトを軌道に乗せる上でも効果的です。また、コードが整然としていれば、新規加入のチームメンバーもすぐにその構造を理解することができます。

PHPでOOPを実装する

PHPのOOPでは、設計図や家のように、クラスとオブジェクトでコードを整理します。すべてのもの(ユーザーや本など)に対して、その特性やアクションを含むクラスを作成します。そして、継承を使用して既存のクラスから新しいクラスを作成します。また、カプセル化によってクラスの一部が非公開になるため、コードがより安全になります。

以下のセクションでは、PHPプログラミングでOOPの原則を効果的に使用する方法をご紹介します。記事を管理するのに便利なコンテンツ管理システム(CMS)を作成してみましょう。

1. プロパティとメソッドを持つクラスを定義する

タイトル、コンテンツ、ステータスのプロパティと、これらのプロパティを設定したり表示したりするメソッドを含むArticleクラスから始めます。

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. オブジェクトを作成しメソッドチェーンを実装する

記事(Article)オブジェクトを作成し、そのプロパティを設定するためにメソッドチェーンを使います。

$article = new Article("OOP in PHP", "オブジェクト指向プログラミングの概念");
$article->setTitle("PHPにおける高度なOOP")->setContent("OOPの高度な概念に迫る。")->setStatus(Article::STATUS_PUBLISHED)->display();

3. カプセル化と継承の強化

getterメソッドとsetterメソッドを使ってカプセル化を強化し、Articleを継承したFeaturedArticleクラスを作成します。

class FeaturedArticle extends Article {
    private $highlightColor = '#FFFF00'; // デフォルトのハイライトカラー

    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("注目の記事", "注目の記事をご紹介します。");
$featuredArticle->setStatus(FeaturedArticle::STATUS_PUBLISHED)->setHighlightColor('#FFA07A')->display();

4. インターフェースとポリモーフィズム

公開可能なコンテンツのインタフェースを定義し、Articleクラスに実装して多相性を表現します。

interface Publishable {
    public function publish();
}

class Article implements Publishable {
    // 既存のクラスコード...

    public function publish() {
        $this->setStatus(self::STATUS_PUBLISHED);
        echo "Article '{$this->title}' published.";
    }
}

function publishContent(Publishable $content) {
    $content->publish();
}

publishContent($article);

5. traitを使って挙動を共有する

PHPでは、他のクラスを継承しなくてもtraitを使ってクラスに関数を追加することができます。以下のコードで、CMS内のログを記録するためのtraitを導入します。

trait Logger {
    public function log($message) {
        // ログメッセージをファイルまたはデータベースに記録
        echo "Log: $message";
    }
}

class Article {
    use Logger;

    // 既存のクラスコード...

    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ディレクトリにあります。

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

// 使用
$bookArgs = [
    'public' => true,
    'label'  => 'Books',
    'supports' => ['title', 'editor', 'thumbnail'],
    'has_archive' => true,
];
new CustomPostTypeRegistrar('book', $bookArgs);

このコードでは、カスタム投稿タイプbookを動的に登録し、その詳細をbookArgsという配列を使って渡しています。このようにして作成したカスタム投稿タイプは、WordPress管理画面サイドバーのBooksラベルで確認できます。

WordPressのBooksページのスクリーンショット(ページの上部には、新規投稿を追加するボタンがある)
Booksという名前のカスタム投稿タイプとその新規追加画面

この例からは、どのようにOOPを使って機能のカプセル化とカスタム投稿タイプの登録ができるのかがわかります。結果として、これをあらゆるタイプの投稿に対して再利用することができます。

WordPressプラグインにおけるOOPショートコードハンドラ

プラグインの例として、特別なメッセージを表示するためのショートコードを処理するクラスを開発してみましょう。以下のショートコードを任意の投稿やページに追加することで、この機能をテストできます。

<?php
/**
* Plugin Name: OOP Shortcode Handler
* Description: 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' => 'メッセージを表示しています!'], $atts);
        return "<div>{$attributes['message']}</div>";
    }
}

new OOPShortcodeHandler();

これをwp-content/pluginsディレクトリにmy-oop-shortcode-handler.phpとして保存します。最後にプラグインを有効化します。

プラグインページのスクリーンショット(ページ上部には新しいプラグイン追加のボタンがあり、その下にプラグインの一覧がある。作成したOOP Shortcode Handlerが有効になっている)
プラグインページにMy OOP Shortcode Handlerが表示されている

次に、公開または更新する前に、ページまたは投稿エディターで、以下のようにショートコード[oop_message][oop_message message="カスタムメッセージ"]を使用します。

サンプルページのスクリーンショット("[oop_message]"と"[oop_message message="Custom Message Here"]"というコードが表示されている。さらにそれに"This is an example page..."という文章が続く)
カスタムショートコードメッセージが追加されたサンプルページ
公開または更新すると、ショートコードによりメッセージが表示されます。

サンプルページのスクリーンショット("Hello, this is your OOP message!"と"This is a custom message."そしてその後にサンプルの文章が表示されている)
サンプルページにカスタムショートコードのメッセージが表示されている

WordPressウィジェットにおけるOOP─ダイナミックコンテンツウィジェット

ウィジェットの機能をクラス内にカプセル化できるため、OOPはウィジェットにとっても有益です。WordPressのコア自体が、ウィジェットにOOPを使用しています。それでは、ユーザーによるタイトルとテキストエリアを持つ動的なコンテンツの表示を可能にするカスタムウィジェットを作成してみましょう。

以下のコードをテーマのfunctions.phpファイルまたはプラグインとして追加します。これにより、「カスタムウィジェットです!」というメッセージを表示するカスタムウィジェットが定義できます。

class My_Custom_Widget extends WP_Widget {

    public function __construct() {
        parent::__construct(
            'my_custom_widget', // 基本ID
            'My Custom Widget', // 名前
            array('description' => __('シンプルなカスタムウィジェット', 
'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'];
        }
        // ウィジェットのコンテンツ
        echo __('カスタムウィジェットです!', 'text_domain');
        echo $args['after_widget'];
    }

    public function form($instance) {
        // WordPress管理画面のフォーム
    }

    public function update($new_instance, $old_instance) {
        // 保存するウィジェットオプションを処理
    }
}

function register_my_custom_widget() {
    register_widget('My_Custom_Widget');
}
add_action('widgets_init', 'register_my_custom_widget');

管理画面内「外観」の下にある「カスタマイズ」を使用してテーマの好みの場所に作成したばかりのカスタムウィジェットを追加できます。

WordPressサイトのランディングページのスクリーンショット(ページの左側には、最近の投稿と最近のコメントを示すメニューと公開ボタンがある)
サイドバーのカスタムウィジェットの設定とサンプルページでのウィジェットの使用

WordPressクラスの活用

WordPressには、CMSのコア機能と相互にやりとりするための様々なクラスが用意されています。そのようなクラスとして、WP_UserWP_Postがあり、それぞれユーザーと投稿を表します。

上記のWordPressプラグインの例を拡張して、これらのクラスを組み込み、投稿の作者に関する情報と投稿自体の詳しい情報を表示するショートコードを作成してみましょう。

wp-content/pluginsディレクトリにmy-oop-shortcode-handler-extended.phpとして保存し、プラグインを有効化します。

<?php
/**
* Plugin Name: Extended OOP Shortcode Handler
* Description: ショートコードハンドラを拡張し投稿と作者の情報を表示します。
* 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; // グローバル$postオブジェクトにアクセスして現在の投稿の情報を取得する

        $attributes = shortcode_atts([
            'post_id' => $post->ID, // デフォルトは既存の投稿ID
        ], $atts);

        $postDetails = get_post($attributes['post_id']); // WP_Postオブジェクトの取得
        if (!$postDetails) {
            return "ページが見つかりませんでした。";
        }

        $authorDetails = new WP_User($postDetails->post_author); // WP_Userオブジェクトの取得

        $output = "<div class='post-author-details'>";
        $output .= "<h2>作者情報</h2>";
        $output .= "<p>名前:" . esc_html($authorDetails->display_name) . 
"</p>";
        $output .= "<h2>投稿情報</h2>";
        $output .= "<p>タイトル:" . esc_html($postDetails->post_title) . "</p>";
        $output .= "<p>コンテンツ:" . 
esc_html(wp_trim_words($postDetails->post_content, 20, '...')) . "</p>";
        $output .= "</div>";

        return $output;
    }
}

new ExtendedOOPShortcodeHandler();

この拡張バージョンでは、[post_author_details post_id="1"]というショートコードが生成されます。

サンプルページのスクリーンショット("[post_author_details post_id="1"]"コードとその下に"This is the rest of the article..."という文章がある。その下には"Type / to choose a block"というメッセージが続く)
拡張カスタムショートコードのメッセージを追加した状態のサンプルページ
投稿やページに追加すると、投稿の作者(WP_Userクラスを使用)と投稿自体(WP_Postクラスを使用)に関する情報が表示されます。

OOPとWordPress REST API

WordPress REST APIはWordPressに追加された最新のAPIで、これを使ってプログラムを介してサイトのデータを扱うことができます。これにも、OOPが活用されています。エンドポイント、レスポンス、リクエストの処理をクラスが定義します。従来の手続き的なアプローチからOOP採用への明確な移行を意味する一例です。

OOPの原則とは対照的に、WordPressのコアの多く、特にテーマやプラグインAPIなどの初期のコンポーネントは、手続き型プログラミングスタイルで書かれています。

手続き型に分類されるアプローチではグローバル変数を直接操作し、タスクの一連の関数に依存するのが典型ですが、REST APIにおけるOOPはロジックをクラス内にカプセル化します。このような理由で、これらのクラス内の特定のメソッドが、投稿のフェッチ、作成、更新、削除などのタスクを処理することになります。

これにより、懸念事項が明確に分離され、コードの拡張やデバッグが容易になります。

エンドポイントを定義し、GET /wp-json/wp/v2/postsリクエストで投稿を取得するようなリクエストを処理するクラスを通して、REST APIはWordPressデータとの構造的な対話を可能にし、JSONフォーマットのレスポンスを返します。

PHPとWordPressのホスティングにKinstaを活用する

Kinstaのホスティングソリューションは、PHPアプリケーションの最適化とWordPressホスティングの管理を包括的に支援し、従来型のPHPセットアップとWordPress固有の要件に対応します。Google Cloudをはじめとする最先端の技術で構築された堅牢なインフラストラクチャにより、KinstaはOOPベースのPHPアプリケーションの比類ないパフォーマンスとスケーラビリティを実現します。

WordPressサイト向けに、KinstaのWordPressホスティングサービスは自動アップデート、セキュリティ監視、エンジニアによるサポートなどの機能を提供しています。KinstaのWordPress専用マネージドホスティングサービスは、手間をかけずに優れたパフォーマンスを実現したい開発者や事業者の方にうってつけです。

まとめ

今回の記事を通してご紹介したとおり、OOPはPHPとWordPressの開発において比類のない柔軟性、拡張性、保守性を可能にします。

WordPress専用マネージドホスティング会社として、Kinstaはこのニーズを認識し、お客様のようなOOP PHP開発者の方々をサポートする独自のソリューションをご用意しています。KinstaのアプリケーションおよびWordPress専用マネージドホスティングソリューションは、パフォーマンス、拡張性、およびOOPベースのWordPressプロジェクトの構築を後押しする設計です。

今すぐKinstaをお試しいただき、WordPressサイトの構築や管理がどれだけ捗るかその性能をお確かめください。

プロジェクトでOOPの利点を実感したことはありますか?またはOOPで開発プロセスをどのように変えることができると思いますか?以下のコメント欄でお聞かせください。

Jeremy Holcombe Kinsta

Kinstaのコンテンツ&マーケティングエディター、WordPress開発者、コンテンツライター。WordPress以外の趣味は、ビーチでのんびりすること、ゴルフ、映画。高身長が特徴。