- 特徴
- <?= ?>
- 変数
- WP グローバル変数
- スーパーグローバル変数
- $_SERVER
- ファイル関連
- ショートコードの作り方
- コメントアウト
- 配列
- 連想配列の書き方
- 演算子
- if文の書き方
- 繰り返し処理
- 関数の書き方
- デフォルト関数(getが付く物はHTML内で使う時はechoを頭につける)
- API関連でよく使う関数
- クラス
- コロン構文
- サブクエリ(任意のページのデータをDBから取得する)
- アクションフック
- add_action() 主要な第一引数の一覧
- add_filter()
- xmlを扱う
- 完全ランダム
- 自動処理関連(wpの擬似Cron)
- X-Content-Type-Options: nosniff X-Frame-Options / CSP
- setcookie()
- APIをプラグイン間で跨いで使用する時相手側のJSを読まないようにする
- is_singular()
- 仮想環境と本番環境でコードを切り換える
- テーマ(スタイル)回避
- ハッシュ処理
- その他
特徴
- HTMLがPHPファイル内で書ける
- <?php 処理 ?>これだけでコードが走る
- <?php 〜処理 ?>はファイル内で何回も書ける、HTMLの途中で一行だけ書いてそれを複数書くとかもできる
- 終わりの ?> の部分は省略できる
- エントリーポイントがわかりにくい(PHPを扱う環境によって調べ方があるようだ。)
- 動的型付け言語なので、変数の型を自由に変更できる
|
1 2 3 4 5 6 7 8 9 10 |
$a = []; function test(){ $c = ['1' => 'a', '2' => 'b']; return $c; } $a = test(); print_r($a); //正常終了 |
<?= ?>
<?= ?>は値をHTMLに出力する専用タグ(<?php echo ... ?>の短縮形)です。<?=は主にテンプレート表示で便利ですが、基本は<?phpを使い、HTML埋め込み時には<?=を使うのが一般的です。
変数
- 頭に【$】をつける。
- 変数の型は推論型で型指定不要。
- 予約語が使えるが非推奨。
- floatはdoubleで返される。正確な型を知るには【var_dump(変数)】を使用する。
- ブール型は true で 1 だが false は何も入らない。
- 文字、文字列を扱う時はシングルコーテーションを使う。HTMLは普通にダブルコーテーション。
- スコープ特殊で関数外変数は関数内と同じ変数名を使用しても別扱いとなる。関数外の変数を扱う場合 $変数 の前に global を付けて宣言し直す。例 global $変数;
WP グローバル変数
$post
WordPressの$postは、現在表示中の投稿や固定ページのデータを格納するグローバル変数(WP_Postオブジェクト)です。ID、タイトル、内容、投稿日時などの情報にアクセスでき、ループ内では自動的に更新されます。ループ外で使う場合はglobal $post;と宣言が必要です。
|
1 2 3 4 5 6 7 8 9 |
<?php global $post; // ループ外で使う場合必須 echo $post->ID; // 投稿IDを取得 echo $post->post_title; // 投稿タイトルを取得 echo $post->post_content; // 投稿内容を取得 echo $post->post_author; // 投稿者IDを取得 echo $post->post_date; // 投稿日時を取得 ?> |
スーパーグローバル変数
元々PHPで定義されている変数のこと、$GLOBALS以外は $_ から始まる。
PHP内のどこからでも呼べる
- $GLOBALS
- $_SERVER[]
- $_GET[‘キー’]
- $_POST[‘キー’]
- $_FILES[‘キー’]
- $_COOKIE[‘キー’]
- $_SESSION[‘キー’]
- $_ENV[‘キー’]
- $_REQUEST[‘キー’]
$_SERVER
主な引用元https://qiita.com/With21/items/1c0520921d8729813473
- $_SERVER[‘PHP_SELF’]
- $_SERVER[‘GATEWAY_INTERFACE’]
- $_SERVER[‘SERVER_ADDR’]
- $_SERVER[‘SERVER_NAME’]
- $_SERVER[‘SERVER_NAME’]
- $_SERVER[‘SERVER_PROTOCOL’]
- $_SERVER[‘REQUEST_METHOD’]
- $_SERVER[‘REQUEST_TIME’]
- $_SERVER[‘REQUEST_TIME_FLOAT’]
- $_SERVER[‘QUERY_STRING’]
- $_SERVER[‘DOCUMENT_ROOT’]
- $_SERVER[‘HTTPS’]
- $_SERVER[‘HTTP_ACCEPT’]
- $_SERVER[‘HTTP_ACCEPT_CHARSET’]
- $_SERVER[‘HTTP_ACCEPT_ENCODING’]
- $_SERVER[‘HTTP_ACCEPT_LANGUAGE’]
- $_SERVER[‘HTTP_CONNECTION’]
- $_SERVER[‘HTTP_HOST’]
- $_SERVER[‘HTTP_REFERER’]
- $_SERVER[‘HTTP_USER_AGENT’]
- $_SERVER[‘REMOTE_ADDR’]
- $_SERVER[‘REMOTE_HOST’]
- $_SERVER[‘REMOTE_PORT’]
- $_SERVER[‘REMOTE_USER’]
- $_SERVER[‘REDIRECT_REMOTE_USER’]
- $_SERVER[‘SCRIPT_FILENAME’]
- $_SERVER[‘SERVER_ADMIN’]
- $_SERVER[‘SERVER_PORT’]
- $_SERVER[‘SERVER_SIGNATURE’]
- $_SERVER[‘PATH_TRANSLATED’]
- $_SERVER[‘SCRIPT_NAME’]
- $_SERVER[‘REQUEST_URI’]
- $_SERVER[‘PHP_AUTH_DIGEST’]
- $_SERVER[‘PHP_AUTH_USER’]
- $_SERVER[‘PHP_AUTH_PW’]
- $_SERVER[‘AUTH_TYPE’]
- $_SERVER[‘PATH_INFO’]
- $_SERVER[‘ORIG_PATH_INFO’]
ファイル関連
- ABSPATH
- __DIR__
- require_once
- wp_enqueue_script()
- wp_enqueue_style()
- plugin_dir_url()
|
1 2 3 4 5 6 7 8 |
// プラグインのディレクトリURLを取得 $plugin_url = plugin_dir_url( __FILE__ ); // CSSファイルを読み込む例 wp_enqueue_style( 'my-styles'$plugin_url . 'css/style.css' ); // 画像を表示する例 echo '<img src="' . $plugin_url . 'images/logo.png" />'; |
- plugin_dir_path()
|
1 2 |
// 自身のプラグインフォルダ内にある includes/functions.php を読み込む require_once plugin_dir_path( __FILE__ ) . 'includes/functions.php'; |
違い
| 関数名 | 返り値のタイプ | 主な用途 | 例 |
|---|---|---|---|
plugin_dir_url() | WebのURL | CSS, JS画像の読み込み | https://example.com/wp-content/plugins/my-plugin/ |
plugin_dir_path() | サーバーの絶対パス | PHPファイルの読み込み | /var/www/wp-content/plugins/my-plugin/ |
- plugins_url()
基本的な使い方
プラグインのメインファイル内で、自身のフォルダ内にあるファイルを指定する場合は以下のように記述します。
|
1 2 |
// 例: プラグイン内の 'js/script.js' へのURLを取得 $url = plugins_url( 'js/script.js', __FILE__ ); |
- 第1引数:取得したいファイルへの相対パス
- 第2引数:基準となる現在のファイルパス(通常
__FILE__)を指定すると、そのファイルがある場所を基準にURLを解決します
一つ上のフォルダのファイルを指定するとき
- 一つ上のフォルダ(親ディレクトリ)にあるPHPファイルを指定するには、PHPの
dirname()関数を組み合わせて使用します plugin_dir_path()は末尾にスラッシュを含んだパスを返すため、それをdirname()で囲むことで一段階上の階層を取得できます。
具体的なコード例
現在のファイルが plugins/my-plugin/includes/sub.php にあり、一つ上の plugins/my-plugin/main.php を読み込みたい場合は以下のように書きます。
|
1 2 |
// 一つ上のディレクトリのパスを取得してファイルを指定 require_once dirname( plugin_dir_path( __FILE__ ) ) . '/main.php'; |
ポイント
dirname()の役割: 指定したパスの「親ディレクトリ」のパスを返します。- スラッシュの補完:
dirname()を通すと末尾のスラッシュが消えるため、ファイル名の前に'/'を忘れないようにしてください。 - さらに上の階層: 2つ上の階層を指定したい場合は、
dirname( dirname( ... ) )と二重にするか、PHP 7以降であればdirname( パス, 2 )と階層数を指定することも可能です。
ショートコードの作り方
WordPressでPHPショートコードを作成するには、テーマ(通常は子テーマ)のfunctions.phpファイルにadd_shortcode()関数を用いてコードを記述します。これにより、[ショートコード名]という記述を、PHPで定義したHTMLや定型文に置き換えて表示できます。
ショートコード作成の3ステップ
- 子テーマの
functions.phpを開く
必ず「外観」>「テーマファイルエディタ」などで、使用しているテーマのバックアップを取った上で編集してください。 - PHPコードを追加する
functions.phpの末尾に以下の形式でコードを記述します。
|
1 2 3 4 5 6 7 |
// 1. 関数定義:ショートコードが読み込まれた時に何を表示するか function my_shortcode_func() { return '<p>追加したいコンテンツやHTML</p>'; } // 2. ショートコード登録:[my-shortcode] と記述した場合に関数を呼び出す add_shortcode('my-shortcode', 'my_shortcode_func'); |
投稿・固定ページで呼び出す
エディタ(ブロックエディタ)で [my-shortcode] と入力すると、その場所にHTMLが表示されます。
主な作成パターン
- 自己完結型 (例:
[my-shortcode])
上記の手順で作成可能です。定型文の挿入に適しています。 - 囲み型 (例:
[my-box]コンテンツ[/my-box])$content引数を使用して、挟まれたテキストを処理できます。
|
1 2 3 4 |
function my_box_func($atts, $content = null) { return '<div class="my-box">' . $content . '</div>'; } add_shortcode('my-box', 'my_box_func'); |
注意点・ヒント
- バックアップ:
functions.phpを編集する際は、必ず事前にバックアップを取り、エラーによるサイト表示崩れに備えてください。 - エラー対策:
echoではなくreturnを使用して内容を返してください。 - 利用プラグイン: PHPコードの編集が難しい場合、「Post Snippets」などのプラグインを使用する方法もあります。
コメントアウト
C言語と同じ。
// 一行
/**/ 範囲
配列
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php $aaa = array(2); $aaa[0] = 1; $aaa[1] = 2; $bbb = array('ああ', 'いい'); $ccc = ['ああ', 'いい'] //多次元 $ddd = [ ['ああ', 'いい'],['うう', 'ええ'] ]; echo ($ddd[1][0]); //結果 //うう |
連想配列の書き方
通常の配列の宣言に => を使うと左がキー、右が値の連想配列ができる。
PHPの配列は配列の中に配列を入れられるので連想配列を連結することができます。
主にJSON形式にする場合に使用する
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?php $a = array('aaa' => '1', 'bbb' => '2'); $b = [ 1 => 'a', 2 => 'b' ] $aa = [ [ 'title' => 'タイトル1', 'reportDateTime' => '2025-09-07', 'weather' => '晴れ' ], [ 'title' => 'タイトル2', 'reportDateTime' => '2025-09-08', 'weather' => '曇り' ] ]; //キー毎にまとめる $bb = [ 'forecast1' => [ 'title' => 'タイトル1', 'reportDateTime' => '2025-09-07', 'weather' => '晴れ' ], 'forecast2' => [ 'title' => 'タイトル2', 'reportDateTime' => '2025-09-08', 'weather' => '曇り' ] ]; //アクセス方法 echo $a['aaa']; //出力 1 echo $b[1]; //出力 a echo $aa[1]['title']; //出力 タイトル2 echo $bb['forecast1']['reportDateTime']; //出力 2025-09-07 //要素の追加 $a['追加キー'] = '追加する値'; //要素の削除 unset($a['削除したいキー']); //要素の連結 $c = array_merge($a, $b); |
演算子
演算子はC言語とほぼ同じ。
イコール3つ === は厳密等価演算子と呼ばれ、値と型の両方が一致しているかを比較する
if文の書き方
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php $a = 1; if($a == 1){ echo ('あ'); }else if ($a == 2){ echo ('い'); }else{ echo ('う'); } ?> //結果 //あ |
繰り返し処理
foreachはC言語とかと変数の配置が逆かつ as を表記
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php //for(スタート値; 継続条件; 増減){} for($i = 0; $i <= 3; $i++){ echo $i.'\n' //'\n'は改行'<br>'でも可 } ?> //break continue は使用可能 //結果 //1 //2 //3 //while <?php $i = 0; while($i < 3){ echo $i.','; $i++; } ?> //結果 //0,1,2 //foreach <?php foreach($配列とか as $取り出されて入る変数){ 処理 } ?> |
関数の書き方
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php function aaa($a){ echo $a.'\n'; return $a++; } $b = aaa(1); //変数に代入が可能 $c = function($d){ echo $d; }; //セミコロン必須 $c($b); //結果 //1 //2 |
デフォルト関数(getが付く物はHTML内で使う時はechoを頭につける)
| echo | 値を出力できる |
| var_dump() | ・echoでは出力されない詳細なデータを出力できる ・型 + 値で出力される ・オブジェクトのプロパティや要素の詳細まで見れる |
| print_r() | var_dump()を見やすくした形式で表示 |
| echo_count() | 配列の要素数を出力 |
| var_export() | PHP形式のコードとして出力 |
| get_theme_file_url(‘テーマディレクトリからのパス’) | ・テーマディレクトリまでのパスを取得する。 ・HTMLで使うならechoを頭につけて使う。(取得するだけでhtmlのhref=””等の中に文字列として表示されないから) ・テーマ以下のファイルを読み込むときに便利 |
| home_url(‘必要なファイルのパス’) | ・WordPressのトップのURLまでのパスを取得する。 ・HTMLで使うならechoを頭につけて使う。(取得するだけでhtmlのhref=””等の中に文字列として表示されないから) |
| get_header() & get_footer | ・header.php footer.php をインクルード出来る ・header.phpの<head></head>内に<?php wp_head(); ?>必須 ・footer.phpの</body>の直上に<php? wp_footer(); ?>必須 ・header.phpの<body>の直下に<?php wp_body_open(); ?>必須 |
| have_posts() | 投稿(記事)存在判定 |
| has_shortcode() | 投稿や固定ページなどのコンテンツ内に、特定のショートコードが含まれているかどうか |
| the_posts() | ・投稿リストから最新の投稿を取り出して取り出した投稿を消す ・恐らくオブジェクトで取得して一件ずつ吐き出す感じ ・これの下で投稿の何を表示するかとかの処理をするのが一般的 |
| the_title() | タイトルの取得、表示 |
| the_date() | ・日付の取得、表示 ・引数で表示形式を変えれる(‘Y.m.d’で2025.9.10) ・同じ日付がある場合2回目以降は出力しない ・常に出力する場合はget_the_dateにする ・HTMLで表示させるにはechoを頭につける |
| the_content() | 記事の内容を取得、表示 |
| the_permalink() | URLの取得、表示 |
| get_sideber() | サイドバーの取得 |
| is_admin() | ・現在のリクエストが管理画面ページであるかどうか ・現在のユーザーが管理者権限を持つかどうかを判定するものではなく、管理画面が表示されている状態かどうかを確認する目的で使用される |
| is_main_query() | ・メインクエリかどうか ・クラスのメソッド |
| is_front_page() | ・front.php存在確認 ・frontはサイト全体のトップページを自由にカスタマイズするためのテンプレート(最優先にロードされる) |
| is_home() | ・home.php存在確認 ・homeはブログの投稿一覧ページ(投稿インデックス)をカスタマイズするためのテンプレート(最新の投稿一覧) |
| is_single() | 投稿記事存在確認 |
| is_singulare() | ・引数に投稿タイプを入れてそれの存在確認をする ・カスタム投稿タイプを使用しているときに使える |
| the_posts_pagination() | ページタブの表示 |
| add_action() | ・アクションフック、第一引数にフックする関数(アクション) ・第二引数に追加する関数名(自分で作った関数) |
| add_filter() | ・フィルターフック、第一引数にフックする関数(アクション) ・第二引数に追加する関数名(自分で作った関数) ・アクションとはフックする関数が呼ばれるタイミングと内容で使い分ける |
API関連でよく使う関数
- register_rest_route()
- register_rest_field()
- wp_send_json()
wp_remote_get()/wp_remote_post()- rest_ensure_response()
- is_user_logged_in()
- current_user_can()
クラス
変数や関数にアクセスするには -> を使う、その時変数の$が取れる。
public protected private 使用可能。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php class Aaa { //PHPではクラスの頭文字を大文字にするのが慣習 public $a; public function __construct(){ //コンストラクタ、アンダーバー2つ echo 'hello'.'\n'; $this->a = 0; //$取れる } function aaa(){ echo 'あ' } } $b = new Aaa(); //インスタンス化 $b->a = 1; //$取れる $b->aaa(); echo $b->a.'\n'; //結果 //hello //あ //1 //未定義の変数は使用してもエラーが出ない、そして何も代入されない |
コロン構文
{}を使わない書き方 : と end~ に置き換える書き方。
これを使うと処理をまとめて書ける。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php for(): //処理 endfor; while(): //処理 endwhile; foreach(): //処理 endforeach; ?> //複数処理をまとめて書く <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> //表示処理 <?php endwhile; endif; ?> |
サブクエリ(任意のページのデータをDBから取得する)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php $a = [ //クエリする条件を連想配列にする 'post_type' => 'post', //記事の種類 通常の記事(カスタムではない) 'posts_per_page' => 5 //ページ数 ]; $b = new WP_Query($a); //引数の条件のデータを取得するクラスをインスタンス化 ?> <?php //通常のデータ表示処理にインスタンス化した変数を追加 if ($b->have_posts()){ while ($b->have_posts()){ $b->the_post(); //表示灯の処理 } } wp_reset_postdate(); //メモリの解放(the_post()の)、必須 ?> |
アクションフック
特定の関数に処理を追加、または変更することができる
例:メインクエリで取ってくる最新の投稿10件分を特定の投稿タイプの時だけ9件に変更する
※functions_php に書く
API作成例
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php function change_set_post($query){ if(is_admin() || !$query->is_main_query()) { return; } if(&query->is_post_type_archive('works')) { //worksタイプの投稿なら $query->set('posts_per_page', 9); //取ってくる最新の投稿記事数を9件に return; } } add_action('pre_get_posts', 'change_set_post'); //フック関数、第一引数にフックする関数第二引数に自作関数 //pre_get_postsはメインクエリが実行される直前の関数 |
register_activation_hook(__FILE__, '反映したい関数名') | プラグインが管理画面で「有効化」された瞬間に、指定したPHP関数(初期化処理)を一度だけ実行するためのフックです。 |
add_action() 主要な第一引数の一覧
サイトの読み込み・初期化関連
init | WordPress本体の読み込みが完了した直後に実行。テーマやプラグインの初期設定で最も使われる。 |
after_setup_theme | テーマのfunctions.phpが読み込まれた直後に実行。テーマサポートの設定に最適。 |
wp_loaded | WordPressが完全に読み込まれた後に実行。 |
管理画面関連 (Administration)
admin_menu | 管理画面のメニューに項目を追加する時。 |
admin_init | 管理画面の各ページが表示される前に実行。 |
admin_enqueue_scripts | 管理画面のCSS/JSを読み込む時。 |
フロントエンド(テーマ)関連
wp_enqueue_scripts | テーマのフロントエンドでCSSやJSを読み込む(wp_enqueue_script)時に使用。 |
wp_head | <head> タグの閉じる直前(wp_head()関数内)にコードを追加。 |
wp_footer | </body> タグの直前(wp_footer()関数内)にコードを追加。 |
get_sidebar | サイドバーを表示する前に実行。 |
コンテンツ・投稿関連
wp_insert_post | 投稿がデータベースに追加・更新された直後に実行。 |
publish_post | 投稿が公開された時。 |
save_post | 投稿が保存(新規・更新)された時に実行。 |
delete_post | 投稿が削除された時に実行。 |
コメント関連
comment_post | コメントが投稿された直後に実行。 |
wp_set_comment_status | コメントのステータス(承認/スパムなど)が変更された時。 |
ユーザー関連
wp_login | ユーザーがログインした時に実行。 |
wp_logout | ユーザーがログアウトした時に実行。 |
user_register | 新しいユーザーが登録された時に実行。 |
add_action の基本構成
|
1 |
add_action( '第一引数:アクションフック名', 'コールバック関数名', 優先順位, 受け取る引数の数 ); |
第一引数は上記の通り、do_action('タグ名')で定義されたフック名です。
add_filter()
add_filter() は、特定のデータを表示したりデータベースに保存したりする直前に、その中身を書き換える(加工する)ための関数です。
主な効果と役割
- データの加工・変更: 記事のタイトルや本文などの文字列を受け取り、一部を置換したり、末尾に文字を追加したりして「変更したデータ」を返します。
- 設定のカスタマイズ: プラグインやテーマのデフォルト設定(配列データなど)を、自身の環境に合わせて書き換えられます。
- 安全なカスタマイズ: WordPress本体やテーマのファイルを直接編集せず、
functions.phpから処理を上書きできるため、アップデート時に変更が消えるのを防げます。
add_action() との違い
混同されやすいですが、目的が異なります。
add_filter(): 「データ」を加工して返す(例:本文を書き換える)。add_action(): 特定のタイミングで「動作」を実行する(例:メールを送る、スクリプトを読み込む)。
基本的な書き方
|
1 |
add_filter( 'フック名', '実行する関数名', [優先順位], [引数の数] ); |
第3引数で実行順を指定でき、数値が小さいほど早く実行されます。
例:
|
1 2 3 4 5 6 7 |
add_filter("cron_schedules", function ($schedules) { $schedules["minutely"] = [ "interval" => 60, "display" => "Every Minute" ]; return $schedules; }); |
コードの全体像
WordPressにはデフォルトで「1時間ごと(hourly)」「1日2回(twicedaily)」「1日1回(daily)」といったスケジュールがありますが、「1分ごと」は標準では存在しません。
このコードは、その選択肢をシステムに追加(フィルター)しています。
詳細解説
1. add_filter("cron_schedules", ...)
cron_schedulesは、WordPressが持っているスケジュールのリスト(配列)を管理しているフィルターフックです。- ここに自作の関数をフックさせることで、既存のリストに新しい項目を混ぜることができます。
2. function ($schedules) { ... }
- 引数の
$schedulesには、現在登録されているすべてのスケジュール(配列)が入っています。 - この関数の中で、その配列に新しいデータを書き加えます。
3. 配列への追加内容
|
1 2 3 4 |
$schedules["minutely"] = [ "interval" => 60, // 実行間隔(秒単位) "display" => "Every Minute" // 管理画面などで表示される名前 ]; |
"minutely": このスケジュールのID(名前)です。後で予約設定をする際にこの名前を使います。"interval" => 60: ここが最も重要です。 単位は「秒」なので、60を指定することで「1分間隔」と定義しています。"display": 人間が見てわかりやすい名前です。
4. return $schedules;
- フィルターの絶対ルールです。加工した配列を
returnで返さないと、WordPress内のスケジュール設定が空っぽになってしまい、エラーの原因になります。
xmlを扱う
準備として
file_get_contents()でxmlファイルを読み込み、
simplexml_load_string()でオブジェクト化する。
simplexml_load_file(‘ファイルパス’)でもok、これなら一行。
出来たオブジェクトからアロー演算子でアクセスする。
|
1 2 3 4 5 6 7 8 9 |
//xml中身 <Body>あああ</Body> <?php $a = simplexml_load_file('~~.xml'); echo $a->Body; //結果 //あああ |
xpathが使用可能
要素にアクセスする場合に xpath で指定することができ、直接アクセス可能。
ただし xml に名前空間(xmlns属性)がある場合、SimpleXMLElementのxpathはそのままでは要素を見つけられません。
xmlns= “~~” がある場合は registerXPathNamespace(‘変数’, ‘~~’) を使用してからパスの前に : を使って記述する。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php //xml中身 <Control><Body>あああ</Body></Control> <?php $a = simplexml_load_file('~~.xml'); echo $a->xpath('//Body')."\n"; //xml中身 <Report xmlns="~~/" xmlns:jmx="~~" xmlns:jmx_add="~~"> // <Control><Body>いいい</Body></Control> $b = simplexml_load_file('~~.xml'); $c->registerXPathNamespace('変数', '~~'); // 実際のXMLの名前空間URIに合わせて変更(目的のパスの直上にあるxmlns=" ") echo $c->xpath('//変数:Body'); //結果 //あああ //いいい |
json変換
|
1 2 3 4 5 |
<?php $obj = simplexml_load_file('~~.xml'); $json = json_encode($obj, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); //json形式へ $test = json_decode($json, true); //配列にデコード |
完全ランダム
random_bytes()
random_bytes()を使うと、暗号学的に安全なランダムなバイト列を生成できます。主に、CSRF対策のトークン作成や、強力な一時パスワードの生成などに利用されます。
基本的な使い方
生成されるのはバイナリデータ(人間が読めない形式)のため、通常は bin2hex() などで16進数に変換して使用します。
|
1 2 3 4 5 |
// 16バイトのランダムなデータを生成し、32文字の16進数文字列に変換 $bytes = random_bytes(16); $token = bin2hex($bytes); echo $token; // 例: 385e33f741... |
WordPressでの活用例(CSRF対策など)
WordPressでフォームのセキュリティを強化する際に、独自のトークンを生成する例です。
|
1 2 3 4 5 |
// functions.php 内などで使用 function generate_custom_secure_token() { // 32バイト(64文字分)のセキュアな文字列を生成 return bin2hex(random_bytes(32)); } |
注意点
- PHPバージョン: PHP 7.0以上が必要です。WordPressの推奨環境は現在PHP 7.4以上であるため、最新のWordPress環境であれば問題なく動作します。
- 戻り値: 指定した長さ(バイト数)の文字列が返されますが、そのまま出力すると文字化けのように見えるため、必ず
bin2hex()やbase64_encode()で変換してください。
random_int()
random_int(0, 10) で 0 〜 10 の数値がランダムで返る
自動処理関連(wpの擬似Cron)
WordPressにアクセスされないと役に立たない機能
|
1 2 3 4 5 6 7 |
何かのアクセスが来る ↓ WordPress が起動する ↓ 「期限切れのCronある?」と確認 ↓ あれば実行 |
なのでアクセスが頻繁にある状態でしか期待できない。
一応Bot、クローラー、REST APIでも動く。
作るか????う〜む・・・・・・・・
wp_schedule_event()
特定の処理を定期的に(1時間おき、1日おきなど)自動実行させるための関数です。
主な効果と用途
- タスクの自動化: 「毎日決まった時間にバックアップを取る」「1時間ごとに外部データを取得する」といったバックグラウンド処理が可能になります。
- 擬似 Cron の活用: サーバー側の設定(OSの Cron)を触ることなく、WordPress 内の仕組み(WP-Cron)だけでスケジュール管理が完結します。
- 標準機能の動作: WordPress 本体の「予約投稿」や「プラグイン・テーマの自動更新確認」もこの仕組みで動いています。
注意点
- 実行タイミング: サーバーの Cron とは異なり、「誰かがサイトにアクセスした瞬間」に処理が動きます。アクセスが全くない時間は実行されないため、正確な時刻指定が必要な場合は注意が必要です。
- 重複登録の防止: ページを読み込むたびにこの関数を呼ぶと、同じタスクが大量に登録されてしまいます。必ず
wp_next_scheduled()で既存のスケジュールがないか確認してから実行するのが鉄則です。
1. 基本的なコード例
「1日1回(daily)、特定の関数を実行する」という最も一般的な例です。重複登録を防ぐための wp_next_scheduled() によるチェックが必須となります。
|
1 2 3 4 5 6 7 8 9 10 |
// 1. 実行したい関数を定義 function my_custom_cron_job() { // ここに自動実行したい処理を書く(例:メール送信、データ更新など) } add_action( 'my_daily_event_hook', 'my_custom_cron_job' ); // 2. スケジュールの登録(プラグイン有効化時や特定のアクションで実行) if ( ! wp_next_scheduled( 'my_daily_event_hook' ) ) { wp_schedule_event( time(), 'daily', 'my_daily_event_hook' ); } |
2. カスタムスケジュールの追加方法
WordPress 標準では hourly(毎時)、twicedaily(12時間毎)、daily(毎日)、weekly(毎週)しか用意されていません。それ以外の間隔(例:5分ごと)が必要な場合は、cron_schedules フィルターを使って追加します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 「5分ごと」のスケジュールを新しく定義 add_filter( 'cron_schedules', function ( $schedules ) { $schedules['five_minutes'] = array( 'interval' => 5 * MINUTE_IN_SECONDS, // 300秒 'display' => '5分ごとに実行' ); return $schedules; } ); // 定義した 'five_minutes' を指定して登録 if ( ! wp_next_scheduled( 'my_frequent_event_hook' ) ) { wp_schedule_event( time(), 'five_minutes', 'my_frequent_event_hook' ); } |
3. スケジュールの削除(重要)
不要になったタスクが残り続けるとサイトのパフォーマンスを下げることがあります。プラグインの停止時などには、wp_clear_scheduled_hook() を使って削除するのがマナーです。
|
1 |
wp_clear_scheduled_hook( 'my_daily_event_hook' ); |
最後に、開発時の強力な味方をご紹介しておきます。WP-Cron は目に見えないところで動くため、実際にスケジュールが登録されているか不安になることが多いです。
そんな時は、Advanced Cron Manager や WP Control といったプラグインをインストールしてみてください。管理画面から「次にいつ実行されるか」が一目で確認でき、テスト実行(今すぐ実行)もボタン一つで可能になります。
wp_next_scheduled()
wp_next_scheduled() 関数は、指定した「フック名」に対して次に予定されている実行時刻を取得するためのものです。
主な効果と特徴は以下の通りです。
1. 二重登録の防止(最重要)
最も一般的な使い道は、タスクの重複登録を防ぐことです。WordPressのスケジュール登録関数(wp_schedule_event など)は、呼び出すたびに新しい予定を追加してしまいます。if ( ! wp_next_scheduled( 'my_hook_name' ) ) という条件文で囲むことで、「未登録の場合のみスケジュールする」という制御が可能になります。
2. スケジュール状況の確認
指定したイベントがシステム(WP-Cron)に登録されているかどうかを判定できます。
- 登録されている場合:次の実行予定時刻の タイムスタンプ (整数) を返します。
- 登録されていない場合:
falseを返します。
3. デバッグや表示
「次の自動更新はいつか?」といった情報を管理画面などでユーザーに表示する際に、この関数の戻り値を利用できます。
|
1 2 3 |
if ( ! wp_next_scheduled( 'my_daily_event' ) ) { wp_schedule_event( time(), 'daily', 'my_daily_event' ); } |
流れ:
add_action() で関数にアクションフックとして名前を登録して wp_next_scheduled() で次の動作が登録されていなかったら wp_next_scheduled() で登録する。
なぜ add_action() が必要なのか?
- データ保存の仕組み:
wp_schedule_event()を実行すると、WordPressはデータベース(optionsテーブル)に「〇時〇分に ‘my_task_hook’ というフックを実行する」という名前だけを保存します。PHPの関数オブジェクトやクロージャ(匿名関数)をそのままデータベースに保存して後で復元することはできません。 - 実行時の呼び出し: 予定時刻になり、サイトにアクセスがあると、WordPressは保存された名前(例:
'my_task_hook') を呼び出します(do_action( 'my_task_hook' ))。 - 紐付け: このとき、あなたの書いた関数が実行されるためには、あらかじめ
add_action( 'my_task_hook', '実行したい関数名' )として、「その名前が呼ばれたらこの関数を動かしてね」という紐付けがメモリ上に登録されていなければなりません。
匿名関数(クロージャ)は使えない?
add_action() の第2引数に匿名関数を書くことは可能ですが、wp_schedule_event()自体の引数に直接関数を渡して完結させることは、システムの構造上不可能です。
X-Content-Type-Options: nosniff X-Frame-Options / CSP
|
1 2 3 4 5 |
add_filter("wp_headers", function ($headers) { $headers["X-Content-Type-Options"] = "nosniff"; $headers["X-Frame-Options"] = "SAMEORIGIN"; return $headers; }); |
① X-Content-Type-Options: nosniff
■ これは何?
ブラウザに対して、
「サーバーが指定した Content-Type を勝手に推測(sniff)するな」
と命令するセキュリティヘッダです。
■ 何を防ぐの?
MIME Type Sniffing 攻撃
ブラウザは本来、
image/pngtext/cssapplication/javascript
などの Content-Type を見て処理します。
しかし昔の仕様では
👉 中身を見て「これはJSっぽいな?」と勝手に解釈することがありました。
攻撃例(超重要)
- 攻撃者が 画像アップロード欄 に
|
1 |
<script>alert('XSS')</script> |
を仕込む
- サーバーは
image/pngとして返す - ブラウザが sniffing して「これJSじゃね?」
- スクリプト実行 → XSS成立
👉 nosniff があると ③が発生しない
■ WordPress + Webゲームでの重要性
特に危険なケース
- ユーザー名 / スコア表示
- 画像アップロード
- JSON / API レスポンス
- JS / CSS を動的生成している場合
👉 Webゲームは JS / JSON / 画像 を大量に扱う
👉 sniffing が許可されていると XSSの踏み台になる
✔ ほぼ 100% 有効化すべき
✔ 副作用ほぼなし
✔ XSS対策の基本
② X-Frame-Options
■ これは何?
ページが 他サイトの <iframe> に埋め込まれるのを制御するヘッダです。
|
1 2 3 |
X-Frame-Options: DENY または X-Frame-Options: SAMEORIGIN |
■ 何を防ぐの?
クリックジャッキング攻撃
攻撃例
- 攻撃者のサイトに
|
1 |
<iframe src="https://example.com/game"></iframe> |
- iframe を 透明 にする
- 上に「ここをクリック!」ボタンを置く
- 実際は あなたのゲームのボタンをクリックさせている
👉
- 不正送信
- スコア操作
- 管理画面操作
などが可能
■ 設定値の違い
| 値 | 意味 |
|---|---|
| DENY | 完全禁止 |
| SAMEORIGIN | 同一ドメインのみ許可 |
| ALLOW-FROM | ※ほぼ非推奨・非対応 |
WordPress + Webゲームの場合
- 管理画面・スコア送信 → DENY
- サイト内で iframe 表示するゲーム → SAMEORIGIN
③ CSP(Content Security Policy)
■ これは何?
X-Frame-Options の上位互換 + XSS対策の最重要ヘッダ
|
1 |
Content-Security-Policy: ... |
■ 何を防ぐ?
主に防ぐもの
- XSS(スクリプト注入)
- iframe 埋め込み
- 外部 JS 読み込み
- 不正リソース通信
■ 例(Webゲーム向けの最低ライン)
|
1 2 3 4 5 6 |
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'self'; |
これで何が起きる?
| 項目 | 効果 |
|---|---|
| script-src ‘self’ | 外部JS実行不可 |
| frame-ancestors ‘self’ | iframe制御(X-Frame-Options代替) |
| img-src data: | base64画像OK |
| default-src ‘self’ | 原則同一ドメイン |
■ X-Frame-Options vs CSP
| 項目 | X-Frame-Options | CSP |
|---|---|---|
| iframe制御 | ○ | ◎ |
| XSS対策 | × | ◎ |
| 柔軟性 | 低 | 高 |
| 推奨度 | 旧 | 現行標準 |
👉 可能なら CSP を優先
👉 X-Frame-Options は保険
setcookie()
WordPressにおける PHP の setcookie() 関数は、ユーザーのブラウザにデータを保存し、再訪問時のユーザー特定や閲覧履歴の表示などに活用されます。
基本的な使い方
setcookie() は、HTTP ヘッダーの一部としてクッキーを送信します。
|
1 |
setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly ); |
- $name: クッキーの名前(例:
'user_id') - $value: 保存する値
- $expire: 有効期限。UNIX タイムスタンプで指定(例:
time() + 3600で 1 時間) - $path: クッキーが有効なパス。サイト全体なら
'/' - $secure:
trueにすると、HTTPS 接続時のみ送信 - $httponly:
trueにすると、JavaScript からのアクセスを禁止しセキュリティを向上
WordPressで利用する際の注意点
WordPress で setcookie() を使う場合、PHP の仕様上、あらゆる出力(HTMLや空白)よりも前に実行する必要があります。これに違反すると Warning: Cannot modify header information エラーが発生します。
- 推奨されるフック: WordPress の初期化段階である
initフックを使用するのが一般的です。 - 削除方法: 削除する場合は、有効期限を過去の時間(例:
time() - 3600)に設定して再度実行します。 - データの取得: 保存されたクッキーは、次回のリクエスト時に
$_COOKIE['名前']で取得できます。
実装例
以下は、ユーザーの訪問回数をカウントする簡単なコード例です。
|
1 2 3 4 5 6 7 8 9 10 |
function my_set_visitor_cookie() { if ( !isset( $_COOKIE['visit_count'] ) ) { $count = 1; } else { $count = (int)$_COOKIE['visit_count'] + 1; } // 30日間有効なクッキーをセット setcookie( 'visit_count', $count, time() + ( DAY_IN_SECONDS * 30 ), COOKIEPATH, COOKIE_DOMAIN ); } add_action( 'init', 'my_set_visitor_cookie' ); |
有効期限について
1. ブラウザによる制限(最大400日)
現在、Google Chrome をはじめとする主要なブラウザでは、セキュリティとプライバシー保護の観点から、クッキーの有効期限を 「最大400日(約13ヶ月)」 に制限しています。
- 400日を超える値を指定しても、ブラウザによって自動的に400日以内に短縮されます。
- Safariなど一部の環境(ITP)では、さらに短い期間(7日間など)に制限される場合もあります。
2. 2038年問題の制約
PHPの setcookie() は UNIX タイムスタンプを使用するため、理論上の最大値は 2038年1月19日 までとなります(32bitシステムの場合)。これを超える値を設定すると、計算がオーバーフローして過去の日時として扱われ、クッキーが即座に削除される原因となります。
3. 指定しない場合の挙動(セッションクッキー)
有効期限を 0 または省略した場合、そのクッキーは 「セッションクッキー」 となり、ブラウザを閉じると消滅します。これは「無期限」とは逆の挙動です。
「実質的な無期限」を実現する方法
ユーザーがサイトを訪れるたびに有効期限を更新(上書き保存)することで、継続的に利用するユーザーに対しては実質的に期限が切れないように運用するのが一般的です。
|
1 2 |
// ユーザーがアクセスするたびに、現在から約1年後(365日)に期限を延ばす setcookie( 'my_cookie_name', 'value', time() + ( DAY_IN_SECONDS * 365 ), COOKIEPATH, COOKIE_DOMAIN ); |
長期的なデータの保持が必要な場合は、クッキーには識別用の ID のみを保存し、実際のデータはサーバー側のデータベース(WordPress なら wp_options テーブルやカスタムテーブルなど)で管理することをおすすめします。
APIをプラグイン間で跨いで使用する時相手側のJSを読まないようにする
|
1 2 3 4 5 6 7 8 |
if (!is_singular()) { return; } global $post; if (!$post || !has_shortcode($post->post_content, 'ショートコードにした関数')) { return; } |
↑をフックに追加する
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function JS、CSSを読み込ませる関数() { if (!is_singular()) { return; } global $post; if (!$post || !has_shortcode($post->post_content, 'ショートコードにした関数')) { return; } wp_enqueue_style('style', plugin_dir_url(__FILE__) . 'game.css', array(), filemtime(plugin_dir_path(__FILE__) . 'game.css')); wp_enqueue_script('script', plugin_dir_url(__FILE__) . 'game.js', array(), filemtime(plugin_dir_path(__FILE__) . 'game.js'), true); wp_localize_script("script", "wpApiSettings", ["nonce" => wp_create_nonce("wp_rest")]); } add_action('wp_enqueue_scripts', 'JS、CSSを読み込ませる関数'); |
is_singular()
主な効果と判定範囲
通常の「投稿(is_single)」だけでなく、「固定ページ(is_page)」や「カスタム投稿タイプ」の個別ページも一括で判定できるのが最大の特徴です。
| 表示中のページ | is_singular() の戻り値 |
|---|---|
| 投稿ページ (single) | true |
| 固定ページ (page) | true |
| 添付ファイルページ (attachment) | true |
| カスタム投稿の個別ページ | true |
| アーカイブ・一覧ページ | false |
| トップページ・検索結果 | false |
主な活用シーン
- メタタグ・広告の制御: 記事ページ全般(投稿・固定・カスタム投稿)にのみ特定のスクリプトや広告、メタタグを出力したい場合に便利です。
- サイドバーの切り替え: 一覧ページではなく、詳細記事の時だけサイドバーの内容を変更するといった制御に使われます。
使い分けのポイント
is_single(): 通常の投稿(post)の個別ページのみを判定します。カスタム投稿には反応しません。is_singular('my_post_type'): 引数に投稿タイプ名を指定すると、特定のカスタム投稿タイプのみを狙い撃ちして判定できます。
仮想環境と本番環境でコードを切り換える
WordPressにおけるJavaScriptの環境切り替え(仮想/ローカル環境と本番環境)は、PHP側で環境を判定し、その情報をJSに渡す方法が最も一般的で安全です。
主に以下の2つのステップで実装します。
1. PHPで環境を判定し、JSへ変数を渡す
WordPress 5.5以降では wp_get_environment_type() 関数を使用して、現在の環境(local, staging, productionなど)を取得できます。
functions.php 等で wp_localize_script() を使い、JS側で参照できるオブジェクトとして環境情報を出力します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// functions.php function my_enqueue_scripts() { wp_enqueue_script('my-script', get_template_directory_uri() . '/js/script.js', array(), '1.0', true); // 環境タイプを取得 (デフォルトは 'production') $env_type = wp_get_environment_type(); // JS側で myAppVars.env として参照可能にする wp_localize_script('my-script', 'myAppVars', array( 'env' => $env_type )); } add_action('wp_enqueue_scripts', 'my_enqueue_scripts'); |
※ wp-config.php に define( 'WP_ENVIRONMENT_TYPE', 'local' ); と記述することで、明示的に環境を指定できます。
2. JavaScript側で条件分岐する
PHPから渡された変数 myAppVars.env を使って、コード内で処理を切り替えます。
|
1 2 3 4 5 6 7 8 |
// script.js if (myAppVars.env === 'local') { console.log('現在は仮想(ローカル)環境です。デバッグ用コードを実行します。'); // 開発用APIエンドポイントの使用など } else { console.log('現在は本番環境です。'); // 本番用トラッキングコードの実行など } |
その他の方法
- 読み込むファイル自体を切り替える: PHP側の
if文で wp_enqueue_script() するファイルパスを書き換える手法もあります。 - 環境変数によるビルド切り替え: WebpackやVite等のビルドツールを使用している場合は、ビルド時に
.envファイルを読み込み、環境ごとに最適化されたJSファイルを生成するのが一般的です。
wp_localize_script()
WordPressのwp_localize_script()関数は、PHP側(サーバーサイド)で定義した配列や変数を、JavaScriptファイル(クライアントサイド)へ渡すための推奨される方法です。
本来はローカライズ(翻訳)のための関数ですが、PHPのデータをJSに渡す機能が非常に便利なため、主に「JSの動的な設定値の受け渡し」に利用されます。
wp_localize_script() の主な効果・用途
- PHPの値をJSへ安全に渡す
- JSファイルに動的なデータを持たせる
- Ajax通信時のURL指定
- セキュリティ向上(セキュリティトークン)
基本的な使い方
wp_enqueue_script()でJSを読み込んだ後、その直後で使用します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function my_scripts_method() { // 1. スクリプトをエンキュー wp_enqueue_script( 'my-script', get_template_directory_uri() . '/js/my-script.js', array('jquery'), '1.0', true ); // 2. PHPのデータをJSに渡す wp_localize_script( 'my-script', 'myScriptVars', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'themeUrl' => get_template_directory_uri(), 'userId' => get_current_user_id(), 'message' => __( 'こんにちは', 'textdomain' ), ) ); } add_action( 'wp_enqueue_scripts', 'my_scripts_method' ); |
上記に対応するJavaScript(my-script.js)
PHPで指定したオブジェクト名(myScriptVars)を使ってアクセスします。
|
1 2 |
console.log(myScriptVars.ajaxUrl); // AjaxのURLが出力される console.log(myScriptVars.message); // 「こんにちは」が出力される |
なぜ直接jsファイルに書かないのか?
JavaScriptファイル内に直接PHPのコード(<?php ... ?>)は書けません。JSファイルを別ファイルにせず、PHP内に<script>タグで直接埋め込むことも可能ですが、それだとJSファイルが複数箇所に散らばり、管理が大変になります。wp_localize_script()を使うと、JSファイルを外部ファイル(.js)に保ったままデータを渡せるため、クリーンなコードになります。
※補足:WordPress 4.5以降、単純な値の渡し方としてwp_add_inline_script()も推奨されていますが、配列データを渡す場合はwp_localize_script()が適しています。
wp_get_environment_type()
WordPressの wp_get_environment_type() 関数は、WordPress 5.5で追加された、現在のWebサイトが「本番環境」「ステージング環境」「開発環境」のどれであるかを取得する機能です。
この関数を使うことで、環境ごとに動作を切り替える(条件分岐する)ことが可能になり、安全で効率的な開発・運用ができるようになります。
1. 主な戻り値
デフォルトでは、以下の3つの値のいずれかを返します。
production(本番環境) – デフォルト設定staging(ステージング環境) – 本番の複製環境development(開発環境) – ローカル環境など
2. 主な効果と活用例
本番環境でエラー表示を出さず、開発環境ではエラーを表示する、といったきめ細やかな管理ができます。
開発/ステージング環境のみGoogleアナリティクスを無効化する
|
1 2 3 |
if ( 'production' !== wp_get_environment_type() ) { // 本番環境以外ではタグを出力しない } |
ローカル環境でのみデバッグ機能を有効にする
|
1 2 3 4 |
if ( 'development' === wp_get_environment_type() ) { define( 'WP_DEBUG', true ); define( 'WP_DEBUG_DISPLAY', true ); } |
ステージング環境で検索エンジンにインデックスさせない(noindex)
|
1 2 3 |
if ( 'staging' === wp_get_environment_type() ) { // noindexタグを出力 } |
3. 設定方法
環境タイプは、wp-config.php ファイルに定義を追加して指定します。
|
1 2 |
// 例: ローカル環境を開発用として設定 define( 'WP_ENVIRONMENT_TYPE', 'development' ); |
この定義がない場合、WordPressは自動的に production(本番)として扱います。
テーマ(スタイル)回避
✅ STEP① rewrite ruleを追加
|
1 2 3 4 5 6 7 8 |
function aim_game_add_rewrite_rule() { add_rewrite_rule( '^aim/?$', 'index.php?aim_game=1', 'top' ); } add_action('init', 'aim_game_add_rewrite_rule'); |
✅ STEP② クエリ変数を登録
|
1 2 3 4 5 |
function aim_game_query_vars($vars) { $vars[] = 'aim_game'; return $vars; } add_filter('query_vars', 'aim_game_query_vars'); |
✅ STEP③ テーマを通さず出力
|
1 2 3 4 5 6 7 |
function aim_game_template_redirect() { if (get_query_var('aim_game') == 1) { include plugin_dir_path(__FILE__) . 'game-template.php'; exit; } } add_action('template_redirect', 'aim_game_template_redirect'); |
⚠ 重要:パーマリンク更新
管理画面
→ 設定
→ パーマリンク
→ 「変更せず保存」
これを必ず実行。
これをしないと /aim/ は動きません。
🎮 STEP④ game-template.php を作る
プラグインフォルダに:
|
1 |
wp-content/plugins/aim-training-game/game-template.php |
最小構成テンプレート
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php if (!defined('ABSPATH')) exit; ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>AIM TRAINING</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <?php // WPのスクリプトを読み込む wp_head(); ?> <style> html, body { margin: 0; padding: 0; background: #000; overflow: hidden; } </style> </head> <body> <div id="aim-root"> <canvas id="aimCanvas"></canvas> </div> <?php wp_footer(); ?> </body> </html> |
🔹 wp_enqueue をこのページだけに限定
|
1 2 3 4 5 6 7 |
function aim_game_conditional_enqueue() { if (get_query_var('aim_game') == 1) { wp_enqueue_style('aim-training-game-style'); wp_enqueue_script('aim-training-game-script'); } } add_action('wp_enqueue_scripts', 'aim_game_conditional_enqueue'); |
add_rewrite_rule()
独自のカスタムURL(パーマリンク)を作成し、それをWordPress内部のクエリ変数へ紐付けるための関数です。
実装の際の注意点
- フック: 必ず
initアクションフック内で実行する必要があります。 - ルールの反映: コードを追加しただけでは反映されません。管理画面の「設定 > パーマリンク」で「変更を保存」ボタンを押す(リライトルールの更新/フラッシュ)作業が必要です。
- 優先順位: 第3引数に
'top'を指定することで、既存のWordPress標準ルールよりも優先的に適用させることができます
第一引数.、$regex (正規表現)
「どのURLに一致させるか」を定義する文字列です。
- ユーザーがブラウザに入力するURLのパターンを正規表現で記述します。
- 例:
'^travel/([^/]+)/?$'(example.com/travel/tokyo/のようなURLにマッチ)
第二引数、$query (リライト先)
「一致したURLをWordPress内部でどう処理するか」を指定する文字列(または配列)です。
- 通常は
index.php?から始まるクエリ文字列を指定します。 - 正規表現でキャプチャした値は
$matches[1]のように参照できます。 - 例:
'index.php?category_name=$matches[1]'
第三引数 $priority (優先順位)
「新しいルールをどこに追加するか」を指定するオプション引数です(デフォルトは 'bottom')。
'top': 既存のWordPress標準ルールよりも優先されます。'bottom': 既存ルールの後に評価されます。- 基本的には、意図した通りに動作させるために
'top'を指定するのが一般的です。
|
1 2 3 4 5 |
add_rewrite_rule( '^news/([0-9]{4})/?$', // 1. $regex: news/数字4桁/ にマッチ 'index.php?year=$matches[1]', // 2. $query: 抽出した数字を内部クエリに渡す 'top' // 3. $priority: 優先度を高く設定 ); |
ハッシュ処理
hash_hmac() の使い方(署名生成)
hash_hmac は、秘密鍵を使ってハッシュ値を計算する関数です。これを使うと、データが改ざんされているかどうかをチェックできます。
基本構文:
|
1 |
hash_hmac(string $algo, string $data, string $key, bool $binary = false): string |
$algo: ハッシュアルゴリズム(’sha256′ など)$data: ハッシュ化するデータ$key: 秘密鍵(サーバー側のみが知る安全な文字列)$binary: trueにするとバイナリ、falseだと16進数(デフォルト)
WordPressでの使用例(カスタム署名の作成):
|
1 2 3 4 5 |
$data = 'user_id=123&action=delete'; $secret_key = 'super-secret-key'; // wp-config.phpなどで定義した秘密の文字列 // 署名を作成 $signature = hash_hmac('sha256'$data$secret_key); |
hash_equals() の使い方(安全な比較)
hash_equals() は、2つの文字列を、タイミング攻撃に耐性のある手法で比較します。
基本構文:
|
1 |
hash_equals(string $known_string, string $user_string): bool |
$known_string: 期待される正しいハッシュ値$user_string: ユーザーから受け取ったハッシュ値
WordPressでの使用例(署名の検証):
|
1 2 3 4 5 6 7 8 9 10 11 12 |
// 上記で作った署名をユーザーが送信してきたと仮定 $user_submitted_signature = $_GET['signature']; // サーバー側で再計算 $expected_signature = hash_hmac('sha256'$data$secret_key); // 安全に比較する if (hash_equals($expected_signature$user_submitted_signature)) { echo "署名が一致しました。安全です。"; } else { echo "データが改ざんされています。"; } |
WordPressでの実装例:安全なAPIエンドポイント
外部からのデータを受け取り、そのデータが正しいかどうかを検証する例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function check_custom_secure_request() { // 1. ユーザーから送信されたデータと署名を取得 $data = $_POST['data']; $received_signature = $_POST['signature']; // 2. サーバー側のみが知る秘密鍵 // ※実際には wp-config.php で定義した定数を使用すべき $secret_key = 'YOUR_SECRET_KEY'; // 3. 署名を再計算 $expected_signature = hash_hmac('sha256'$data$secret_key); // 4. hash_equals で検証 if (hash_equals($expected_signature$received_signature)) { // 検証成功: データ処理 return true; } else { // 検証失敗: エラー処理 wp_die('Invalid Signature'); } } |
まとめ
| 関数 | 役割 | セキュリティ上のポイント |
|---|---|---|
hash_hmac() | データの署名生成(ハッシュ計算) | 第3引数に秘密鍵を必ず使う |
hash_equals() | 文字列の比較 | == や === は絶対に使わない |
注意点
- WordPressにはネイティブのNonce機能(
wp_create_nonce())があります。通常のフォーム・Ajax処理にはそちらを推奨します。wp_verify_nonce() hash_hmac()+hash_equals()は、外部APIとの連携、独自のURL署名など、より堅牢なセキュリティが必要な場合に使用します。hash_equals()は、比較する2つの文字列の長さが同じ場合に安全です。HMACは通常固定長なので問題ありません。
その他
- false は int にキャストすると 0 になる
コメント