HerokuでのPHPサポートが正式版になってたので、現時点でこんな感じで使っているよ、ということ。
reference
- Getting Started with PHP on Heroku | Heroku Dev Center
- Customizing web server and runtime settings for PHP | Heroku Dev Center
- Heroku PHP Support | Heroku Dev Center
- PHP session handling on Heroku | Heroku Dev Center
start
-
composer.json
があればPHPアプリケーションとしてdetectされる - しかし、
package.json
とかGemfile
とかあるとPHPのアプリケーションとして認識されない - 今どきはこういうファイル、大抵ある
- buildpackを明示的に指定することでPHPアプリケーションと認識させる
heroku config:set BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-php
- 必要ならタイムゾーン設定
heroku config:add TZ=Asia/Tokyo
runtime
- PHPとHHVMが選べる
- HHVMがサポートされてないフレームワークとかあるので注意
- でも大概動く
- どちらを選ぶかは
composer.json
に記述する
runtime settings
- document_rootの
index.php
があるところに.user.ini
を置く - PHP: .user.ini ファイル - Manual
例
[PHP]
upload_max_filesize = "10M"
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = Off
mbstring.func_overload = 0
server
- Apacheとnginxが選べる
- Apacheはmod_proxy_fcgi経由のFastCGIで動く
- nginxはphp-fpm経由で動く
-
Procfile
で指定する - nginx:
web: vendor/bin/heroku-php-nginx
- nginxでdocument_rootを指定:
web: vendor/bin/heroku-php-nginx web
- nginxで設定ファイルも指定:
web: vendor/bin/heroku-php-nginx -C nginx_app.conf web
- nginxの場合に
client_max_body_size
を指定できないぽいのでアップロードがある場合はApacheがよさそう - Apache(2.4):
web: vendor/bin/heroku-php-apache2
- Apacheでdocument_rootを指定:
web: vendor/bin/heroku-php-apache2 web
- 設定ファイルを指定することもできるが
.htaccess
を使った方が楽
nginx_app.conf
index.php
から起動する今どきなフレームワークの場合の設定。
ちなみにCSSとか画像をHerokuから配信するのであれば、ここでExpires
ヘッダーを付加するヘッダーの追加が可能。
location / {
# try to serve file directory, fallback to rewrite
try_files $uri @rewriteapp;
}
location @rewriteapp {
# rewrite all to index.php
rewrite ^(.*)$ /index.php/$1 last;
}
location ~ .*\.(jpg|gif|png|ico|css|js|ttf|eot|svg|woff) {
expires 5d;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass heroku-fcgi;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
.htaccess(Apacheを使う場合)
index.php
から起動する今どきなフレームワークの場合の設定。
もちろんその他の設定もできますが、省略。
FallbackResource /index.php
LimitRequestBody 10485760
extension
- Heroku側で結構用意されてるのでそれを使う
- https://devcenter.heroku.com/articles/php-support#extensions
-
composer.json
に使いたいextensionを記述すればOK - どうしても自分で入れたい場合はbuildpackをいじるしかない
- 面倒なのでやるべきではない
- そこまでやるなら素直にAWS使うべき
add-on
New Relic
- add-onで有効にした後でdeployすると勝手にext-newrelicが入る
- 有効にしただけだと当然入らないので注意。deployしよう
- ライセンスキーなどは自分のものに差し替えるのがよさそう
- アプリ名:
heroku config:set NEW_RELIC_APP_NAME=<アプリ名>
- ライセンスキー:
heroku config:set NEW_RELIC_LICENSE_KEY=<自分のキー>
MongoLab
- 有効にすると
MONGOLAB_URI
という環境変数に接続先情報がセットされる - Mongoクラスの接続文字列としてそのまま使える
- セッションストレージで利用する場合など、DB名が必要な場合は最後のスラッシュ以降の文字列を取り出して利用する。
$mongolabUri = getenv('MONGOLAB_URI');
$mongolabDbName = substr($mongolabUri, strrpos($mongolabUri, '/') + 1);
Postgres
- 有効にすると
DATABASE_URL
という環境変数に接続先情報がセットされる - 例:
postgres://<ユーザー名>:<パスワード>@<ホスト名>:<ポート番号>/<DB名>
-
parse_url
関数を使って必要な値に分解するのがよい
$dbUrl = parse_url(getenv('DATABASE_URL'));
$dbName = ltrim($dbUrl['path'], '/');
$dbHost = $dbUrl['host'];
$dbPort = $dbUrl['port'];
$dbUser = $dbUrl['user'];
$dbPass = $dbUrl['pass'];
SendGrid
- 有効にすると
SENDGRID_USERNAME
とSENDGRID_PASSWORD
という環境変数がセットされる - 必要であれば自分でSendGridのサイトから登録、自分のユーザー名とパスワードを同環境変数に設定して使う
- ユーザー名:
heroku config:set SENDGRID_USERNAME=<自分のユーザー名>
- パスワード:
heroku config:set SENDGRID_PASSWORD=<自分のパスワード>
- 取得は
getenv('SENDGRID_USERNAME')
、getenv('SENDGRID_PASSWORD')
で - 公式のライブラリ、Sendgrid-phpを使うのが便利
logging
- ログ出力はローカルにするわけにいかない
- 標準出力(
php://stdout
)もしくは標準エラー出力(php://stderr
)に出力するのがよい - 必要に応じてPapertrailなどのアドオンを組み合わせるのがオススメ
limitation
- サーバー側に何か保存するのはダメ
- ファイルアップロードを一度受けるぐらいならOK
- ファイルベースのセッション、使えない
- memcachedなりMongoDBなりのadd-onをセッションストレージにすべき
- https://devcenter.heroku.com/articles/php-sessions
etc.
switch environment
- 環境変数を利用してローカルの開発環境とHeroku上の環境で設定とか切り替えるのがよさそう
heroku config:set PHP_ENV=heroku
こんな感じで切り替え
switch (getenv('PHP_ENV')) {
case 'heroku':
$app = require __DIR__ . '/bootstrap.heroku.php';
break;
default:
$app = require __DIR__ . '/bootstrap.local.php';
break;
}
Basic Authentication
- Herokuの場合だけ読まれるファイルにPHPで書くのが早い
if (isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])
&& $_SERVER['PHP_AUTH_USER'] === '<ユーザー名>'
&& $_SERVER['PHP_AUTH_PW'] === '<パスワード>') {
} else {
header('WWW-Authenticate: Basic realm="<表示されるメッセージ>"');
header('HTTP/1.0 401 Unauthorized');
exit;
}