かなり久しぶりの更新です。
前回では、HerokuでSymfony2を動かすようにしてみましたが、セッションをMemcachedに格納するところがどうしてもできずにいました。
しかし、PHP session handling on Herokuを見つけまして、試したらちゃんと動きました。
結局は、設定ミスや勘違いが原因だったのですが、同じようなことにハマっている人もいるかもしれないので方法を紹介します。
今回の目標
環境
前提条件
- Herokuのアカウントを登録、アドオン追加のため、クレジットカードも入力済みとする
- Git, Heroku Toolbelt, Composer はインストール済みとする
- PHPのMemcached(memcacheではない)モジュールをインストールする
$ php -m
でmemcached
と表示されていれば大丈夫です
Memcachierアドオンをインストール
HerokuでMemcachedを使うアドオンとして、Memcachierを使います。
無料枠もありますが、使うにはクレジットカードの登録が必要です。
Memcachierアドオンをインストールします。
$ heroku addons:add memcachier:dev
Adding memcachier:dev on heroku-symfony2-test0515... done, v17 (free)
Please allow up to three minutes for MemCachier credentials to sync.
Use `heroku addons:docs memcachier` to view documentation.
設定を確認してみます。
$ heroku config | grep MEMCACHIER
MEMCACHIER_PASSWORD: xxxxxxxxxx
MEMCACHIER_SERVERS: xxx.dev.ec2.memcachier.com:11211
MEMCACHIER_USERNAME: xxxxx
Memcachedを使うための設定が環境変数に格納されています。
composer.json にMemcachedを追加する
composer.json
にMemcached
を追加して、composer update
します。
// composer.json
{
"require": {
...,
"ext-memcached": "*"
}
}
$ composer update
PHPのMemcachedモジュール(memcacheではない)をインストールしていないと、以下のようなエラーがでます。
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested PHP extension ext-memcached * is missing from your system.
Problem 2
- Installation request for symfony/framework-standard-edition 2.3.x-dev -> satisfiable by symfony/framework-standard-edition[2.3.x-dev].
- symfony/framework-standard-edition 2.3.x-dev requires ext-memcached * -> the requested PHP extension memcached is missing from your system.
フロントコントローラ(app_xxx.php)に、ini_set()を追記する
先ほどのMemcachedの設定をPHPの設定に組み込むために、ini_set()
を使います ((.user.ini
を使う方法もあります))。
今回は、web/app_heroku.php
に以下のように追記します。
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Debug\Debug;
+ini_set('session.save_handler', 'memcached');
+ini_set('session.save_path', 'PERSISTENT=pool ' . getenv('MEMCACHIER_SERVERS'));
+ini_set('Memcached.sess_binary', 1);
+ini_set('Memcached.sess_sasl_username', getenv('MEMCACHIER_USERNAME'));
+ini_set('Memcached.sess_sasl_password', getenv('MEMCACHIER_PASSWORD'));
Memcachedの設定値はgetenv()
で環境変数から取得するようにしています。
Symfony2でセッションの保存先をMemcachedに変更する
先ほどのweb/app_heroku.php
でセッションの保存先をMemcachedに変更したので、Symfony2の設定ファイルでは以下のように修正します。
# app/config_heroku.yml
imports:
- { resource: config.yml }
- { resource: parameters_heroku.yml }
framework:
router:
resource: "%kernel.root_dir%/config/routing_heroku.yml"
strict_requirements: true
profiler: { only_exceptions: false }
+ session:
+ handler_id: ~
web_profiler:
toolbar: true
handler_id: ~
とすることで、php.ini
のSession
セクションの設定値をそのまま読み込むようになります。
Symfony2では、この設定をしないとini_set()
で設定を変更してしまいます *1。
デプロイ
Gitのリポジトリに追加して、git push
すればデプロイ完了です。
$ git add -A && git commit -m "Add Memcached support"
$ git push heroku master
最後に
HerokuでMemcachedを有効にして、セッションを格納できるようになりました。
デプロイする度にSymfony2のキャッシュがクリアされてしまい、app/cache/<env>/sessions
に格納されていたセッションファイルも削除されるためセッションが切れてしまっていましたが、Memcachedに格納することでデプロイしてもセッションを保つことができるのでより実用的に使えるのではないかと思います。
*1:僕がここが一番ハマったところです