Laravel5.6のセッション管理をmemcachedでやる手順(2)
パート1はこちらからどうぞ。
Laravelのsessionドライバーをmemcachedにしようと思ったわけだが
あんなにいつも親切なLaravelのドキュメントに、
なんと、設定方法が載っていなかった。
なので、Laravelのフレームワークのコードを読んで設定したぜよ
というお話。
Laravel 5.6 のsessionドライバーでmemcachedを使う(Macローカルで実験)
.envをのSESSION_DRIVERを書き換える。
.env
SESSION_DRIVER=memcached
vendor/laravel/framework/src/Illuminate/Session/SessionManager.php これによると、cacheドライバーとセッションドライバーの設定は共通らしい。
sessionのconfigのstoreにcacheのstoreのキーを指定すればよいっぽい。
/** * Create an instance of the Memcached session driver. * * @return \Illuminate\Session\Store */ protected function createMemcachedDriver() { return $this->createCacheBased('memcached'); } /** * Create an instance of a cache driven driver. * * @param string $driver * @return \Illuminate\Session\Store */ protected function createCacheBased($driver) { return $this->buildSession($this->createCacheHandler($driver)); } /** * Create the cache based session handler instance. * * @param string $driver * @return \Illuminate\Session\CacheBasedSessionHandler */ protected function createCacheHandler($driver) { $store = $this->app['config']->get('session.store') ?: $driver; return new CacheBasedSessionHandler( clone $this->app['cache']->store($store), $this->app['config']['session.lifetime'] ); }
config/session.php
/* |-------------------------------------------------------------------------- | Session Cache Store |-------------------------------------------------------------------------- | | When using the "apc" or "memcached" session drivers, you may specify a | cache store that should be used for these sessions. This value must | correspond with one of the application's configured cache stores. | */ 'store' => 'memcached',
config/cache.php
/* |-------------------------------------------------------------------------- | Cache Stores |-------------------------------------------------------------------------- | | Here you may define all of the cache "stores" for your application as | well as their drivers. You may even define multiple stores for the | same cache driver to group types of items stored in your caches. | */ 'stores' => [ 'apc' => [ 'driver' => 'apc', ], 'array' => [ 'driver' => 'array', ], 'database' => [ 'driver' => 'database', 'table' => 'cache', 'connection' => null, ], 'file' => [ 'driver' => 'file', 'path' => storage_path('framework/cache/data'), ], 'memcached' => [ 'driver' => 'memcached', 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), 'sasl' => [ env('MEMCACHED_USERNAME'), env('MEMCACHED_PASSWORD'), ], 'options' => [ // Memcached::OPT_CONNECT_TIMEOUT => 2000, ], 'servers' => [ [ 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100, ], ], ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], ],
自分のMacにmemcachedをインストールして実験するため
localhostなので設定はこのままで大丈夫そうだ。
しかしリロードするとMemcachedはないと怒られた。
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR) Class 'Memcached' not found
https://laravel.com/docs/5.6/cache#memcached-cache
cacheのほうのドキュメントを読んでみると、Memcached PECL package をインストールしなさいよと書いてある。
pecl install memcached
peclでインストールしてみたがエラーが出た。
ERROR: `/private/tmp/pear/temp/memcached/configure --with-php-config=/usr/local/opt/php/bin/php-config --with-libmemcached-dir=no' failed
libmemcachedのインストールでコケているっぽいのでbrewインストールする。
brew install libmemcached
再度、実行したらインストールに成功。
zlibでエラー出る人はXcodeのアップデートか、再インストールが必要そう。
pecl install memcached . . Build process completed successfully Installing '/usr/local/Cellar/php/7.2.6/pecl/20170718/memcached.so' install ok: channel://pecl.php.net/memcached-3.0.4 Extension memcached enabled in php.ini
ちゃんと入っているので、phpをリスタートする。
php -i | grep memcached memcached memcached support => enabled libmemcached version => 1.0.18
sudo brew services stop php sudo brew services start php
保存されているかテストする
routes/web.php
Route::get('/', function () { session()->put('sample', 'beruko'); return view('welcome'); });
ここでデバッグするためにddとか書いてしまうとsessionが保存されないので、デバッグしたい気持ちをぐっとこらえる。
telnetに接続しmemcachedに保存されているか確認する
stats items STAT items:8:number 1
stats cachedump 8 1 ITEM beruko_sandbox_cache:uWTlfeZtpTUpHFAYfNR6nwycgA53gO0uZ1xg5nkp [273 b; 1529063998 s] END
get beruko_sandbox_cache:uWTlfeZtpTUpHFAYfNR6nwycgA53gO0uZ1xg5nkp VALUE beruko_sandbox_cache:uWTlfeZtpTUpHFAYfNR6nwycgA53gO0uZ1xg5nkp 0 273 a:5:{s:50:"login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d";i:2;s:9:"_previous";a:1:{s:3:"url";s:26:"http://beruko-sandbox.test";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:6:"_token";s:40:"BVVBUIbJE94ZCLpb71aTLtSQzNI15r7MUIGwLdjj";s:6:"sample";s:6:"beruko";} END
わーい♫ できたー
Laravel5.6のセッション管理をmemcachedでやる手順(1)
おっす、おらベル子。久しぶりのブログだぜっ!
最近、忙しくてイラストもまともに描けなくてストレスが溜まってるぜっ!
その代わり踊ってるんですが、踊りとイラストはまた別物なので、イラストを描く一人の時間がとにかく欲しいです。
昔から、好きなことに一人で没頭する時間がないと、快適に暮らしていてもストレスが徐々に溜まってきてしまうんですよね。
とにかく一人の時間を少し作って絵を描きたいです。
ということで本題です。
Laravel5.6のセッション管理をmemcachedでやりたい人向けの記事です。
「memcached、何それ美味しいの?」な人から手順どおりやれば、Laravelのセッションドライバーをmemcachedでやれるようになります。
具体的にどういうときにmemcached使ったほうがいいのかというと、
Webサーバ2台構成とかでセッションを共有しないといけないなどの際に
ローカルストレージのfileじゃセッションの共有ができないので、
memcachedでやるとかそういう感じです。
キーと値のペアをメモリ上に保持するKVSの一種でRedisのお友達なので、
memcachedじゃなくてRedisでもいいです。
というかむしろ特別な理由がなければRedisでもいい気がしました。
まず、パート1ではmemcachedとは何かと基本的な使い方を学び、Macローカルにmemcachedをインストールします。
memcachedについて
memcachedとRedisの違い
なるほどねー。
Macにmemcachedをインストールし、実行確認する手順
memcachedをbrewインストール
brew install memcached which memcached
自動起動させるコマンドと、起動コマンドを案内してくれた。 brewでインストールしたので以下のフルパスじゃなくてmemcachedって打てば使えそう。
To have launchd start memcached now and restart at login: brew services start memcached Or, if you don't want/need a background service you can just run: /usr/local/opt/memcached/bin/memcached
macOS High Sierraでtelnetを使えるようにする
https://qiita.com/samuraidays/items/b8a3d4a06e2c6c379865
brew install telnet
memcachedの起動オプション
オプション | 説明 |
---|---|
-p | 利用するTCPのポート。デフォルトは11211 |
-m | 最大のメモリーサイズ。デフォルトは64MB |
-vv | very verboseモードで起動してデバックメッセージやエラーをコンソールへ出力 |
-d | memcachedをデーモンとしてバックグラウンドで起動 |
-h | ヘルプを表示 |
telnet で接続
[~] telnet localhost 11211 Trying ::1... Connected to localhost. Escape character is '^]'.
バージョンの確認
version VERSION 1.5.8
ステータスの確認
stats STAT pid 3684 STAT uptime 96 STAT time 1529014973 STAT version 1.5.8 STAT libevent 2.1.8-stable STAT pointer_size 64 STAT rusage_user 0.020749 STAT rusage_system 0.016610 STAT max_connections 1024 STAT curr_connections 2 STAT total_connections 3 STAT rejected_connections 0 STAT connection_structures 3 STAT reserved_fds 20 STAT cmd_get 0 STAT cmd_set 0 STAT cmd_flush 0 STAT cmd_touch 0 STAT get_hits 0 STAT get_misses 0 STAT get_expired 0 STAT get_flushed 0 STAT delete_misses 0 STAT delete_hits 0 STAT incr_misses 0 STAT incr_hits 0 STAT decr_misses 0 STAT decr_hits 0 STAT cas_misses 0 STAT cas_hits 0 STAT cas_badval 0 STAT touch_hits 0 STAT touch_misses 0 STAT auth_cmds 0 STAT auth_errors 0 STAT bytes_read 16 STAT bytes_written 15 STAT limit_maxbytes 67108864 STAT accepting_conns 1 STAT listen_disabled_num 0 STAT time_in_listen_disabled_us 0 STAT threads 4 STAT conn_yields 0 STAT hash_power_level 16 STAT hash_bytes 524288 STAT hash_is_expanding 0 STAT slab_reassign_rescues 0 STAT slab_reassign_chunk_rescues 0 STAT slab_reassign_evictions_nomem 0 STAT slab_reassign_inline_reclaim 0 STAT slab_reassign_busy_items 0 STAT slab_reassign_busy_deletes 0 STAT slab_reassign_running 0 STAT slabs_moved 0 STAT lru_crawler_running 0 STAT lru_crawler_starts 510 STAT lru_maintainer_juggles 145 STAT malloc_fails 0 STAT log_worker_dropped 0 STAT log_worker_written 0 STAT log_watcher_skipped 0 STAT log_watcher_sent 0 STAT bytes 0 STAT curr_items 0 STAT total_items 0 STAT slab_global_page_pool 0 STAT expired_unfetched 0 STAT evicted_unfetched 0 STAT evicted_active 0 STAT evictions 0 STAT reclaimed 0 STAT crawler_reclaimed 0 STAT crawler_items_checked 0 STAT lrutail_reflocked 0 STAT moves_to_cold 0 STAT moves_to_warm 0 STAT moves_within_lru 0 STAT direct_reclaims 0 STAT lru_bumps_dropped 0 END
各項目の詳細
データをセット&ゲット
このへんを参考にデータをセットしたりゲットしたりしてみる。
set
# set key flags expiretime bytes set hoge 0 0 4 # value huga STORED
保存するbyte数が間違ってるとエラーが返ってくる
set hoge 0 0 4 laravel CLIENT_ERROR bad data chunk ERROR
get
get hoge VALUE hoge 0 4 huga END
ありもしないkeyを指定するとエラーは返ってこず、ただ終わる
get hogege END
なるほど、難しいことは何もない。 Redisと変わらなそう。
インクリメントとかデクリメントとか、コマンド間違えてみたりとか
set count 0 0 1 1 STORED
get count VALUE count 0 1 1 END
incr count 1 2
get count VALUE count 0 1 2 END
decr count 1 1
get count VALUE count 0 1 1 END
incr count 2 3
get count VALUE count 0 1 3 END
ありもしないキーを指定
decr count3 ERROR
存在しないコマンドを唱える
dect count 3 ERROR
なるほど、Redisと一緒ですね。
保存しているキーの一覧を表示
stats itemsと打って、items:{m}:number {n}みたいな行を探し、 stats cachedump {m} {n}みたいに打つと、キーの一覧を表示できる。
stats items STAT items:1:number 2 STAT items:1:number_hot 0 STAT items:1:number_warm 0 STAT items:1:number_cold 2 STAT items:1:age_hot 0 STAT items:1:age_warm 0 STAT items:1:age 572 STAT items:1:evicted 0 STAT items:1:evicted_nonzero 0 STAT items:1:evicted_time 0 STAT items:1:outofmemory 0 STAT items:1:tailrepairs 0 STAT items:1:reclaimed 0 STAT items:1:expired_unfetched 0 STAT items:1:evicted_unfetched 0 STAT items:1:evicted_active 0 STAT items:1:crawler_reclaimed 0 STAT items:1:crawler_items_checked 6 STAT items:1:lrutail_reflocked 0 STAT items:1:moves_to_cold 7 STAT items:1:moves_to_warm 5 STAT items:1:moves_within_lru 0 STAT items:1:direct_reclaims 0 STAT items:1:hits_to_hot 0 STAT items:1:hits_to_warm 0 STAT items:1:hits_to_cold 7 STAT items:1:hits_to_temp 0 END
stats cachedump 1 2 ITEM count [1 b; 0 s] ITEM hoge [4 b; 0 s] END
キーの削除
delete hoge DELETED
stats items STAT items:1:number 1 . . END
stats cachedump 1 1 ITEM count [1 b; 0 s] END
有効期限付きでセット
set some_id 0 10 1 1 STORED
速攻唱えると参照できるが
get some_id VALUE some_id 0 1 1 END
10秒後に唱えると消えている。
get some_id END
儚い。
telnetを終了する
^C^] telnet> q Connection closed.
memcachedコマンド一覧
NoSQL比較
Redisと違って、永続化もできないし、保存できるデータ構造も文字列しかなさそうなので
他にいろんな用途で使うようなことがあればRedisのほうがいいのかなと思いました。
でもmemcachedはシンプルで分かりやすくていいです。
ちなみにLaravelのセッションドライバーはRedisも選べます。
パート2はLaravel側の設定について書くぜ!
お楽しみにー。
Vuex使った時にフォームのバインディングにv-model使うと怒られる問題の解決法
Vuex使った時にフォームのバインディングにv-model使うと怒られる問題の 最終的な私の答え。
eventでvalueとキーネームを飛ばして ミューテーションでキーネーム付け合わせて、 バーンて入れるだけ。
これならミューテーションにupdateHogeを入力項目ごとに書かなくて済む。
inputにはこれを書いて
:value="blogForm.title" @input="updateBlogForm($event, 'title')"
inputのあるコンポーネントのmethodにはこれを書いて
updateBlogForm(e, key_name) { this.$store.commit('updateBlogFormValue', { value:e.target.value, key_name }); }
ストアにこれを書くだけ
updateBlogFormValue (state, { value, key_name }) { state.blogForm[key_name] = value; },
思いついたときに感動した。
Laravel mixでbrowserSyncを使っている場合に<pre>タグを使うと、その前に謎の<script>が入りVueコンパイルエラーになるぞ
ググってきた人のために最初に言っておく、 この問題の解決策は見つからなかったので、ここには解決策は書いてない。
解決策を求めている人は、今すぐ立ち去るが良い。
Laravel mixでbrowserSyncを使ってブラウザの自動リロードをしている場合に、
ドキュメントに
<pre>
preタグがあると、閉じタグの前に謎の
<script>
scriptタグが挿入され
Vue.jsのテンプレートコンパイルエラーが出て怒られる。
Error compiling template
対処法は今のところ見つかっていないが、自動リロードしているタブじゃなければエラーは発生しないので
本番&ステージング環境などでは特に問題はなさそう。
ちなみにpreタグのある箇所の親divにv-preをつけてもエラーは消えない。
【キーワード】 Vue.js vue コンパイルエラー Error compiling template Laravel mix browserSync BrowserSync browser sync preタグ
$requestでは$request->get()はダメ、ゼッタイ
Laravel4に慣れてる諸君は分かると思うが、Laravel4ではInput::get()という書き方をしていたので
Laravel5系でもついつい$request->get()って書いてしまう。
さらに悪い事に$request->get()と書いても入力値が取得できてしまう。
でもこの$request->get()で取ってくる値は、Symfonyのほうのメソッドなので
単に入力値を取ってくるだけのやつなのである。
よって、FormRequestでごちゃごちゃやってるのは何も反映されない。
なので、必ず入力値は$request->input()で取得するように。
お姉さんとの約束だ。
$request->input()
safariで出力ファイルの拡張子に.htmlを付けられる時の対処法
対処方法1
出力処理の最後にexit;を足す。 ※ ただし、exitで処理をぶった切るので、middlewareでactionのafterにごちゃごちゃやってると、それもぶった切られる。
// ファイル出力 $fp = fopen('php://output', 'w+b'); fwrite($fp, $csv); fclose($fp); exit;
【参考】 https://stackoverflow.com/questions/19363744/safari-adding-html-to-download
https://qiita.com/mata/items/6a30b65ecc71e02d447a
対処方法2
responseヘルパーを使ってレスポンスを返す
ex) csv
$csv = FileUtils::createCsv($user_rows); return response($csv)-> header('Content-Type', 'text/csv')-> header( 'Content-Disposition', 'attachment; filename="'.$file_name.'.csv'.'"' );
ex) zip
$headers = [ 'Content-Type' => 'application/zip', 'Content-disposition' => 'attachment; filename*=UTF-8\'\''.rawurlencode($zipName), 'Content-Length' => filesize($zipPath) ]; return response()->download($zipPath, $zipName, $headers);
youtubeのソースに埋め込まれてるogpタグを確認する方法
youtubeの仕様が変わって、UserAgentを見てogpタグの出力を制御している模様。
Google dev toolでカスタムUserAgentに以下を指定することで、ogpタグを確認することができる。
facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)
参考
Google ChromeでカスタムUserAgentを指定する方法はこちら
ogpタグ値をChrome拡張機能で確認
ogpタグで指定されている値をさくっと確認したい場合は、こちらのChrome拡張入れると便利。
Open Graph Preview
こんな感じ。