wordpress-plugin-core について
wordpress-plugin-coreは、WordPressプラグイン開発者向けのスキルです。セキュアな実装、アーキテクチャ選択、機能パターン、配布方法を扱います。
主な機能
- 01プラグイン構成の選択
- 02セキュリティ確認とデータ処理
- 038種類の機能実装パターン
- 04更新と配布のガイド
活用シーン
- 01小規模・大規模プラグインの開発開始
- 02フォームやデータベースクエリの保護
- 03REST APIエンドポイントやカスタム投稿タイプの追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill wordpress-plugin-coreインストール後、Claude Code で/wordpress-plugin-coreを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/example-template.txtexamples/github-updater.phpreferences/advanced-topics.mdcommon-hooks.mdcommon-patterns.mderror-catalog.mdexample-reference.mdgithub-auto-updates.mdplugin-architectures.mdsecurity-checklist.mdscripts/example-script.shscaffold-plugin.shtemplates/examples/ajax-handler.phpcustom-post-type.phpmeta-box.phprest-endpoint.phpsettings-page.phptemplates/plugin-oop/my-oop-plugin.phpREADME.mduninstall.phptemplates/plugin-oop/views/admin-settings.phptemplates/plugin-psr4/composer.jsonmy-psr4-plugin.phpREADME.mdtemplates/plugin-psr4/src/Plugin.phptemplates/plugin-psr4/src/Admin/Settings.phptemplates/plugin-psr4/src/API/BookEndpoints.phptemplates/plugin-psr4/src/Frontend/Assets.phptemplates/plugin-psr4/src/PostTypes/Book.phptemplates/plugin-psr4/src/Taxonomies/Genre.php詳細
WordPress プラグイン開発(コア)
ステータス:本番環境対応 最終更新日:2026-08-03 依存関係:なし(WordPress 6.0+、PHP 8.0+) 最新バージョン:WordPress 7.0+、PHP 8.3+ を推奨
クイックスタート(10 分)
1. プラグイン構造を選ぶ
3 種類のアーキテクチャパターンを利用できます(詳しい例は references/plugin-architectures.md を参照してください)。
- シンプル(関数のみ)- 関数が 5 個未満の小規模なプラグイン
- OOP - 関連する機能を持つ中規模のプラグイン
- PSR-4(名前空間 + Composer)- 現代の標準(2025)、最も保守しやすい方式
2. プラグインヘッダーを作成する
すべてのプラグインには、メインファイルにヘッダーコメントが必須です。
<?php
/**
* Plugin Name: My Awesome Plugin
* Description: Brief description.
* Version: 1.0.0
* Requires at least: 6.0
* Requires PHP: 8.0
* Text Domain: my-plugin
*/
if ( ! defined( 'ABSPATH' ) ) exit;
重要:プラグイン名は必須です。Text Domain はプラグインのスラッグと完全に一致させてください。
3. セキュリティの基盤(5 つの必須項目)
// 1. Unique Prefix (4-5 chars)
function mypl_init() { /* code */ }
add_action( 'init', 'mypl_init' );
// 2. ABSPATH Check (every file)
if ( ! defined( 'ABSPATH' ) ) exit;
// 3. Nonces for Forms
wp_nonce_field( 'mypl_action', 'mypl_nonce' );
// 4. Sanitize Input, Escape Output
$clean = sanitize_text_field( $_POST['input'] );
echo esc_html( $output );
// 5. Prepared Statements
$wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}table WHERE id = %d", $id ) );
セキュリティの基盤となる 5 つのステップ
ステップ 1:すべてに一意のプレフィックスを使う
ルール:最低 4~5 文字とし、関数、クラス、定数、オプション、トランジェント、メタキーに適用します。wp_、__、_ は避けてください。
// GOOD
function mypl_init() {}
class MyPL_Settings {}
add_option( 'mypl_option', 'value' );
// BAD - Will conflict
function init() {}
class Settings {}
ステップ 2:管理者かどうかではなく、権限を確認する
// WRONG
if ( is_admin() ) { /* SECURITY HOLE */ }
// CORRECT
if ( current_user_can( 'manage_options' ) ) { /* Secure */ }
一般的な権限:manage_options(管理者)、edit_posts(編集者)、publish_posts(投稿者)
ステップ 3:セキュリティの三原則
入力 → 処理 → 出力(サニタイズ → 検証 → エスケープ):
// SANITIZATION (Input)
$name = sanitize_text_field( $_POST['name'] );
$email = sanitize_email( $_POST['email'] );
$url = esc_url_raw( $_POST['url'] );
$html = wp_kses_post( $_POST['content'] );
// VALIDATION (Logic)
if ( ! is_email( $email ) ) wp_die( 'Invalid email' );
// ESCAPING (Output)
echo esc_html( $name );
echo '<a href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';
ルール:入力をサニタイズし、出力をエスケープします。ユーザーデータを決して信用しないでください。
ステップ 4:ノンス(CSRF 対策)
リクエストがサイトから送信されたことを証明するワンタイムトークンです。
// Form
<form method="post">
<?php wp_nonce_field( 'mypl_action', 'mypl_nonce' ); ?>
<input type="text" name="data" />
</form>
// Verify
if ( ! wp_verify_nonce( $_POST['mypl_nonce'], 'mypl_action' ) ) wp_die( 'Security check failed' );
// AJAX
check_ajax_referer( 'mypl-ajax-nonce', 'nonce' );
ステップ 5:データベースにはプリペアドステートメントを使う
重要:ユーザー入力には必ず $wpdb->prepare() を使ってください。
// WRONG - SQL Injection
$wpdb->get_results( "SELECT * FROM {$wpdb->prefix}table WHERE id = {$_GET['id']}" );
// CORRECT
$wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}table WHERE id = %d", $_GET['id'] ) );
プレースホルダー:%s(文字列)、%d(整数)、%f(浮動小数点数)
LIKE クエリ:ワイルドカードを追加する前に $wpdb->esc_like() を使います。
$search = '%' . $wpdb->esc_like( $term ) . '%';
$wpdb->get_results( $wpdb->prepare( "... WHERE title LIKE %s", $search ) );
重要なルール
必ず行うこと
✅ 一意のプレフィックスを使う(4~5 文字)。すべてのグローバルコード(関数、クラス、オプション、トランジェント)に適用します
✅ すべての PHP ファイルに ABSPATH チェックを追加する:if ( ! defined( 'ABSPATH' ) ) exit;
✅ is_admin() だけでなく、権限を確認する(current_user_can())
✅ すべてのフォームと AJAX リクエストでノンスを検証する
✅ ユーザー入力を含むすべてのデータベースクエリで $wpdb->prepare() を使う
✅ 保存前に sanitize_*() 関数で入力をサニタイズする
✅ 表示前に esc_*() 関数で出力をエスケープする
✅ カスタム投稿タイプを登録する際は、有効化時にリライトルールをフラッシュする
✅ 恒久的なクリーンアップには uninstall.php を使う(無効化フックではなく)
✅ WordPress Coding Standards に従う(インデントにはタブを使い、Yoda 条件式を使う)
絶対に行わないこと
❌ extract() は絶対に使わない - セキュリティ上の脆弱性を生みます
❌ サニタイズせずに $_POST/$_GET を信用しない
❌ ユーザー入力を SQL に連結しない - 必ず prepare() を使います
❌ 権限の確認に is_admin() だけを使わない
❌ サニタイズされていないデータを出力しない - 必ずエスケープします
❌ 汎用的な関数名やクラス名を使わない - 必ずプレフィックスを付けます
❌ 短縮 PHP タグ <? や <?= を使わない - <?php のみを使います
❌ 無効化時にユーザーデータを削除しない - アンインストール時にのみ削除します
❌ アンインストールフックを繰り返し登録しない - 有効化時に一度だけ登録します
❌ メイン処理で register_uninstall_hook() を使わない - 代わりに uninstall.php を使います
既知の問題の予防
このスキルは、報告されている 20 件の問題を防ぎます。
問題 #1:SQL インジェクション
エラー:エスケープされていないユーザー入力によりデータベースが侵害されます
出典:https://patchstack.com/articles/sql-injection/ (全脆弱性の 15%)
発生原因:ユーザー入力を SQL クエリに直接連結すること
予防策:プレースホルダーを使って、必ず $wpdb->prepare() を使用します
// VULNERABLE
$wpdb->query( "DELETE FROM {$wpdb->prefix}table WHERE id = {$_GET['id']}" );
// SECURE
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}table WHERE id = %d", $_GET['id'] ) );
問題 #2:XSS(クロスサイトスクリプティング)
エラー:悪意のある JavaScript がユーザーのブラウザーで実行されます 出典:https://patchstack.com (全脆弱性の 35%) 発生原因:サニタイズされていないユーザーデータを HTML に出力すること 予防策:コンテキストに適した関数を使って、必ず出力をエスケープします
// VULNERABLE
echo $_POST['name'];
echo '<div class="' . $_POST['class'] . '">';
// SECURE
echo esc_html( $_POST['name'] );
echo '<div class="' . esc_attr( $_POST['class'] ) . '">';
Issue #3: CSRF(クロスサイトリクエストフォージェリ)
エラー:ユーザーに代わって不正な操作が実行されます
出典:https://blog.nintechnet.com/25-wordpress-plugins-vulnerable-to-csrf-attacks/
原因:リクエストがサイトから送信されたことを検証していません
対策:wp_nonce_field() と wp_verify_nonce() を使用してノンスを実装します
// VULNERABLE
if ( $_POST['action'] == 'delete' ) {
delete_user( $_POST['user_id'] );
}
// SECURE
if ( ! wp_verify_nonce( $_POST['nonce'], 'mypl_delete_user' ) ) {
wp_die( 'Security check failed' );
}
delete_user( absint( $_POST['user_id'] ) );
Issue #4: 権限チェックの欠如
エラー:一般ユーザーが管理者向け機能にアクセスできます
出典:WordPress Security Review Guidelines
原因:current_user_can() ではなく is_admin() を使用しています
対策:管理者コンテキストだけでなく、必ず権限を確認してください
// VULNERABLE
if ( is_admin() ) {
// Any logged-in user can trigger this
}
// SECURE
if ( current_user_can( 'manage_options' ) ) {
// Only administrators can trigger this
}
Issue #5: ファイルへの直接アクセス
エラー:WordPress のコンテキスト外で PHP ファイルが実行されます 出典:WordPress Plugin Handbook 原因:ファイルの先頭に ABSPATH チェックがありません 対策:すべての PHP ファイルに ABSPATH チェックを追加します
// Add to top of EVERY PHP file
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
その他の問題(#6-20)
上位 5 件以外のエラーも網羅的に確認するには、以下を含む references/error-catalog.md を読み込んでください:
- 機能:プレフィックスの衝突、リライトルールのフラッシュ漏れ、非推奨関数、テキストドメインの不一致、プラグインの依存関係、自動保存のトリガー
- パフォーマンス:すべてのページでのスクリプト読み込み、トランジェントの未削除、admin-ajax.php のパフォーマンス
- セキュリティ:保存時のサニタイズ漏れ、LIKE クエリの誤り、extract() の使用、REST API の権限コールバックの欠如、アンインストールフックの問題
- データ整合性:無効化時のデータ削除
各問題には、エラーの説明、出典、原因、対策コード、影響の深刻度、発生頻度が含まれています。
プラグインアーキテクチャのパターン
プラグインの規模と複雑さに応じて、適切なアーキテクチャを選択してください。
選択ガイド
シンプル(関数のみ)
- 用途:小規模なプラグイン(関数が 5 個未満)、単一の機能
- 利点:すぐに始められ、ボイラープレートが最小限です
- 欠点:拡張性がなく、関数が約 5 個を超えると整理が難しくなります
- 例:シンプルなショートコードプラグイン、基本的なウィジェット
OOP(シングルトンパターン)
- 用途:中規模のプラグイン(関数が 5~20 個)、関連する機能
- 利点:整理しやすく、カプセル化でき、テスト可能です
- 欠点:シンプルな構成よりボイラープレートが多く、最新の PHP 機能を使用しません
- 例:カスタム投稿タイププラグイン、管理画面の設定ページ
PSR-4(名前空間 + Composer)
- 用途:大規模またはモダンなプラグイン、チーム開発、2025 年以降の標準
- 利点:モダンな PHP、名前空間、オートローディング、ベストプラクティス
- 欠点:Composer が必要で、初期設定に手間がかかります
- 例:eコマース拡張機能、多機能プラグイン
完全な例
ディレクトリ構成、有効化フック、コードパターンを含む実装例の全体については、references/plugin-architectures.md を読み込んでください。
一般的な実装パターン
このスキルでは、WordPress プラグインでよく使われる 8 つの機能について、本番環境ですぐに使えるパターンを提供します。
- カスタム投稿タイプ - Gutenberg 対応の CPT を登録し、リライトルールをフラッシュします
- カスタムタクソノミー - 階層型(カテゴリー)またはフラット型(タグ)のタクソノミー
- メタボックス - 適切なセキュリティ(ノンス、権限、自動保存チェック)を適用してカスタムフィールドを保存します
- Settings API - サニタイズ機能を備えた WordPress 標準の設定ページ
- REST API エンドポイント - 権限コールバックとバリデーションを備えた最新の API エンドポイント
- AJAX ハンドラー - 従来の admin-ajax.php パターン(新規プロジェクトでは REST API を使用してください)
- カスタムデータベーステーブル - dbDelta とバージョン管理を使用してテーブルを作成します
- キャッシュ用トランジェント - コストの高い処理をキャッシュし、更新時にクリアします
実装コード全体については、これらの機能を実装する際に references/common-patterns.md を読み込んでください。各パターンには以下が含まれています。
- 動作する完全なコード例
- セキュリティ要件のチェックリスト
- 避けるべきよくある間違い
- ベストプラクティスとパフォーマンスのヒント
配布と自動更新
WordPress.org 以外でホストされているプラグインでは、YahnisElsts の Plugin Update Checker(推奨)を使用して自動更新を提供できます。
簡単な解決策:
- 公開リポジトリ:Plugin Update Checker(GitHub/GitLab/BitBucket)
- 非公開プラグイン:Plugin Update Checker + 認証トークン
- 商用プラグイン:Freemius またはカスタム更新サーバー
- コーディング不要:Git Updater プラグイン
完全な実装については、次の内容を含む references/github-auto-updates.md を読み込んでください。
- Plugin Update Checker のセットアップ(5 分)
- GitHub Releases のワークフロー
- 非公開リポジトリの認証
- セキュリティのベストプラクティス(チェックサム、トークン、レート制限)
- 代替ソリューションの比較
- ZIP 構造の要件
依存関係
必須:
- WordPress 6.0 以降(7.0 以降を推奨)
- PHP 8.0 以降(8.3 以降を推奨)
任意:
- Composer 2.0 以降 - PSR-4 オートローディング用
- WP-CLI 2.0 以降 - コマンドラインでのプラグイン管理用
- Query Monitor - デバッグとパフォーマンス分析用
公式ドキュメント
- WordPress プラグインハンドブック:https://developer.wordpress.org/plugins/
- WordPress コーディング規約:https://developer.wordpress.org/coding-standards/
- WordPress REST API:https://developer.wordpress.org/rest-api/
- WordPress データベースクラス($wpdb):https://developer.wordpress.org/reference/classes/wpdb/
- WordPress セキュリティ:https://developer.wordpress.org/apis/security/
- Settings API:https://developer.wordpress.org/plugins/settings/settings-api/
- カスタム投稿タイプ:https://developer.wordpress.org/plugins/post-types/
- Transients API:https://developer.wordpress.org/apis/transients/
- Context7 ライブラリ ID:/websites/developer_wordpress
トラブルシューティング
致命的なエラー:WP_DEBUG を有効にし、wp-content/debug.log を確認して、プレフィックス付きの名前を使用していることを確認してください。
CPT の 404 エラー:rewrite ルールをフラッシュしてください(wp-admin に一時的に flush_rewrite_rules(); を追加します)。
Nonce の失敗:名前が一致していること、正しいアクションであること、有効期限が 24 時間であることを確認してください。
AJAX が 0/-1 を返す:アクション名が wp_ajax_{action} と一致していること、nonce が送信・検証されていること、ハンドラーがフックされていることを確認してください。
HTML が削除される:sanitize_text_field() の代わりに wp_kses_post() を使用してください。
DB クエリの失敗:必ず $wpdb->prepare() を使用し、$wpdb->prefix を含め、構文を確認してください。
リファレンスを読み込むタイミング
このスキルでは段階的開示を採用しています。メインファイルには必須事項が含まれ、リファレンスファイルには詳細な実装方法が記載されています。現在の作業に応じてリファレンスを読み込んでください。
references/common-patterns.md(465 行)
読み込むタイミング:特定の WordPress 機能を実装するとき
内容:
- カスタム投稿タイプ(登録、Gutenberg サポート、rewrite ルール)
- カスタムタクソノミー(階層型とフラット型、REST API)
- メタボックス(セキュリティ要件、保存フック、自動保存のチェック)
- Settings API(register_setting、セクション、フィールドの階層)
- REST API エンドポイント(権限コールバック、検証、レスポンス)
- AJAX ハンドラー(nonce の検証、wp_ajax フック、JavaScript 連携)
- カスタムデータベーステーブル(dbDelta、文字エンコーディング、バージョン管理)
- キャッシュ用 Transients(キャッシュパターン、無効化、有効期限)
references/plugin-architectures.md(220 行)
読み込むタイミング:プラグインの構造を選択するとき、またはパターン間で移行するとき
内容:
- シンプルパターン(関数のみ、5 関数未満)
- OOP パターン(シングルトン、カプセル化、中規模プラグイン)
- PSR-4 パターン(名前空間、Composer オートローディング、現代的な標準)
- パターン選択のための決定木
- すべてのファイルを含む完全なディレクトリ構造
- 有効化/無効化フックの例
- パターン間の移行方法
references/error-catalog.md(Issue #6-20、573 行)
読み込むタイミング:上位 5 件のセキュリティ脆弱性以外の問題をデバッグするとき 内容:
- 機能に関する問題(プレフィックスの衝突、書き換えルール、非推奨関数、テキストドメイン、依存関係、自動保存)
- パフォーマンスに関する問題(スクリプトの全ページ読み込み、一時データのクリーンアップ、admin-ajax.php の代替手段)
- セキュリティに関する問題(サニタイズ、extract()、REST の権限、アンインストールフック)
- データ整合性に関する問題(無効化とアンインストールの違い) 各問題に含まれる内容:エラーの説明、ソース/参考資料、発生する理由、防止用コード、影響の深刻度、発生頻度
references/advanced-topics.md(150 行)
読み込むタイミング:i18n、WP-CLI、cron ジョブ、依存関係チェックを実装するとき 内容:
- 国際化(i18n)- load_plugin_textdomain()、翻訳ワークフロー、.pot/.po/.mo ファイル
- WP-CLI コマンド - カスタムコマンドの作成、プログレスバー、出力関数
- スケジュールイベント(Cron)- wp_schedule_event()、カスタムスケジュール、有効化フック
- プラグインの依存関係チェック - バージョン要件、ソフト依存関係、ユーザーフレンドリーなエラーメッセージ
references/security-checklist.md(527 行)
読み込むタイミング:セキュリティ監査を実施するとき、または脆弱性がないかコードをレビューするとき 内容:
- セキュリティ監査チェックリスト一式
- WordPress 向け OWASP Top 10
- 各種脆弱性のコード例
- テスト手順とツール
- セキュリティプラグインの推奨
references/github-auto-updates.md(1,224 行)
読み込むタイミング:WordPress.org 以外でホストされているプラグインの自動更新を設定するとき 内容:
- Plugin Update Checker(推奨)- 5 分で設定
- GitHub Releases のワークフローと自動化
- プライベートリポジトリの認証(トークン、wp-config.php)
- 代替ソリューション(Git Updater、Custom Server、Freemius)
- セキュリティのベストプラクティス(チェックサム、署名、レート制限)
- ZIP の構造要件とよくある間違い
- デプロイ自動化の例
references/common-hooks.md(234 行)
読み込むタイミング:WordPress のフックを扱い、フックのリファレンスが必要なとき 内容:
- アクションフックのリファレンス(init、admin_menu、save_post など)
- フィルターフックのリファレンス(the_content、post_type_args など)
- フックの優先度と実行順序
- よく使われるフックの組み合わせとパターン
セットアップ完全チェックリスト
このチェックリストを使って、プラグインを確認してください。
- すべてのフィールドを含むプラグインヘッダー
- すべての PHP ファイルの先頭に ABSPATH チェックがある
- すべての関数/クラスで一意のプレフィックスを使用している
- すべてのフォームで nonce 検証を行っている
- すべてのユーザー入力をサニタイズしている
- すべての出力をエスケープしている
- すべてのデータベースクエリで $wpdb->prepare() を使用している
- 権限チェックを行っている(is_admin() だけではない)
- カスタム投稿タイプで有効化時に書き換えルールをフラッシュしている
- 無効化フックで一時データのみを消去している
- uninstall.php で永続データのクリーンアップを処理している
- テキストドメインがプラグインのスラッグと一致している
- 必要な場所でのみスクリプト/スタイルを読み込んでいる
- 開発中に WP_DEBUG を有効にしている
- Query Monitor でパフォーマンスをテストしている
- 非推奨関数の警告がない
- 最新の WordPress バージョンで動作する
質問や問題がありますか?
- 追加の問題 #6-20 については
references/error-catalog.mdを確認してください - セキュリティ基盤のすべての手順を確認してください
- 公式ドキュメントを確認してください:https://developer.wordpress.org/plugins/
- WP_DEBUG を有効にして debug.log を確認してください
- Query Monitor プラグインを使ってフックとクエリをデバッグしてください