Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
セッションで遊んでみた
Search
gallu
February 28, 2024
Technology
79
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
セッションで遊んでみた
gallu
February 28, 2024
More Decks by gallu
See All by gallu
日付四方山話
gallu
0
79
Slimをオススメしてみる ディレクトリ構造
gallu
0
600
Slimをオススメしてみる ControllerとContainer
gallu
0
390
20230315のPHP勉強会(Slimをオススメしてみる)
gallu
0
280
20230215PHP勉強会.pdf
gallu
0
71
PHP 来歴のトリヴィア
gallu
0
130
HTTPを振り返ってみる
gallu
0
65
Other Decks in Technology
See All in Technology
「守りたい体験」を渡すだけで E2E を生成させられるようになった話
hinac0
2
1k
Multicaで30個のミニプロジェクトをAIエージェント運用して見えてきたこと
eiei114
1
620
探索・可視化・自動化を一本化 Amazon Quickでデータ活用スピードを上げる方法
koheiyoshikawa
0
170
AI時代の開発生産性を捉え直す — 経営と現場をつなぐ「開発組織のオブザーバビリティ」— / AI Dev Ex Conference 2026
tkyowa
1
1.3k
AI時代におけるエンジニアの新たな役割──FDEとクオリアの探求/登壇資料(戸井田 裕貴)
hacobu
PRO
0
310
文字起こし基盤の信頼性
abnoumaru
0
120
「休む」重要さ
smt7174
6
1.6k
キャリアLT会#3
beli68
2
240
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.5k
そのドキュメント、自動化しませんか?
yuksew
1
410
複数プロダクト組織のAIネイティブ化における戦略 / AICon2026_kude
rakus_dev
0
300
AI時代のPlaywright活用(システムテストを自動化する ー 実行エンジンにPla ywrightを選んだ理由)
ynisqa1988
2
930
Featured
See All Featured
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.5k
Building Adaptive Systems
keathley
44
3.1k
Chasing Engaging Ingredients in Design
codingconduct
0
240
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
220
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.7k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Prompt Engineering for Job Search
mfonobong
0
380
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
3
360
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.7k
Abbi's Birthday
coloredviolet
3
8.8k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Transcript
セッションで遊んでみた by がる
自己紹介 古庄と申します 「がる(gallu)」というハンドルでふらついております 本職は技術者です。現役プログラマーやってます バックエンド系なので、インフラとかDBとかも一通り
最近はPM業も多いですねぇ あわせて、教育とか色々
Slimいいよ!! PHPセッション楽しいよ! 「PHPのセッションサポート機能」(ってマニュアルに書い てある)、お世話になっている人も多いのではないか? と 思われます Laravel使うと「Laravelのセッション」なのであんまり……という 人もいるかと思いますがキニスンナ
普通に使う分には割と慣れっこな気がしますが、「ちょっ と奇妙な事」も割と耐えられるので、そんなこんなを見て いきましょう!! お題は3つ。5分なんでサクサクいきます(笑
前提) セッションって? 大雑把には「ステートレスなHTTPで、ステートを保存す る」用途のあんなこんな Cookieと似てる Cookieは「RFCで定義された」機能
昔は「ネスケが提案実装した」localだったんですけどねぇ 2000年に出てるRFC 2965には出てきているので、まぁ古参 セッションは「共通の定義はない」 のでまぁ「どの」セッションか? でいろいろとお話が変わる 今回は「PHPという言語が提供しているセッション処理 https://www.php.net/manual/ja/book.session.php 」
Cookieとセッションの大まかな違い データの置き場所 Cookieは「HTTPのリクエストとレスポンス」の通信でやりとりし て、データはユーザ側に保存されます セッションは「どこにあるかは実装次第」。でもまぁサーバ上に あることが「多い」かなぁ
データ量の制限とか Cookieが保証しているのは「Cookieごとに少なくとも4096バイ ト」「ドメインごとに少なくとも50のCookie」「合計で少なくとも 3,000のクッキー」 by RFC 6265 セッションは「実装次第」。Cookieよりは多い事が多いと思う
本題1) 複数ドメインで同じセッション ニーズ ゲーム作ってるんですが(過去のリニューアル込みで) www.example.com でメインのユーザ管理
game1.example.com とか game2.example.com とかでそれぞれ個別 にゲーム 全体で「同じユーザ」として管理したい けどまぁ開発の都合もあって、ドメインは切り分けたい ので「wwwでユーザ登録しぃの、ログインしてもらいぃの」 した後で「個々のゲームを楽しんでもらいたい」 認可情報は「セッションに入れる(事が多い)」から、まぁ「違うド メインで同じセッション使えると具合がよいなぁ」と
大まかな実装指針 session_set_cookie_params() 関数つかって「domainを指 定する」 今回の場合 example.com を対象ドメインにする
後は普通にセッションを開始して書いたり読んだりする かいつまんでいくつかコードを書いておきます 後で資料公開するのでその時に落ち着いて読んでください(笑 Blogにもうちょっと詳細がありますので、こちらもよかったら https://gallu.hatenadiary.jp/entry/2024/02/13/174635
コード(一部) common.php <?php // common.php declare(strict_types=1); // ob_start(); //
ざっくりセッション設定 session_set_cookie_params([ 'lifetime' => 0, 'samesite' => 'Strict', // 'secure' => true, // テスト環境なのでhttpsになってないからコメントアウト 'httponly' => true, 'domain' => 'example.com', ]); ini_set('session.use_strict_mode', 1); // セッション開始 session_start();
<?php // hoge/read.php, foo/read.php declare(strict_types=1); require __DIR__ . '/../common.php'; //
セッション情報の表示 var_dump($_SESSION); var_dump(session_id()); <?php // hoge/write.php declare(strict_types=1); require __DIR__ . '/../common.php'; // セッションへの書き込み $_SESSION['hoge'] = 'hoge value'; // echo 'ok'; <?php // foo/write.php declare(strict_types=1); require __DIR__ . '/../common.php'; // セッションへの書き込み $_SESSION['foo'] = 'foo value'; // echo 'ok';
結果(例) うんいけてるいけてる セッションIDが「同じ」なので、ちゃんと「同じセッション見てる」 事がわかる ゲーム保存データ本体はまた別のこと考えてますがチャンス があったらまたどこかで
http://hoge.example.com/read.php array(2) { ["hoge"]=> string(10) "hoge value" ["foo"]=> string(9) "foo value" } string(32) "f4a57c3d4dc2e0fe4f4fb4b167d4dcd2" http://foo.example.com/read.php array(2) { ["hoge"]=> string(10) "hoge value" ["foo"]=> string(9) "foo value" } string(32) "f4a57c3d4dc2e0fe4f4fb4b167d4dcd2"
余談) セッションとCookieのテスト方法 ブラウザの、シークレットモードとかプライベートブラウジ ングとか(火狐だとプライベートウィンドウ、Chromeだと シークレットウィンドウ)を使うと楽です 開いた瞬間、「まっさらな状態」からstartできるので 「全部のシークレットウィンドウを閉じる」とCookieも完全に消
えるので、またまっさらからテストし直せます ブラウザの開発ツール(F12)も便利なので積極的に使い ましょう! 先日、学校の生徒さんから「開発ツールで初めて通信のイ メージがついた」って言われたので、来年度は授業でももっと 積極的に使おうかと思ってます!!
本題2)セッションの寿命(GC)の実験 この辺割と「なんとなく」触っているので、実験してみたく なった ところでGCって…… ガベジコレクタ ?
ガベージコレクタ ? ガーベジコレクタ ? ガーベッジコレクタ ? 面倒だから「ジーシー」「ガベコレ」って言うことが増えた(笑
大まかな実装指針 5秒の寿命、1/1でGCされるように設定をする 通信レイテンシもあるけどまぁその辺込みで「ざっくり」確 認をしてみる
コード <?php declare(strict_types=1); error_reporting(-1); ob_start(); ini_set('session.gc_maxlifetime', 5); // 5秒 //
1/1の確率で破棄 ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 1); session_start(); echo "5秒を見切ってみましょう<br>¥n"; if (false === isset($_SESSION['time'])) { echo "一見さんですね?"; } else { $t = (hrtime(true) - $_SESSION['time']) / 1e9; echo "前回アクセスから {$t} 秒経過しています。¥n"; } $_SESSION['time'] = hrtime(true);
動かしてみた 一見さんですね? 前回アクセスから 1.859404099 秒経過しています。 前回アクセスから 4.374510851 秒経過しています。 前回アクセスから 10.326877074
秒経過しています。 一見さんですね? 前回アクセスから 0.69189565 秒経過しています。 前回アクセスから 4.530781299 秒経過しています。 前回アクセスから 5.74658378 秒経過しています。 一見さんですね? 前回アクセスから 5.400823442 秒経過しています。 前回アクセスから 3.952103308 秒経過しています。 前回アクセスから 6.470162867 秒経過しています。 一見さんですね?
タイムリミットのタイミングで「データ取得できるがGCが走 る」感じ コードを見ていないのですが、小数点以下はなんとなく「四捨 五入」っぽい感じ デフォルトが「1440 (24分)」「1/100 なので各リクエスト毎
に1%の確率でGCプロセスが始動」です 無操作時間をどれくらい許容するか? 次第ですが、必要 そうならちょっとだけ気にしておきましょう
本題3) Cookieでセッション 「おまえは何を言っているんだ」 セッションは「実装依存」です 実装によっては「いろいろな事ができます」 ので「セッション情報をCookieに入れる事だって」 「出来らあっ!」
コード class JokeSessionHandler implements SessionHandlerInterface { const COOKIE_NAME = "joke";
// 一部省略。省略メソッドは return true; 程度の実装 #[¥ReturnTypeWillChange] public function read(string $id) { return $_COOKIE[self::COOKIE_NAME] ?? ''; } public function write(string $id, string $data): bool { setcookie(self::COOKIE_NAME, $data); return true; } public function destroy(string $id): bool { setcookie(self::COOKIE_NAME, '', time() - 1); return true; } }
<?php declare(strict_types=1); ob_start(); class JokeSessionHandler implements SessionHandlerInterface { (略) }
session_set_save_handler(new JokeSessionHandler()); session_start(); var_dump($_SESSION); $_SESSION['rand'] = random_int(0, 9999); $_SESSION['rand2'] = random_int(0, 9999); $_SESSION['rand3'] = random_int(0, 9999); var_dump($_SESSION); var_dump( session_encode() );
結果 一回目 array(0) { } array(3) {
["rand"]=> int(6045) ["rand2"]=> int(9493) ["rand3"]=> int(5557) } string(38) "rand|i:6045;rand2|i:9493;rand3|i:5557;" Set-Cookie: joke=rand%7Ci%3A6045%3Brand2%7Ci%3A9493%3Brand3%7Ci% 3A5557%3B
二回目 array(3) { ["rand"]=> int(6045) ["rand2"]=> int(9493) ["rand3"]=>
int(5557) } array(3) { ["rand"]=> int(7301) ["rand2"]=> int(4857) ["rand3"]=> int(9676) } string(38) "rand|i:7301;rand2|i:4857;rand3|i:9676;" Cookie: PHPSESSID=3cec75116c097a73f89d52c5bfe78a13; joke=rand%7Ci%3A6045%3Brand2%7Ci%3A9493%3Brand3%7Ci% 3A5557%3B Set-Cookie: joke=rand%7Ci%3A7301%3Brand2%7Ci%3A4857%3Brand3%7Ci% 3A9676%3B
ちゃんと「Cookieに保存されたセッション」ができました!!! 多分、ほぼなんの用途もありませんが まぁ真面目な話「保存データを暗号化する」とかやれば、 うっすらと使い道がないわけでもなく write側で暗号化、read側で復号すればいい
「サーバ側の資源を使わない」のは、マジで割と強い Laravelにも「cookie」ってセッションの設定があるし もしかしたら、どこかで使える、かも? 「絶対にない」を言い切るのは難しいwww
まとめ 普段何気なく使ってる(と思う)セッションですが、ほかにも まだいろいろ関数もあったりして、掘っていくと割合に面 白いものです 「こんな必要が」から「面白い」までいろいろな角度で技 術を楽しんでいくと、きっと新しい学びがある、んじゃない か、と思います!!
多分ねw この戯言があなたの技術人生の彩りになれば幸いです