質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

5547閲覧

PHPでCookieを使用した値の追加と削除について教えて下さい!

miconear

総合スコア31

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

2クリップ

投稿2015/03/23 16:28

PHPを最近始めたばかりの初心者です。
ご教授の程、どうぞ宜しくお願い致します!m(__)m

早速ですが、商品一覧のページを作成しました。
下記のように商品毎にそれぞれ「お気に入り追加」というアンカーを設置しています。

lang

1<!-- index.php --> 2 3<ul> 4 <li>商品1</li> 5 <li><a href="favorite.php?keep_in=10001">お気に入り追加</a></li> 6 <li>商品2</li> 7 <li><a href="favorite.php?keep_in=10002">お気に入り追加</a></li> 8 . 9 . 10 . 11</ul>

「お気に入り追加」をクリックするとCookieに商品IDを追加して行き、
もう一度「お気に入り追加」をクリックで商品IDを削除するにはどうしたら良いでしょうか?

setcookieで配列にして記憶させておいて、再度「お気に入り追加」をクリックで keep_in と同じ値が既にCookieにある場合は、該当する配列を削除する様にしたら良いのでしょうか?

lang

1// favorite.php 2 3if (isset($_GET['keep_in'])) { 4 $value = $_GET['keep_in']; 5 setcookie("KeepID[$value]", $value, time()+60*60*24*30, "/"); 6}

お気に入り追加を行った商品の保存期間は30日として設定しています。

後々やりたいことになりますが、Cookieで記録した配列はPDOでプレースホルダーにして
MySQLで商品詳細として抽出し表示したいと思っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

シリアライズすれば良いと思います。

lang

1$keeplist[$value] = $value; 2setcookie("keeplist", serialize($keeplist), time()+60*60*24*30, "/");

取り出すときはデシリアライズします。

lang

1$keeplist = unserialize($_COOKIE["keeplist"]);

例外処理とか無視した最小限で書くと下記のような感じです。

lang

1<?php 2$keeplist = array(); 3 4if (isset($_COOKIE['keeplist'])) { 5 $keeplist = unserialize($_COOKIE["keeplist"]); 6} 7 8if (isset($_GET['keep_in'])) { 9 $value = $_GET['keep_in']; 10 if (isset($keeplist[$value])) { 11 unset($keeplist[$value]); 12 } else { 13 $keeplist[$value] = $value; 14 } 15 16 setcookie("keeplist", serialize($keeplist), time()+60*60*24*30, "/"); 17} 18 19var_dump($keeplist);

コメントにもある通り、クッキーのような外部からくる値を unserialize するのは危険なので json_encode/json_decode を使うほうが良いです。

投稿2015/03/24 00:35

編集2018/02/06 00:35
ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miconear

2015/03/24 09:45

ngyuki様、ご回答ありがとうございます! シリアライズという便利な関数があるのですね。 早速、回答頂いた様にシリアライズ後、デシリアライズして print_r($keeplist) で配列の内容を確認しましたら追加した配列が上書きになってしまい、最後にお気に入りに追加した商品IDのみ表示されます。 追加したIDを配列で保持していきたいのですがどのようにしたら良いでしょうか? お忙しいところ申し訳ございません。 ご回答の程、宜しくお願い致します。
ngyuki

2015/03/24 14:57

デシリアライズはコード上ではシリアライズの前に行う必要がありますが、順番を逆にしていないでしょうか?
ngyuki

2015/03/24 14:59

追記しました
ngyuki

2015/03/24 15:03

質問を少し勘違いしていたのでさらに修正しました
miconear

2015/03/25 10:50

ngyuki様、再度ご回答いただきまして有難う御座います! 期待通りに動作致しました。 有難う御座います。m(__)m ソースもスッキリしていてとてもわかり易かったです。 こちらお気に入りに追加後の動作なのですが、画像再読み込み等による煩わしさを無くしたいのでページ遷移を軽減するためiframeで行うことにしました。 【index.html】 <li><iframe src="/include/sp/favorite.php?set_id=10001" width="100%" height="52" style="float:right;"></iframe></li> <li><iframe src="/include/sp/favorite.php?set_id=10002" width="100%" height="52" style="float:right;"></iframe></li> <li><iframe src="/include/sp/favorite.php?set_id=10003" width="100%" height="52" style="float:right;"></iframe></li> 【favorite.php】 <?php $keeplist = array(); if (isset($_COOKIE['keeplist'])) { $keeplist = unserialize($_COOKIE["keeplist"]); } if(isset($_GET['keep_in'])) { $value = $_GET['keep_in']; if (isset($keeplist[$value])) { unset($keeplist[$value]); } else { $keeplist[$value] = $value; } setcookie("keeplist", serialize($keeplist), time()+60*60*24*30, "/"); } else { // iframe読み込み時に商品IDを取得する $keep_in = $_GET['set_id']; } include_once(dirname(__FILE__).'/favorite.tpl'); ?> 【favorite.tpl】 <?php if(isset($_GET['set_id'])): ?><!-- iframeから商品IDを取得 --> <li><a href="/favorite.php?keep_in=<?php echo $keep_in; ?>" class="off">お気に入り</a></li> <?php else: ?><!-- お気に入りをクリックした時 --> <li><a href="/favorite.php?keep_in=<?php echo $keep_in; ?>" class="on">お気に入り</a></li> <?php endif; ?> ページをリロードさせない為にiframeを使用していますが他に良い方法がありましたらご教授頂けないでしょうか? 又、同じページの最下部に「お問合せ」というアンカーリンクを設置し お問合せ入力フォームへ遷移してお気に入りに追加したクッキーの配列を取得したいのですがその際は下記のように行うと宜しいでしょうか? if (isset($keeplist)) { foreach ($keeplist as $val) { echo $val; } } 何度も申し訳ございません。 どうぞ宜しくお願い致します。
miconear

2015/03/26 02:35

昨日記述したコメントの件ですが解決することが出来ました。 プログラムの流れやCookieの仕組みを理解できていたらスムーズにいきそうですね。 ベストアンサーありがとうございます。
ngyuki

2015/03/26 09:31

確かに `unserialize($_COOKIE["keeplist"]);` はものすごい脆弱性になりかねないのでやらない方がいいです。
miconear

2015/03/26 13:23

ArimaRyunosuke様、ngyuki様、補足コメントありがとうございます。 早速、参考URLを拝見しました。 将来、脆弱性になりかねないですね・・・(汗) jsonで代替するとなると、このようにして使用したら良いでしょうか? 誤)setcookie("keeplist", serialize($keeplist), time()+60*60*24*30, "/"); 誤)$keeplist = unserialize($_COOKIE["keeplist"]); 正)setcookie("keeplist", json_encode($keeplist), time()+60*60*24*30, "/"); 正)$keeplist = json_decode($_COOKIE["keeplist"]);
ngyuki

2015/03/27 00:45

実際にやってみればわかると思いますが json_decode の第2引数に true を指定しないと stdClass になってしまうので上手く動きません
miconear

2015/03/27 14:04

ngyuki様 再補足ありがとうございます! true有りで配列ということですね。 最終的にこうなりました。 $keeplist = json_decode($_COOKIE["keeplist"], true);
guest

0

ごめん、余計なことした、cookie のときは [] 使えないんだね

lang

1 if( isset( $_GET[ 'keep_in' ] ) ) { 2 if( array_key_exists( 'KeepID', $_COOKIE ) && ( $p = array_search( $_GET[ 'keep_in' ], $_COOKIE[ 'KeepID' ] ) ) !== false ) { 3 // Delete value from cookie. 4 setcookie("KeepID[{$p}]", '', time() - 3600, '/'); 5 unset($_COOKIE['KeepID'][$p]); 6 } else { 7 // Add value in cookie. 8 $value = $_GET[ 'keep_in' ]; 9 setcookie("KeepID[{$value}]", $value, time() + 2592000 /*60*60*24*30*/, '/'); 10 } 11 } 12 13 var_dump( $_COOKIE );

投稿2015/03/25 19:21

miya

総合スコア81

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miconear

2015/03/26 02:44

ご回答ありがとうございます。m(__)m Cookieの場合は[]配列記述が使用できないのですね。 必ず配列キーを設定しなくてはいけないのですね(^o^; array_key_exists()やarray_search()は様々なシーンで使えそうですね。 miya様、ngyuki様 御二方のご教示により上手く解決することが出来ました。 両者ともベストアンサーにしたいのですがシステム上、それは無理そうですね?(^o^; 今回はシンプルな方法をご教示頂いたngyuki様をベストアンサーにしたいと思います。(miya様、大変申し訳ございませんm(__)m) setcookie("KeepID[{$value}]", $value, time() + 2592000 /*60*60*24*30*/, '/'); 最後に気になったのですが こちらのsetcookieで有効期間が60*60*24*30の答えが秒数で記述されていますが 答え(2592000)を記述することによって処理速度も向上するのでしょうか?
guest

0

ごめんなさい、逆でした

lang

1array_search( $_GET[ 'keep_in' ], $_COOKIE[ 'KeepID' ] )

setcookie で表示されたエラーは、array_search のエラー出力が原因です。

投稿2015/03/24 13:05

miya

総合スコア81

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miconear

2015/03/25 10:51

再度ご回答有難う御座います!(^^) 下記のようにif(isset($_COOKIE['KeepID']) してクッキーがセットされているか分岐させてみました。 // お気に入りクリック if(isset($_GET['keep_in'])) { // クッキーがセットされているか if (isset($_COOKIE['KeepID'])) { if(array_key_exists($_GET['keep_in'], $_COOKIE['KeepID']) && ($p = array_search($_GET['keep_in'], $_COOKIE['KeepID'])) !== false) { echo $ke = array_search($_GET['keep_in'], $_COOKIE['KeepID']); // Delete value from cookie. setcookie("KeepID[{$p}]", '', time() - 3600, '/'); unset($_COOKIE['KeepID'][$p]); } else { // Add value in cookie. setcookie('KeepID[]', $_GET['keep_in'], time() + 2592000 /*60*60*24*30*/, '/'); } } else { // Add value in cookie. setcookie('KeepID[]', $_GET['keep_in'], time() + 2592000 /*60*60*24*30*/, '/'); } } 早速、「お気に入り追加」を下記の順番でクリックしていきました。 【HTML】 <a href="/favorite.php?keep_in=10001">お気に入り</a> <a href="/favorite.php?keep_in=10002">お気に入り</a> <a href="/favorite.php?keep_in=10003">お気に入り</a> <a href="/favorite.php?keep_in=10004">お気に入り</a> 10004~10004迄それぞれクリックして、foreach文で配列から取り出して確認してみましたら10004のみしか取り出せませんでした。 foreach ($_COOKIE["KeepID"] as $value) { echo $value . "<br>"; } 10001 10002 10003 10004 と言う様にクリックした分を配列に追加して 再度同じ番号がクリックされたら該当する番号を削除したいです。 すみません、何度もお手数かけますが どうぞ宜しくお願い致します!m(__)m
guest

0

lang

1if ( isset( $_GET[ 'keep_in' ] ) ) { 2 if ( ( $p = array_search( $_COOKIE[ 'KeepID' ], $_GET[ 'keep_in' ] ) ) !== false ) { 3 // Delete value from cookie. 4 setcookie( "KeepID[{$p}]", '', time() - 3600, '/' ); 5 unset( $_COOKIE[ 'KeepID' ][ $p ] ); 6 } else { 7 // Add value in cookie. 8 setcookie( 'KeepID[]', $_GET[ 'keep_in' ], time() + 2592000/*60*60*24*30*/, '/' ); 9 } 10}

KeepID[] = ~ ってすると自動で連番振って新しい要素追加してくれる。
お気に入りとかもデータベース管理したほうがいいと思うけど、登録とかしなきゃいけなくなるからね
俺なら場合によっては登録以外の方法取るけど

投稿2015/03/24 10:05

編集2015/03/24 10:14
miya

総合スコア81

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miconear

2015/03/24 12:16

miya様、ご回答ありがとうございます! 早速、miya様の方法で記述してみたところ下記のエラーが表示されてしまいました。 【HTML側】 <html> <head> <body> <a href="/favorite.php?keep_in=10001">お気に入り</a> <a href="/favorite.php?keep_in=10002">お気に入り</a> </body> </html> 【PHP側】 <?php if ( isset( $_GET[ 'keep_in' ] ) ) { if ( ( $p = array_search( $_COOKIE[ 'KeepID' ], $_GET[ 'keep_in' ] ) ) !== false ) { // Delete value from cookie. setcookie( "KeepID[{$p}]", '', time() - 3600, '/' ); unset( $_COOKIE[ 'KeepID' ][ $p ] ); } else { // Add value in cookie. setcookie( 'KeepID[]', $_GET[ 'keep_in' ], time() + 2592000/*60*60*24*30*/, '/' ); } } ?> ▼ 下記エラーになります。 if ( ( $p = array_search( $_COOKIE[ 'KeepID' ], $_GET[ 'keep_in' ] ) ) !== false ) { この行で下記のエラーが表示されました。 「Notice: Undefined index: keepID in~..」 「Warning: array_search() expects parameter 2 to be array, string given in~..」 setcookie( "KeepID[{$p}]", '', time() - 3600, '/' ); こちらの行で下記のエラーが表示されました。 「Warning: Cannot modify header information - headers already sent by (output started at~..」
miya

2015/03/24 13:08

あ、ここに書けばいいのかw ついでにもう少し修正 ```lang-<PHP> if ( isset( $_GET[ 'keep_in' ] ) ) { if ( is_array( $_COOKIE[ 'KeepID' ] ) && ( $p = array_search( $_COOKIE[ 'KeepID' ], $_GET[ 'keep_in' ] ) ) !== false ) { // Delete value from cookie. setcookie( "KeepID[{$p}]", '', time() - 3600, '/' ); unset( $_COOKIE[ 'KeepID' ][ $p ] ); } else { // Add value in cookie. setcookie( 'KeepID[]', $_GET[ 'keep_in' ], time() + 2592000/*60*60*24*30*/, '/' ); } } ``` あのままだと一発目コケるからね
miya

2015/03/24 13:13

is_array( $_COOKIE[ 'KeepID' ] ) ⇒ array_key_exists( 'KeepID', $_COOKIE ) か
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問