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

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

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

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

PHP

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

Q&A

解決済

2回答

1713閲覧

Cookie: ボタンを押すと履歴消去されるはずが、2度押さないと消去されない不具合について

miikan023

総合スコア3

Cookie

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

PHP

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

0グッド

0クリップ

投稿2021/06/23 04:30

編集2021/06/23 05:32

実現したいこと:アクセス履歴(アクセス数・ログインした日時)を表示、消去するページ。

発生している不具合:「履歴消去」ボタンを押すと、消去される代わりに更新(アクセス数追加、日付更新)されます。二回目にボタンを押すことで、やっと履歴が消去されます。

分からないところ:不具合の解決策 + なぜこのコードでは、一度のボタン操作で履歴を消すことができないのか。なぜ一回目にボタンを押す時は、逆に更新されてしまうのか。がわからないです。

※Cookieの学習を最近はじめたばかりで、理解ができていない面もあるので
お手柔らかにご回答をして頂けると幸いです。

<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Cookie_Practice</title> </head> <body> <?php $now = date('Y-m-d H:i:s'); $now_time = time(); if(!isset($_COOKIE['visit_count'])){ setcookie('visit_count', 1, $now_time + 3600); setcookie('visit_history', $now, $now_time + 3600); print '初めてのアクセスです'."<br>"; print '現在の日時は'.$now."<br>"; } else { $count = $_COOKIE['visit_count'] + 1; $visit_history = $_COOKIE['visit_history']; setcookie('visit_count', $count); setcookie('visit_history', $now); print '訪問回数は'.$count."<br>"; print '現在の日時は'.$now."<br>"; print '前回のアクセス日時は'.$visit_history."<br>"; } if(isset($_POST['delete_cookie'])){ setcookie('visit_count', '', $now_time - 3600); setcookie('visit_history', '', $now_time - 3600); } ?> <form method="POST" action="challenge_cookie.php"> <input type="submit" name="delete_cookie" value="履歴消去"> </form> </body> </html>

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

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

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

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

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

m.ts10806

2021/06/23 04:51

これはエラーと称するのは違うと思います。
miikan023

2021/06/23 05:00

エラー以外に言葉が見当たりませんが、エラーという言葉を消去して表記しなおします。
m.ts10806

2021/06/23 05:08

エラーは基本的に言語やコンパイラから出力されるもののことで、「作成者の想定通りの挙動にならない」は変更されたとおり「不具合」です。 それか、想定の挙動と実際の挙動をそのまま表記したほうが伝わります。 「ボタン押下で削除実行されるはずが、2度押さないと削除されない」とか。「エラー」「不具合」だけだと意味が広すぎるのが問題ですので。
miikan023

2021/06/23 05:18

エラーと不具合の違いを簡単にまとめて頂きありがとうございます。想定の動きとの違いに関しては、説明欄で記入していたのですが、タイトルにも具体性を持たせたほうが良かったかもしれませんね。以降質問時には注意したいと思います。
K_3578

2021/06/23 05:23

因みにタイトルに具体性を持たせた方が良いのは回答者が質問を開くかどうかはタイトルで判断されるからです。ヘルプページの質問するときのヒントにも書いてあります。 https://teratail.com/help/question-tips#questionTips3-1
miikan023

2021/06/23 05:28

リンクの共有をして頂きありがとうございます! さっそくタイトルを変更したいと思います。
K_3578

2021/06/23 05:31

今回は指摘を受けての事なので問題ないかと思いますが、回答が付いた後にタイトルや質問内容を 大きく変更すると、整合性が取れなくなることもあります。 基本的には回答が付いた後の質問文の変更は慎重に行うことを覚えておいてください。
miikan023

2021/06/23 05:34

整合性を確認した上で変更いたします。
guest

回答2

0

ベストアンサー

原因は二つあります。

一つ目の理由はsetcookie()で保存されたcookieをPHPが読み込める(=$_COOKIEに反映される)のは次回アクセス時であるためです。
(この仕様は感覚的には分かりにくいのですが、cookieの性質上仕方無いものなので、そういうものだと理解した上で対応が必要です)

例えば、以下のようなコードの場合、
初回アクセスからはカウントされずに2回目のアクセスからカウントが表示され、カウントは1から始まります(=2回目のアクセスなのに1が表示される)

PHP

1<?php 2if(!isset($_COOKIE['count'])){ 3 setcookie('count',1); 4}else{ 5 setcookie('count',$_COOKIE['count']+1); 6 echo $_COOKIE['count']; 7}

発生しているエラー:「履歴消去」ボタンを押すと、消去される代わりに更新(アクセス数追加、日付更新)されます。二回目にボタンを押すことで、やっと履歴が消去されます。

は、おそらくは正確では無く、
正確には履歴消去ボタンを押したあとにリロードやブラウザのURLを再度入力してのアクセスでもリセットされていると思いますので試してみてください。

二つ目の理由はとしては、

PHP

1 2 if(isset($_POST['delete_cookie'])){ 3 setcookie('visit_count', '', $now_time - 3600); 4 setcookie('visit_history', '', $now_time - 3600); 5 } 6

この部分が表示判定より後にあるためです。
これは一番最初に判定を動かす&削除した場合は新規作成を行う処理を実行しないような分岐が必要でしょう。

対処としては、

  • $_COOKIEを使わずに$_SESSIONを使い、ロジックの順番を見直す

もしくは

  • $_COOKIEの値をそのまま使うのではなく、setcookieによって値が変化させる時に判定に使用する変数も一緒に変化させる様な管理を行う。ロジックの順番も見直す

という感じになります。(cookieの学習目的の質問だと思うので前者は割愛します。)

後者は例えば

PHP

1<?php 2 3//$_COOKIE['count']を使うのはこの判定の中だけにして、以降は全て$countを使う 4 5if(!isset($_COOKIE['count'])){ 6 $count = 1; 7 setcookie('count',1); 8}else{ 9 $count = $_COOKIE['count']+1; 10 setcookie('count',$_COOKIE['count']+1); 11} 12 13echo $count; 14

という感じで、setcookieするタイミングでその後のソースで使用する変数も一緒に操作することで、
初回アクセス時からcookieの値を使えるようにします。
(実際には関数なりクラスに使いやすくまとめます。)

投稿2021/06/23 06:20

tanat

総合スコア18727

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

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

0

現在のロジックだと「現在保持している内容を出力してから消す」になっています。
消えてはいます。ただ、処理順が間違っています。
出力を伴わない処理はhtmlの出力より前に済ませるようにし、データの流れがどうなっているかを意識した実装を心がけましょう。
フローチャート書いてからコード書くと良いと思います。

投稿2021/06/23 04:54

m.ts10806

総合スコア80875

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

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

miikan023

2021/06/23 05:22

ご回答頂きありがとうございます。 仰って頂いた通り、履歴消去の部分だけHTMLの上に上げて書き直したのですが、今度は消去を全くしてくれなくなってしましました。。 もう少し「データの流れ」を意識して試行錯誤してみようと思います!!
m.ts10806

2021/06/23 05:27

「消去したあとどうするか」要件の決め次第かと思います。 今は「消去後初回アクセスとみなす」となってると思うので、消去後にまたsetしています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問