WordPress記事内にPHPを埋め込む(実行させる)方法

Icon PHP

WordPressの記事・固定ページにPHPのコードを入れる場合、一手間が必要です。JavaScriptだとエディタ上で簡単に埋め込めるのですが。

方法は、恐らく、以下の3つでしょう。

  1. functions.phpにショートコードを追加する
  2. プラグインを使用する
  3. iframeタグでPHPページを読み込む

ネットでよく見るのは上の2つです。3つめのiframeを使用した方法では、WordPressとは別の.phpファイルを自分で作成する必要があります。

この記事では、主に上記3つについて説明しています。

ちなみに、1の方法(functions.phpを修正する方法)はコードにシンタックスエラーがあると、WordPress全体が表示されなくなる危険があります。修正前に必ずバックアップを取り、注意して作業しましょう。

functions.phpにショートコードを追加する

ショートコード (Shortcode)とは

公式ドキュメント(日本語訳)に説明がありますが、ショートコートはマクロであり、事前に定義した関数を呼び出すものです。WordPressのエディタ上では、↓のようなアイコンで出てきます。

WordPress Shortcode
ショートコードのアイコン

エディタに埋め込むと、こんな画面が出てきます。事前に定義したショートコードのタグ名を、[ ]で囲って指定します(引数を渡すことも可能)。

WordPress Shortcode

functions.phpにショートコードを追加する方法は、さらに2つの方法があります。

  1. functions.phpに直接ショートコードを書く
  2. 外部PHPファイルを読み込むショートコードを作成する

方法1: functions.phpに直接ショートコードを書く

ネットで探すと一番よく出てくる方法です。

そもそも、functions.phpとは何か?ですが、WordPressテーマに対して独自機能を組み込むためのファイルです。公式ドキュメントのTheme Handbookにはこうあります。

The functions.php file is where you add unique features to your WordPress theme. It can be used to hook into the core functions of WordPress to make your theme more modular, extensible, and functional.
(拙訳:functions.phpファイルはWordPressテーマに独自の機能を追加する場所です。functions.phpは、テーマをよりモジュール化、拡張的、機能的にするために、WordPressの核となる機能にフックするのに使用することができます。)

WordPress.org – Theme Functions

日本語ドキュメントにも記載がありますね…(functions.php概説)。

functions.phpに追記する方法で実現は、まぁ、実現はできるのですが、もう少し簡単にできる方法はないものでしょうか。

注意点: functions.phpに不具合があるとサイト全体が表示されなくなる

functions.phpを修正する際は要注意

重要な注意点ですが、functions.php内でシンタックスエラーがあったりすると、WordPressサイト全体が表示されなくなります。最低限バックアップは取得し、修正箇所はコメントで分かるように書くなどする必要があります。何かあった時、戻せるようにしておきましょう。

問題が発生すると、サイトを閲覧した時に以下のように表示されます。

WordPress fatal error
サイトに重大なエラーがありました(WordPressエラー)

ちなみに、try catchの例外処理でもシンタックスエラーは補足できません。PHPのマニュアルによると、「スローされるオブジェクトは、Exception クラスあるいは Exception のサブクラスのインスタンスでなければなりません。」とあります。

参考サイト:PHP – 例外(exceptions)

方法2: 外部PHPファイルを読み込むショートコードを作成する

上で説明したのは、PHPコードをそのままfunctions.phpに追加する方法でした。それとは違い、ショートコード側で外部のPHPファイルを引数として指定し、実行させることも可能です。

例えば、loadPHPというショートコードを作成するとします。そこで引数fileで指定したPHPファイルを↓こんな感じで指定します。

[loadPHP file=”xxx.php”]

後述するiframeを使用する方法に比べ、内部構造を隠蔽可能です(引数で指定したPHPはHTMLには出力されない)。また、コーディング不備のせいでWordPress全体が落ちてしあう事態を避けることも可能です。全体に波及しません。

ただし、引数で指定した外部PHPファイルにコーディング上の不備があると、ショートコードを使用している記事(もしくは固定ページ)が表示不可能になります。記事の編集もできなくなります。これもミスると多少は面倒です。

記事の最後で説明するiframeを使用する方法が、最も影響範囲が小さいという意味で、安全なのかもしれません。

実装方法

① functions.phpに直接ショートコードを書く方法

functions.phpは、各テーマのフォルダ直下にあります。

WordPressインストールフォルダ/wp-content/themes/テーマ名/functions.php

こんな感じで。

functions.phpの中に直接記述してもいいですが、requireを使って外部ファイル化してもいいかもしれません(その方が、すっきりするかも)。

<?php
// 追加のショートコード
function test_shortcode01() {
  return 'This is a shortcode test.';
}
add_shortcode( 'test01', 'test_shortcode01' );
?>

functionで記述し、最後にadd_shortcodeを実行します。add_shortcodeの引数には、タグ名とそれに紐付く関数名を指定します。タグ名は、記事内でショートコードを指定する時に使用するものです。

記事内のショートコードで、タグ名を指定します。

WordPress Shortcode

すると、こんな感じで表示されるはずです。

WordPress Shortcode

何度も書いていますが、PHPにシンタックスエラーなど致命的なエラーがあるとWordPress全体が表示されなくなるので、テストするなら試験用の環境などで実施しましょう。

ちなみに、shortcodeを記述するPHPファイルをfunctions.phpから切り離す場合は、requireもしくはinclude(か、require_once、include_once)で外部PHPを読み込めばOKです。PHP公式マニュアルのrequireのページに記載がありますが、includeは警告であればその後の処理も実行されるという違いがあります。シンタックスエラーなら、どちらも落ちますが。

補足ですが、英語サイトですが、このShortcodes Generator (GenerateWP)を使用すると、ショートコードの関数のひな形が簡単に作れます。

Generate WordPress Shortcodes
WordPressShortcodesGeneratorfordevelopers.

② 外部PHPファイルを読み込むショートコードを作成する方法

あくまで例ですが、実行させたいPHPコードを “ドキュメントルート/extra”フォルダに置き、ファイル名はtest.phpとします。

WordPress external php files

上で作ったtest.phpを読み込む用のショートコードを作成します。ショートコードの名称としてはloadPHP、関数名はloadExternalPHPとしています。引数としてファイル名も指定できるようにします。

//外部PHPを読み込むショートコード
function loadExternalPHP($args) {
    //$fileに引数をセット
    extract(shortcode_atts(array('file' => 'nothing.php'), $args));
    //外部PHPを実行
    require ABSPATH . "extra/" . "$file";
}
add_shortcode( 'loadPHP', 'loadExternalPHP' );

配列に値が存在しない場合、デフォルト値として’nothing.php’を指定しています。extractとshortcode_attsの詳細な説明は以下のサイトをご覧下さい。ABSPATHはWordPressがあるフォルダの絶対パスです。

記事では以下のように外部PHPファイルを指定します。

WordPress Shortcode

試すと分かると思いますが、この方法でも、PHPファイル中にシンタックスエラーなどがあると、記事編集画面が表示されなかったり、該当記事が表示されなかったりします(他のページは表示される)。こうなると記事が編集できなくなる事態にもなるので、コーディングをミスると不便ですね。

また、補足ですが、引数を指定しない場合も記事編集画面でエラーが出るかもしれません。

プラグインを使用する

これもネットでよく見つかる方法です。

Insert PHP Code SnippetPHP Everywhere、がよく見るものかも。

注意点を挙げるとすれば、脆弱性が入り込む余地が増えることと、サイトが重くなる可能性がある点でしょうか。

よく知られたことではありますが、WordPressはプラグインで簡単に機能追加ができる反面、プラグインを増やすことで脆弱性が入り込む余地が増えます(本体に脆弱性がある場合もあるけど、プラグインの使用でさらに入り口が増える)。便利だからと、安易に導入しないという考え方も必要です。

ちなみに、JVN iPedia(脆弱性情報のデータベース)にも、毎月まぁまぁな数の脆弱性が公表されています(まぁWordPressはプラグインの数自体が多いのもありますが)。ちなみに、2020年6月に公表されたWordPressとプラグインに関連する脆弱性は15件ありました(本体にもありましたね)。なので、セキュリティアップデートは必ずチェックしておく必要があります。

WordPress vulnerabilities
JVN iPedia 6月に公表されたWordPress脆弱性

実装方法

Insert PHP Code Snippet

ショートコードを作成し、記事内に埋め込みます。

プラグインをインストールすると、管理画面に↓のようなメニューが出来ます。

XYZ PHP Code

Add New PHP Code Snippetボタンがあるので押すと、作成画面になります。テスト用のコードは以下のようにします。ただ文字を出すだけ。

XYZ PHP Code

Updateで保存すると、管理画面にショートコードが表示されます。

XYZ PHP Code

後は、記事内のショートコードとして埋め込むだけです。

XYZ PHP Code

PHP Everywhere

こっちのほうが簡単です。

インストールすると、PHP Everywareという名前のブロックが作成可能になるので、これを埋め込み、PHPのコードを書くだけ。

PHP Everywhere

記事内で、以下のように書くだけです。Insert PHP Code Snippetよりは簡単ですね。

PHP Everywhere

こんな感じで表示されます。

PHP Everywhere

iframeタグを使用する

iframeタグを使用して、別に作成したPHPのページを子項目として表示させる、という方法です。WordPress全体(もしくは記事)に不具合が波及しないという意味では、恐らく最も安全でしょう。

実装方法は単純で、記事をHTMLとして編集し、以下のコードを追加するだけです(PHPのページは別途作成済みという前提)。

<iframe src="phpファイルのパス"></iframe>

注意点としては、外部のサイトが勝手にPHPのページをiframeで呼び出さないようにする対策が必要です(勝手に参照する人なんていないかもしれませんが、まぁ必要に応じて)。ちなみに、クリックジャッキング対策でも使用する方法です(クリックジャッキングについてはIPAのサイトをどうぞ)。具体的には、HTTPレスポンスヘッダーの、X-FRAME-OPTIONSで指定します。

X-FRAME-OPTIONS 指定方法

phpファイル中に指定する場合は、ファイルに以下を追記します。

header('X-FRAME-OPTIONS: SAMEORIGIN');

SAMEORIGINは、同一ドメイン内でのみ表示を許可します。
DENYを指定すると、フレーム内で表示させることはできなくなります。

ALLOW-FROM url を指定することで、指定したドメインでのみ表示を許可できるようですが、動作するブラウザが限られているのと、今では廃止されているようです。

補足ですが、X-FRAME-OPTIONSはApacheでも設定は可能。

参考サイト:MDN web docs – X-Frame-Options

補足:気をつけること(evalは安易に使用しない)

上に挙げた例では使用しませんでしたが、PHPにはevalという関数があります。公式サイトでも「非常に危険な言語構造」と説明されている通り、任意のPHPコードが実行可能な関数です。

任意のPHPコードを実行するには便利な関数ですが、外部からの悪意あるコードが実行されないように注意が必要です。

 

以上です。
ご参考までにお願い致します。