WordPressでセッション(SESSION)を扱う方法
以前、JMeterに関するコチラの記事で、セッション情報を利用した記事を紹介しました。
この記事を書くにあたり、WordPressで運用しているテストサイト(penguinweb.net)でセッションの値の出し入れさせる処理を記述したのですが、なぜかうまく動作しませんでした。
早々に諦めて簡単なテストページを作っても良かったのですが、「世界規模で利用されているWordPress様で使えないってことはないだろう」ということで調べてみたところ、セッションを利用するためには少々手間を加えないといけないことがわかりました。
せっかく調べたので、本日はWordPressでセッションを利用する方法について紹介したいと思います。
問題点とその原因
まず、なぜWordPressでセッションが使えなかったかについて触れたいと思います。
PHPでセッションを扱う際は、まず「session_start()」でセッションを開始する必要がありますが、この関数はPHPドキュメントにあるとおり、
クッキーに基づくセッションを使用している場合、ブラウザに何か出力を行う前に session_start() をコールする必要があります。
引用元:https://secure.php.net/manual/ja/function.session-start.php
となっています。
つまり、PHPファイルの一番最初で実行する必要があります。
そこで、WordPressのテンプレートを作成したことがある方はご存知かと思いますが、index.phpや
single.phpなどで、一番最初に呼び出すheader.phpの一番最初に「session_start() 」を記述したのですが、
動かない。。。
一体どうなってるんじゃい?
ここで諦めるわけには行かないので調べてみましたが、原因特定をしているサイトが見つかりませんでした。
引き続き探すこと30分、なんとセッション開始がうまくいかない時にチェックするポイントを紹介しているサイトがありました。
- Make sure
session_start();
is called before any sessions are being called. So a safe bet would be to put it at the beginning of your page, immediately after the opening<?php
tag before anything else. Also ensure there are no whitespaces/tabs before the opening<?php
tag.- After the
header
redirect, end the current script usingexit();
(Others have also suggestedsession_write_close();
andsession_regenerate_id(true)
, you can try those as well, but I’d useexit();
)- Make sure cookies are enabled in the browser you are using to test it on.
- Ensure
register_globals
is off, you can check this on thephp.ini
file and also usingphpinfo()
. Refer to this as to how to turn it off.- Make sure you didn’t delete or empty the session
- Make sure the key in your
$_SESSION
superglobal array is not overwritten anywhere- Make sure you redirect to the same domain. So redirecting from a
www.yourdomain.com
toyourdomain.com
doesn’t carry the session forward.- Make sure your file extension is
.php
(it happens!)引用元:http://stackoverflow.com/questions/17242346/php-session-lost-after-redirect
英語かよ、、、
英検2級の実力見せてやるわ!
ということで、1番目の英語を読み解くと「とにかく一番最初に実行しなさい、余白も改行も入れてはいけません」ということでした。
WordPressには、全ての処理の最初に実行されるのアクションフックがあるので、早速試したところ、うまく動作しました!
おっしゃ!
これにより原因は、header.phpよりも先に処理が実行されているので、セッションが開始できなかったと考えられます。
なお、WordPressがテーマファイルを呼び出すまでの処理の流れを知りたい方は以下のサイトが参考になりますので、紹介しておきます。
解決方法
それでは、具体的なソースで解決方法を紹介します。
先に説明したとおり、アクションフックを利用することが前提になりますので、まずセッションを開始する関数を準備します。
function session_start(){ session_start(); }
こちらの関数を一番最初に実行するべく、アクションフック「add_action」関数の引数に「init」と先に作ったセッションを開始する関数を指定します。
add_action('init', 'session_start'); function session_start(){ session_start(); }
(アクションフックがわからないという方もいると思うので、add_actionについては別の機会で触れたいと思います)
最後に、この出来上がったソースをfunction.phpに記述すれば(一番上じゃなくてもOK)、どの記事にアクセスしてもセッションが開始されます。
なお、特定の記事だけでセッションを利用したい場合は、以下のようにif文などでセッション開始を制御すれば良いと思います。
if(is_single('XX')){ add_action('init', 'session_start'); function session_start(){ session_start(); } }
これでWordPressの各記事で、セッション情報を操作できるようになります。
以下に、実際にテストページで実行しているソースを紹介します。(テストページはコチラ)
処理内容としては、セッションか空の場合、値を格納し、次にアクセスしてきたらセッション情報を削除するという処理を行っています。
<?PHP if ($_SESSION["sessionID"] == ""): ?> <?PHP $_SESSION["sessionID"] = session_id(); ?> <?PHP $_SESSION["mislead"] = "misleadはもうコリゴリだ"; ?> 初回の訪問です。セッションを開始します。 セッションには『<?PHP print $_SESSION["mislead"]; ?>』を格納しています。 <a href="http://penguinweb.net/200.html">リロード(セッション情報がある状態でアクセス)</a> <?php else: ?> セッションが入っています。 セッションに格納されている値は、『<?PHP print $_SESSION["mislead"]; ?>』です。 ここでセッション情報を破棄します。 <?PHP session_destroy(); ?> <a href="http://penguinweb.net/200.html">リロード(セッション情報がない状態でアクセス)</a> <?php endif; ?>
最後に
僕のWordPressでセッションを利用する目的は、「JMeterでセッションを利用する方法を紹介するためのテストページを作るため」でしたが、同じような理由の方でこのサイトに来た人はいないかと思います。
一般的には、WordPressで会員サイトやECサイトを作ろうとしている方が必要としているナレッジなのかなと思います。
(他の理由で訪れた方は、ぜひコメント下さい!)
WordPressには会員サイトやECサイトが実現できる便利なプラグインもありますが、かゆいところに手が届かなかったりするので、この記事が参考になれば幸いです。
コメント一覧
すごく参考になりました!・・・が、
function session_start(){
session_start();
}
これは再帰関数になってしまい終わらないループ処理になる危険があるように思います。
既存の関数名が優先されるのか、新しい定義の関数名が優先されるのか、試さないとわかりませんが、別の名前をつけるべきだと思います。