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

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

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

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

Q&A

解決済

1回答

8350閲覧

ブラウザを閉じても$_SESSIONが残る

SugiuraY

総合スコア318

PHP

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

0グッド

1クリップ

投稿2021/06/18 06:24

編集2021/06/18 09:53

php

1if ($login_user) { 2 session_start(); 3 $_SESSION['user']=$login_user; 4}else{ 5 $_SESSION['user']=false; 6} 7 8if($_SESSION['user']){ 9 echo $_SESSION['user']); 10}

上記のように$login_usertrueの場合に$_SESSION['user']にuser名が格納して処理させる基本的なコードを想定しております。

ここでマニュアルを読んでも具体的な使用があまり、わからなかったため、こちらの参考記事を拝見すると$_SESSIONはブラウザを閉じるまで保持されると記載がありました。(具体的には載っていないですが、当然unset等で変数を破棄した場合も同様かと存じます)

さて、ここで試しに上記のコードでecho $_SESSION['user']); で適切に出力されていることを確認できたのちに、ブラウザを閉じて再度同じページを開いた際に、また同じ出力が発生し、破棄されていないことが判明しました。

[環境等について]
0. php.iniにおけるsession.cookie_lifetimeは0に設定されています。

  1. PHPは7.3.8を使用
  2. OSはmacOS Catalina 10.15.7(上記のブラウザの閉じるは×ボタンだけではなく、ツールバー状のGoogleChromeの終了まで実行しております)
  3. ブラウザはGoogle Chrome 91.0.4472.106(Official Build) (x86_64)

を利用しております。参考記事に誤りがあるのでしょうか?

追記
iniに関連する設定です。コメントアウト部分は文字数オーバーのため削除しました。

php

1//php.ini 2[Session] 3session.save_handler = files 4session.save_path = /Applications/MAMP/tmp/php 5session.use_strict_mode = 0 6session.use_cookies = 1 7session.use_only_cookies = 1 8session.name = PHPSESSID 9session.auto_start = 0 10session.cookie_lifetime = 0 11session.cookie_path = / 12session.cookie_domain = 13session.cookie_httponly =r 14session.serialize_handler = php 15session.gc_probability = 1 16session.gc_divisor = 100 17session.gc_maxlifetime = 1440 18session.referer_check = 19session.cache_limiter = nocache 20session.cache_expire = 180 21session.use_trans_sid = 0 22session.sid_length = 26 23session.trans_sid_tags = "a=href,area=href,frame=src,form=" 24session.sid_bits_per_character = 5

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

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

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

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

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

m.ts10806

2021/06/18 06:36

他にもsessionに関する設定項目はありますが、それぞれどうなっていますか?
SugiuraY

2021/06/18 07:27

ありがとうございます、項目というのは、php.ini上の設定で正しいでしょうか?
SugiuraY

2021/06/18 09:53

本文に追記させていただきました。よろしくお願い申し上げます。
guest

回答1

0

ベストアンサー

ブラウザ側の機能でセッションを維持することが出来るため、ブラウザによっては(chromeやfirefoxはそうだったような)session.cookie_lifetime=0によるセッションの切断は意図したとおりに動作しません。

MDN 開発者向けのウェブ技術>HTTP>HTTP ヘッダー>Set-Cookie

ディレクティブExpires=<date>のあたりを参照

警告: 多くのウェブブラウザーはセッション復元と呼ばれる機能を持っており、これによってすべてのタブを保存し、次回ブラウザーを起動したときに復元することができます。ブラウザーを実際には閉じていないかのように、セッションクッキーも復元されます。

投稿2021/06/18 06:34

編集2021/06/18 13:16
tanat

総合スコア18716

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

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

SugiuraY

2021/06/18 07:26

ありがとうございます。 サーバーサイド言語側で当該Cookie項目を調整することは可能なのでしょうか? 実際にはブラウザを閉じればSessionを必ず破棄して欲しいという仕様を絶対とはしていないのですが、想定していない動きがしているので、疑問に感じている次第です。。
tanat

2021/06/18 07:44

サーバからするとブラウザが閉じたことを検知する手段は存在しない(ブラウザを閉じずに再度アクセスされたのか、ブラウザが閉じられたがブラウザ側のセッション維持機能によって閉じたことが隠蔽されたのか区別がつかない)ので難しいかと思いますよ。 セッションの寿命を短くするとか、 アプリケーション的にJavaScriptで定期的に通信を発生させ、JavaScriptが動作しない時間(タブが非アクティブだったり、ブラウザが閉じられたり)が長く続いたら次のアクセスがあったタイミングでタイミングでアプリケーション的にセッションを破棄したりすると言った対応が必要になると思います。
Y.H.

2021/06/18 07:46

WindowsのChromeで常駐機能を利用していると、 ChromeのWindowを閉じて終了しているつもりでも Chromeが常駐しておりセッションが維持されるという場合もありますね。
tanat

2021/06/18 08:33

> Y.H.さん 補足ありがとうございます。 そうなんですよね。 ブラウザ側が色んな手段で生き残るのでどうしてもサーバや言語の設定というよりはアプリケーション的に対応が必要になってしまいますね。
SugiuraY

2021/06/18 13:20 編集

tanat様、Y.H.様 コメントありがとうございます。少し、話が遡ってしまうのですが、ユーザーログインを実装しようと思う場合、通常は$_SESSIONだけでコントロールするものなのでしょうか?もしその場合にはlife_timeを設定すれば逆にブラウザを閉じても一定期間コントロールできるようにお見受けしたのですが、 「アプリケーション的に対応」という表現が理解できず、サーバーサイドを超えたより広範な知識が実装には必要になるのかと懸念しております。 例えば、本サービスteratailのログイン機能を利用者として観察しているとブラウザを閉じてもしばらくの期間はsessionが生きているように思えます。これはサーバーサイドで$_SESSIONだけでコントロールしているのか推察がつかず、興味を持っております。 もちろん、セキュリティ等を含めた要件次第ではあると思っているのですが、PHP初級記事ではとりあえずsessionを利用したログインに実装ばかりにフォーカスされており、現在実務的にそれで十分なのか等を含めてお尋ねさせていただいた次第です。
tanat

2021/06/18 11:16

> コメントありがとうございます。少し、話が遡ってしまうのですが、ユーザーログインを実装しようと思う場合、通常は$_SESSIONだけでコントロールするものなのでしょうか? 「通常」の定義次第ですが、一番シンプルな形だと$_SESSIONだけで管理するという実装で間違いないです。 > もしその場合にはlife_timeを設定すれば逆にブラウザを閉じても一定期間コントロールできるようにお見受けしたのですが、 「アプリケーション的に対応」という表現が理解できず、サーバーサイドを超えたより広範な知識が実装には必要になるのかと懸念しております。 「アプリケーション的に」=「PHPでセッション管理クラスを作って、$_SESSIONの操作を様々な要件でコントロールする」くらいの意味合いでのコメントです。 例えば業務で使うwebアプリがあったとして、 「営業時間外には使用できない」という要件があった場合は、 営業終了直前にログインしたとしても、営業時間が過ぎたら強制的にセッションを破棄するような仕組みが必要になります。 それをphp.iniの設定だけで実装するのは無理なので、セッションを管理するクラスをPHPで作って現在の時間が営業時間外になったら既にあるセッションでも破棄するような仕様を実装します。 と言う感じです。 > 例えば、本サービスteratailのログイン機能を利用者として観察しているとブラウザを閉じてもしばらくの期間はsessionが生きているように思えます。これはサーバーサイドで$_SESSIONだけでコントロールしているのか推察がつかず、興味を持っております。 teratailの場合、別のデバイスやIPでログインした場合に古い方のセッションが削除されるような挙動をするので(詳細な仕様までは把握していませんが)何らかの方法でアプリケーション的に管理をしていると思いますよ。 > もちろん、セキュリティ等を含めた用件次第ではあると思っているのですが、PHP初級記事ではとりあえずsessionを利用したログインに実装ばかりにフォーカスされており、現在実務的にそれで十分なのか等を含めてお尋ねさせていただいた次第です。 セッション管理の独自実装は脆弱性を作り込みやすいので、 実業務ではフレームワークやライブラリの提供するセッション管理クラスをそのまま使ったり拡張することが多いです。 が、学習目的であれば、前述の様な感じの要件を設定してみて、それを再現するようなセッション管理クラスを作ってみる というのは勉強になると思いますよ。
SugiuraY

2021/06/18 11:53

詳細、ご教示ください誠にありがとうございます。 当初の問題は、firefoxで実行してみたところ、問題がなかったため、ご指摘の通り、ブラウザに依存している問題である可能性と当たりをつけました。ディレクティブという点について、少し調べてみようと思います。(ご回答いただいたのに厚かましいのですが、回答本文の文章に文脈のつながりがない箇所があるため、可能であれば後学のために、ご修正いただけますと幸いです) また、sessionを利用したログイン機能の実装については、おかげさまで少しゴールが見えてきました。まだ、私自身はsessionやブラウザ側のcookieの仕組をはっきり理解できていないのですが、ご指摘の通り、まず一から自分で実装してみて咀嚼をしてから、実際の導入にあたってはライブラリ等の利用を検討してみたいと思います。 改めて、ありがとうございます。
tanat

2021/06/18 13:21

> (ご回答いただいたのに厚かましいのですが、回答本文の文章に文脈のつながりがない箇所があるため、可能であれば後学のために、ご修正いただけますと幸いです) あ、回答の途中が途切れてましたね。 ご指摘ありがとうございます。 修正しました。(編集画面では修正後の状態に最初からなっていたので、teratailの不具合だったのかも?) 「ディレクティブ」は「(設定の)分類」くらいの意味合いです。 他のアプリケーションやサーバの設定ファイルでよく出てくる表現ですね。 この場合は、レスポンスヘッダ「set-cookie」において指定できる項目を意味します。
SugiuraY

2021/06/18 13:21

ご修正、ありがとうございます。 私も質疑応答中の誤字脱字を修正いたしました。。。 よろしくお願い申し上げます。
SugiuraY

2021/06/18 13:24

ディレクティブのニュアンス・イメージが掴めなかったので、コメントありがたいです。 あたりをつけて早速調べて、手を動かしてみます!
SugiuraY

2021/06/18 13:32

申し訳ございません。 >レスポンスヘッダ「set-cookie」において指定できる項目 これはMDNのドキュメント->Set-Cookie->構文にあるような話だと思うのですが、ブラウザ上で指定するものなのでしょうか・・・ Set-Cookie: <cookie-name>=<cookie-value> Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date> Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit> Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value> Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value> Set-Cookie: <cookie-name>=<cookie-value>; Secure Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax Set-Cookie: <cookie-name>=<cookie-value>; SameSite=None // 以下の例のように、複数のディレクティブも利用することができます。 Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
tanat

2021/06/18 13:53

レスポンスヘッダはブラウザ上で指定するものでは無く、サーバ側で設定し、ブラウザに対して送信するものです。 (ブラウザはそのレスポンスヘッダを解釈する役割です。) Chromeの場合、開発者ツールでレスポンスヘッダを確認することが出来るので、サーバの設定を変更しながら確認すると分かりやすいです。 (確認方法は開発者ツール レスポンスヘッダあたりで調べてみてください)
SugiuraY

2021/06/19 15:37

コメントをお寄せいただき、ありがとうございます。 Chromeでの見方は調べることができました!サーバーサイドでどのように設定するのか引き続き調べてみます。初歩的な点に至るまで、ご助言をいただき大変助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問