Exec-PHPは危険!記事内PHPを Post Snippets で一元化しよう – WordPress プラグイン

プロフィール
著者

映像系が本業のフリーランス・3児のパパブロガー。
車関連、Wordpress関連の事をよく記事にします。
イラストは下手なりに頑張って描いてますが、全く上手くなりません(笑)

ライトニングをフォローする

こんにちはライトニングです。

 私めがPHPを語るなんて甚だ厚かましい話ではありますが、それでもめげずに、使ってみて気に入ったプラグイン「Post Snippets」をご紹介したいと思います。

 既にこのプラグインに関しては数多くの紹介記事が出ていますが、書かれていない内容も多いので補足の意味で書かせて頂きました。

SPONSORED LINK

記事内にPHPを記述するのは危険?

 ある程度、WordPressに慣れてくるとPHPなんかを記事に入れて見たくなるものですが、WordPressの仕様上、記事内に<?php ~を記述してもPHPは動作しません。

 そこで有名なプラグインとしては

Exec-PHP
Exec-PHP

作者: Sören Weber

 「EXEC-PHP」が有名なんですけど、巷では現在使用が推奨されていません。詳しくは下記のサイトで論じられていました。

 非常に便利と言えば便利なプラグインではあるのですが、セキュリティの知識がない状態で使うと、大変危険なので使わない方が良いでしょう。

 代替案として有名なプラグインは下記です。

PHP Code for posts
PHP Code for posts

作者: Jamie Fraser

 PHPコードを登録し、記事内にそのショートコードを挿入することによって、実現します。実は結構使いやすい。

 しかしウィジェット内では機能しない(カスタムしたら使える?)のでウィジェットでは別に下記を入れることに。

PHP Code Widget
PHP Code Widget

作者: Otto

 ウィジェット版のExec-PHPみたいなやつで、導入するとウィジェットに専用の枠が追加され、その中であれば<?php ~ ?>の記述ができます。

 意外に記事よりもウィジェットでPHPを記述した事の方が多い気もするので、結構使われているようです。しかしよく考えるとこのプラグインもセキュリティ的には危ないのかも……

 と言うか、ライトニングも「PostSnippets」に出会うまでは、この2つのプラグインを入れていたんですがね(笑)

Post Snippetsとは?

「Post Snippets」ならばプラグインをまとめられる

 プラグインって言うのは、万人に使いやすいようにコードが長かったりするので、たくさん導入すると、どうしてもサイト自体が重くなってしまいます。なので、少ないに越したことがない(2つのプラグインより1つのプラグインの方が重い事もあるけど)。

 という事で、見つけたのがコチラ。

Post Snippets
PostSnippets

作者: Johan Steen

 基本的な仕組みはショートコードを登録して、記事内に挿入するためのプラグインですが、PHPも使えるので前述のPHP Code for postsに近い形で使用する事が出来ます。ただし、インストールした直後は(2016年4月現在)ウィジェット内で機能しません。

 このプラグインの利点と欠点は

利点

  • カスタマイズすると記事内の他にウィジェットでも使用が可能
  • 変数(というよりパラメータ?)を受け渡せる
  • さらに[shortcode]~[/shortcode]のように囲むことによって、その中身を取り扱うこともできる
  • ショートコードを挿入する際、独自のポップアップが表示され分かり安い
  • 記述したショートコードをインポートしたりエクスポートする事ができる

欠点

  • ウィジェットに導入するためにはfunction.php等に少し記述しないといけない(初心者には一手間?)
  • ショートコードを並べ替える事が出来ないので見にくい
  • ちょっと仕様にクセがある。

 欠点も勿論ありますが、ライトニング的にはこれが現在のベストプラグインかと思っています。

インストール

 通常通り 管理画面>プラグイン>新規追加 から「Post Snippets」で検索すれば出てきます。またはワードプレスのページからダウンロードしても可能です。

 導入してもウィジェット内では使用できません。これはWORDPRESSの仕様でウィジェット内でショートコードを使えない(テーマによっては使えるものもあるかも)からなので、functions.phpに下記を追加してください。

CODE
クリックすると内容全部が選択状態
add_filter('widget_text', 'do_shortcode');

 これは、ウィジェットのテキスト枠にショートコードを使えるようにする為の物なので、既に他の用途で追加されているようであれば必要はありません。

設定画面の説明

 以後はプラグインバージョン 2.5.3を基に記述しています。

 管理画面>設定>Post Snippets からコードを登録します。

Manage Snippets 画面

PostSnippets001

(1)ヘルプ

 クリックすると、プラグインの説明などが(英語表記ですが)開いて出てきます。英語が少し分かるようならば、だいたいの内容は書いてあるので、参考になります。

(2)Update Snippets

 コードを追加したり変更した場合、このボタンを押すことによって更新されます。逆に言うとこれを押さないで(3)の「Add New Snippet」なんかを押すと変更が取り消されるのでご注意を。

(3)Add New Snippet

 コードを新たに追加する場合に押します。最初はまずココを押しましょう。

(4)Delete Selected

 チェックしたコードを削除する際、ここを押します。


「Add New Snippet」を押すと下の画面のようになります。
PostSnippets004

(5)Title

 ショートコードは [●●●] といった記述になりますが、この●●●の名前をここに書き込みます。

 使用した経験から言いますと日本語版WordPressを使用している限り、このTitleは日本語を使っても問題は出ませんでした。コードが増えた時に視認性を良くするために、日本語の名前の方が良さそうです。(今後、何かしらの問題が発生する可能性があるので英語にしておいた方が無難ではありますが)

(6)Variables

 コードに渡す変数を設定する場所です。

Variables Example
クリックすると内容全部が選択状態
url,name,role=user,title

 ヘルプには例として上記のように書いてありました。

 例のように変数(個人的にはパレメータと呼びたい)を「,(カンマ)」で区切ることによって複数設定できます。(ただしスペースを空けてはいけない

 例えば事項の説明部分も含まれますが、Post Snippetsで

PostSnippets005

のように記述し、記事内で

HTML
クリックすると内容全部が選択状態
[shortcode name="ライトニング" blogurl="http://lightnig2014.ensyutsubu.com/blog/" ]

と記入すると結果は

PostSnippets006

と、ショートコードにVariablesで定義した変数名に「=」で値を代入すると、Snippet欄の{変数名}に値が差し替えられます。

 後述しますが、変数という名前に惑わされて{変数名}をPHPの変数と考えると間違いですので、「差し替えられる」と覚えてください

 またVariablesは「year=2016,name=ライトニング」という表記で初期値を設定する事もできます。

 しかしその際、Variablesの中(記事内のショートコード記述の事ではない)では文字列だとしても「”(ダブルクォーテーション)」や「’(シングルクォーテーション)」では括らないでください。

 記述すると、最初は問題ないのですが、「Update Snippets」を押す毎に、これらの文字がサニタイズされ続け、変なことになります。(バージョン 2.5.3現在)

LIB_onepoint
こんな事になる。
“ -> &quot; -> &amp;quot; -> &amp;amp;quot; ->……

 さらに下記の条件があります。ご注意ください

  • 変数名には日本語は不可です
  • 変数名にはヘルプに記述はないのですが、経験上、例えば「Name」のように大文字を入れると上手く挿入されません(バージョン 2.5.3現在)
  • 「content」は後述しますが、予約語なので使用できません。

(7)Snippet

 この中にショートコードの中身を書き込みます。

 「PHP Code」にチェックした場合、PHPコードを記述する事もできます。その際は「<?php」などの記述は必要がありません(というか書いてはいけません)

 「Variables」の変数を「{ }」で括る事によって、ショートコードのパラメータを取得することができます。その際、{変数名}自体は変数ではなく、単に値が置換されているようです。

例えば

[test year=2016 name=”ライトニング” ]

というショートコード場合
PHP記述を

$year = {year};
$name = {name};

とすると、$nameはちゃんと代入されません
正解は

$year = {year};
$name = “{name}”;

となります。変数という言葉に騙されて上の記述をしてしまいがちなのでご注意を。

 またショートコードをHTMLタグのように、

HTML
クリックすると内容全部が選択状態
[test-xyz] この中身は{content}として代入されるよ 複数行の場合は? [/test-xyz]

このように括ると、その間の内容を {content} で受け取る事ができます。

 例えば、上記のショートコードに対してPHPコードを

PostSnippets PHP
クリックすると内容全部が選択状態
$str = "{content}"; echo $str;

と記述した結果は

PostSnippets007

のようになります。改行も反映しているのが分かると思います。

(8)Description

 コードの説明を書くところ。記事のエディターで「Post Snippets」ボタンを押すと出てくる選択画面で表示されるので、忘れないようにパラメータの説明も書いておくと便利。

 <br />の記述を使って改行する事もできます。

(9)Shortcode チェックボックス

 チェックを入れると[Title]の形のショートコードが使用できます。

 チェックしない意味がワカラン!って思うかも知れませんが(笑)チェックしないと記事の入力画面での挙動に変化しますので後述します。

(10)PHP Code チェックボックス

 チェックを入れるとSnippet部分がPHPコードとして認識されます。逆にチェックを入れないとHTMLとして扱われます。

(11)wptexturize チェックボックス

 ライトニングは使った事がないのですが、出力する前にwptexturizeを実行するとヘルプに書かれています。wptexturizeに関しては下記を参照してください。

PostSnippets008

 上記がON・OFFの違いですが、かなり微妙なのでクリックで拡大表示してご覧ください。同じ文書を投稿入力した場合、Post Snippetsでwptexturizeの有り無しで比べてみました。ダブルクォーテーションの形とかがWordPressらしく整形されています。(余計な整形までありますが)

 まあ、必要ならばチェックしてみてください。

Options 画面

PostSnippets002

 今のところ(バージョン 2.5.3現在)ひとつしか設定項目がありません。

Exclude from Custom Editors

 チェックを入れるとカスタムエディタから除外する。つまりPost SnippetsはWordPress標準の投稿画面でのみ機能するようになるようです。(ほぼ和訳)

 んーーカスタムエディターって何でしょう?? わかりません。

 チェック入れなくて良いと思います。

Import/Export 画面

PostSnippets003

 こちらの画面から設定をファイルとしてエクスポートとインポートする事ができます。

 これを使えば、複数のサイトを立ち上げていても同じ環境が簡単に手に入りますので楽ですよ。

投稿画面での使い方

基本的な使い方

PostSnippets010

 テキストエディタの場合上の様なボタンが出現します。

PostSnippets011

 個人的には慣れてきたらビジュアルエディタでの投稿はオススメしないのですが、ビジュアルエディタだと上のようなアイコンが表示されます

PostSnippets012

 「Post Snippets」をクリックすると、コードが登録されていれば、このような画面になります。

 設定画面でDescriptionで設定した内容が表示されているのが分かると思います。

 また、今回Variablesには下記のように記述しました。

Variables
クリックすると内容全部が選択状態
name,blogurl=http://から入力してね

 初期値を入力したので、既にblogurlの値に文字が入っているのが確認できます。このように記述しておけばDescriptionに変数の説明を書かなくても、説明を入れられますが、思わぬサニタイズが行われる可能性があるので注意してください。

PostSnippets013

 例えば上の様に入力して「Insert」を押すと

PostSnippets014

登録の際「Shortcode」をチェックしていれば、上のようにショートコードがインサートされます。

 勿論、これを公開するとショートコードは書き換えられて表示されます。

LIB_onepoint
 例えば変数(パラメータ)に

[テスト para=”name:”ライトニング” children:2″ ]

のように「”(ダブルクォーテーション)」を入れたい場合、そのままだと不具合が発生します。その場合は「”」の代わりに

[テスト para=’name:”ライトニング” children:2′ ]

「’(シングルクォーテーション)」で大枠を囲んで上げれば成立できます。どちらも含む値は……無理かな(笑)

Shortcodeチェックの有無の違い

 上述のように「Shortcode」をチェックしていれば、ショートコードが埋め込まれますが、チェックしていないとどうなるでしょうか?

 同様にインサートしてみると

PostSnippets015

なんと、変数に置き換えられたコード内容がそのまま代入されます。

 ちなみに「PHP Code」にチェックが付いていても、「Shortcode」を外せますがインサートしてみると

PostSnippets016

「PHP Code」のチェックが意味なくなるようです。

囲んだ内容を変数(パラメータ)としての送り方。

PostSnippets017

 タグのように囲んだ内容を値に渡したい場合は、上の写真のように、内容終了のところに[/ショートコード名 ]で閉じます。

 その際、内容を囲んで「Post Snippets」のボタンを押すと、内容が消えてしまうのでご注意を。テキストエディタのように選択囲んでみたいにしたいのならば、「AddQuicktag」のようなプラグインでさらに登録する必要があります。

PHP正規表現が使えない?

CODE
クリックすると内容全部が選択状態
preg_match("/(\?v=|\&v=)(.+)?/", $yt_url, $yt_para);

 PHPを記述する際、慣れてくると上のような正規表現を使ったりしますが、PostSnippetsでこういった表記をするとうまく動きません。

 ライトニングも非常に悩んだんですが、問題はエスケープ文字の「\(バックスラッシュ)」または「¥」がプラグイン内部でもエスケープと認識されてしまう(分かりにくいですが、PHP処理まで達しないで、途中で変換されてしまう)みたいです。

 対処法は簡単!エスケープ文字をさらにダブらせます

修正後
クリックすると内容全部が選択状態
preg_match("/(\\?v=|\\&v=)(.+)?/", $yt_url, $yt_para);

 この問題は追々もしかすると修正されるかも知れませんが、ご注意下さい。

(2017年5月現在)

 コードを書くのが別のエディタならば、上のツールを使って整形させれば、間違いがなくなり便利だと思います。

2018年1月20日追記

 PostSnippetsのバージョンがver3.0.0以降から、特に詳細には書かれていないのですが、エスケープ文字をダブらせなくても良くなりました。

 その為、いままでダブらせていたコードを書いていた方は修正をしなくてはならない可能性があります。ご注意!

2018年2月17日追記

 PostSnippetsのバージョンがver3.0.3以降から、またエスケープ文字をダブらせないといけなくなりました。

使用例

 「Post Snippets」の使用例として下記のような事ができます。ご参考にどうぞ。

問題は……

 と非常に有用なプラグインだと思うのですが、調子こいてたくさん登録すると

PostSnippets018

ボタンだらけで、どれがどれだか分からなくなります(笑)

 うーむ。今後この辺の見え方がアップデートで改善されればなぁと思うのですが、こんなにヘビーに使っている人がいないのかなぁ

 という事で、Post Snippetsをご紹介しました。

 このプラグインならばFunctions.phpなんかをいじらなくて済むので、汎用性の高いコードなんかを公表するのに敷居が低いような気がします。

2018年1月20日追記

 ver3.0.0以降、多少UIが変更になりましたが、基本的にはこの説明どおりです

コメント

  1. […] う使うものなのか、自分が使いこなせるものかを調べている時、「Exec-PHPは危険!記事内PHPを Post Snippets で一元化しよう」という記事にたどり着き、この記事が大変わかりやすくとても参 […]

  2. […] Exec-PHPは危険!記事内PHPを Post Snippets で一元化しよう – WordPress プラグイン […]

  3. […] […]