PHPの$_COOKIE(クッキー変数)または$_SESSION(セッション変数)でWordPressに閲覧履歴を表示。
PHPのスーパーグローバル変数の$_COOKIE(クッキー変数)とsetcookie()関数を使ってWordPressで閲覧履歴の表示を実装。
(クライアント側のクッキーにデータを保持させたくない場合は、$_SESSION(セッション変数)を使って実装。)
$_COOKIE[‘クッキーの名前’]でクライアントからのHTTPリクエストに含まれるクッキーの情報を取得、setcookie()でSet-Cookieヘッダーを含めたレスポンスを返して履歴ページのIDを管理する。
(セッションで実装する場合は、サーバー側でPHP実行時に$_SESSION[‘クッキーの名前’]でデータを取得・保持して管理する。)
- 任意のグローバル変数に、閲覧したページのIDを配列で代入して保持。
- 閲覧履歴を表示させたいテンプレートでグローバル変数を呼び出す。
- 保持しているページIDの配列と’post__in’でループ処理。
閲覧したページIDの配列化とクッキーの送信
閲覧したページのIDを新しい順で配列化し、任意のクッキー名の値としてクライアントにHTTPで送信して保持。(setcookie()関数に代入する場合は、型を配列から文字列に変換する。)
送信したクッキーの値は次にアクセスした時にしか取得できないので、現在閲覧中のページのIDを前回までのクッキーに追加した配列を任意のグローバル変数に代入して、実際のループ処理に使用する。
※ setcookie()関数より前にhtmlタグやechoなど出力されるものがあるとSet-Cookieヘッダーの処理ができなくなるので、一番最初に実行される位置に記述する。
//履歴用ページIDの配列を保持させるグローバル変数を宣言
global $his_posts;
//記事ページの場合、ページIDを取得して配列化
if(is_single()){
$post_id = $post->ID;//現在閲覧中のページID
$his_num = 5;//履歴に残す記事数
$expire_date = time()+60*60*24*30;//有効期限30日後
if(isset($_COOKIE['ag2history'])){
//すでにcookieが存在する場合
//クッキー変数から値を取得、文字列から配列に型を変換
$his_posts = explode(',', $_COOKIE['ag2history']);
//現在の記事がすでに履歴にある場合
if(in_array($post_id, $his_posts)){
//$his_postsから現在の記事IDを削除
$his_posts = array_diff($his_posts, array($post_id));
//現在の記事IDを削除したので配列のindex番号を振り直す
$his_posts = array_values($his_posts);
}
//履歴の保存記事数が限度数の場合
if(count($his_posts) >= $his_num){
//履歴配列の最後の値を削除して返す
$his_posts = array_slice($his_posts, 0, ($his_num - 1));
}
//現在のページIDを履歴配列の先頭に追加
array_unshift($his_posts, $post_id);
//配列から文字列に型を変換
$his_posts = implode(',', $his_posts);
//クライアントにSet-Cookieヘッダーを送信
setcookie('ag2history', $his_posts, $expire_date, '/');
//配列に戻して履歴用の変数へ代入
$his_posts = explode(',', $his_posts);
}else{
//cookieが存在しない場合
//現在のページIDを履歴としてクライアントのクッキーに送信
setcookie('ag2history', $post_id, $expire_date, '/');
//配列化して履歴用の変数へ代入
$his_posts = array($post_id);
}
}else{
//記事ページ以外の場合
//cookieがある場合
if(isset($_COOKIE['ag2history'])){
//クッキー変数から値を取得、配列化して履歴用の変数へ代入
$his_posts = explode(',', $_COOKIE['ag2history']);
}else{
//cookieが無い場合
$his_posts = false;
}
}
explode(‘区切り文字’, ‘文字列’) : 文字列を区切り文字で分割して配列にして返す。
in_array(‘文字列’, ‘配列’, ‘型の判定’) : 配列の中に文字列があればtrue、無ければfalseを返す。
array_diff(‘配列’, ‘比較用の配列’) : 比較用の配列には無い値だけを残して配列を返す。(値のindex番号は変わらない)
array_values(‘配列’) : 配列のindex番号(キー)を順番に[0]から数字で振り直す。
count(‘配列’) : 配列の要素数を返す。
array_slice(‘配列’, ‘切り取りを開始する位置までのオフセット’, ‘切り取る要素の数’) : オフセットの位置から指定の数の要素を配列から切り取って配列で返す。
array_unshift(‘配列’, ‘値’) : 配列の先頭に値を追加する。
implode(‘区切り文字’, ‘配列’) : 配列を区切り文字で繋げた文字列を返す。
setcookie(‘クッキーの名前’, ‘値’, ‘クッキーの有効期限’, ‘パス’) : 有効期限(Unixタイムスタンプ)と有効化するパスを指定してクッキーの名前に値を代入してSet-Cookieヘッダーをクライアントに送信する。
クッキーを削除したい場合
値を空、現在時刻より過去のクッキー有効期限を指定してSet-Cookieヘッダーを送信する。
保存する送信の時にパスとドメインが指定してある場合は、同じパスとドメインを指定する必要がある。
setcookie('クッキー名', '', time()-60, '/');
セッションで実装する場合
上記と同じ挙動を、$_COOKIE(クッキー変数)ではなく$_SESSION(セッション変数)で実装する場合。
履歴ページのID配列をクライアント側のクッキーではなく、サーバー側のセッションファイルに保持する。
global $his_posts;
$expire = 60*60*24*30;
if(session_status() === PHP_SESSION_NONE){
@session_start([
'gc_maxlifetime' => $expire,//セッションの有効期限上書き
'cookie_lifetime' => $expire,//クッキーの有効期限上書き
]);
}
if(is_single()){
$post_id = $post->ID;
$his_num = 5;
$his_posts = explode(',', $_SESSION['ag2history']);
if(in_array($post_id, $his_posts)){
$his_posts = array_values(array_diff($his_posts, array($post_id)));
}
if(count($his_posts) >= $his_num){
$his_posts = array_slice($his_posts , 0, ($his_num - 1));
}
array_unshift($his_posts, $post_id);
$_SESSION['ag2history'] = implode(',', $his_posts);
}else{
if(isset($_SESSION['ag2history'])){
$his_posts = explode(',', $_SESSION['ag2history']);
}else{
$his_posts = false;
}
}
セッションファイルを削除したい場合
//セッション変数の任意のキーを削除
unset($_SESSION['キー']);
//空の配列を代入してセッション変数の全てのキーを削除
$_SESSION = [];
//セッションファイルを削除
session_destroy();
//クライアント側でクッキーが保持しているセッションIDを削除
//キー(セッション名):値(セッションID)
setcookie(session_name(), '', time()-1, '/');
session_name() : セッション名を取得。デフォルトのセッション名はPHPSESSID。
テンプレートで履歴を表示
履歴ページIDの配列を保持しているグローバル変数を呼び出して、出力したい場所で’post__in’でループ処理をする。
//履歴があれば表示
global $his_posts;
if($his_posts != false){
$ag2args = array(
'posts_per_page' => -1,
'post__in' => $his_posts,
'orderby' => 'post__in',
);
$ag2query = new WP_Query($ag2args);
if($ag2query->have_posts()):
while($ag2query->have_posts()):
$ag2query->the_post();
//ループ処理
endwhile;
endif;
wp_reset_postdata();
}
https://memo.ag2works.tokyo/post-982/
PHPの$_COOKIE(クッキー変数)または$_SESSION(セッション変数)でWordPressに閲覧履歴を表示。 | memo メモ [AG2WORKS]
<a href="https://memo.ag2works.tokyo/post-982/" target="_blank" rel="noopener">PHPの$_COOKIE(クッキー変数)または$_SESSION(セッション変数)でWordPressに閲覧履歴を表示。 | memo メモ [AG2WORKS]</a>
この記事へのコメント
コメントの書き込みはまだありません。