docker-compose でPHPのマルチバージョン環境を

作りたかったわけです。
色々と苦戦したので、メモとして残します。

  • DockerHubで提供されている公式のPHPイメージを使う
  • 見れればいいのでwebサーバはapache
  • PHPのエクステンションを追加する

イメージ

イメージ名は php<version>-apache で統一されています。
最新は7.3、 一番古いものは5.3でした。

apachehttpd.conf

php5.5~

ドキュメントルートを変更したい場合などあると思います。
基本的には以下のようにdocker-compose.ymlで000-default.confをマウントしてしまえば大丈夫です。

services:
  php55:
    volumes:
      - ./000-default.conf:/etc/apache2/sites-available/000-default.conf

~php5.4

docker-compose.yml でマウントしても反映されません。
サボらずにDockerfile書きましょう。

なお、php5.4では DirectoryIndex がデフォルトでOff、php5.3ではデフォルトでOnのようです。

OSへのパッケージインストール

phpのイメージのOSはどうやらDeb系のようです。

php5.6~

Dockerfile 内でapt-getするだけです。

RUN apt-get update && apt-get install -y libxslt1-dev

~php5.5

OSが古いようで、そのままではapt-get updateできません。
公開鍵を追加したり、source.listをいじる必要があります。

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010 \
    && apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9D6D8F6BC857C906 \
    && echo "deb http://deb.debian.org/debian jessie main" > /etc/apt/sources.list \
    && echo "deb http://security.debian.org jessie/updates main" >> /etc/apt/sources.list \
    && apt-get update \
    && apt-get install -y \
        libxslt1-dev

参考:

bigbuddha.hatenablog.jp

qiita.com

PHPエクステンションの追加

php5.4~

公式サイトにもありますが、Dockerfileに以下のように書くだけで、簡単に追加できます。

RUN docker-php-ext-configure xsl --with-xsl=/usr/include
RUN docker-php-ext-install xsl

php5.3

docker-php-ext-xxx系のスクリプトが使えません。
自分でビルドする必要があります。

まず、phpのソースファイルを落としてくる必要があります。
$PHP_VERSION には落としたいphpのバージョンを入れてください。

RUN curl -SL "http://php.net/get/php-$PHP_VERSION.tar.bz2/from/this/mirror" -o php.tar.bz2 \
    && mkdir -p /usr/src/php \
    && tar -xf php.tar.bz2 -C /usr/src/php --strip-components=1

次に、エクステンションのMakefileを作成します。

RUN cd /usr/src/php/ext/xsl \
    && phpize \
    && ./configure

そして、ビルドをして.soファイルを出力します。

RUN cd /usr/src/php/ext/xsl \
    && make \
    && make install

最後に、php.iniで.soファイルの場所を読み込ませます。

php.ini

extension=/usr/local/lib/php/extensions/no-debug-non-zts-20090626/xsl.so

Dockerfile

COPY ./php.ini /usr/local/lib/php.ini

まとめ

なるべくphp5.3は使わない方がいいです・・・環境作るのも大変。

いきなり1on1を受けてきました

いきなり1on1とは?

nitt-san.hatenablog.com

だいたいの流れ

  1. slackで待ち合わせ
  2. 茶店
  3. ごはんが来るまでにヒアリングシートを書く
  4. ごはん食べる
  5. 本番開始
  6. 蛍の光が流れてきたので隣の喫茶店
  7. 本番再開
  8. 終了

感想

自分の頭の中のことを話す機会はないので、とても新鮮でした。
かなり掘り下げてくれたので、自分の考えの矛盾点が暴露されたり、それを必死に取り繕うとする自分が見えたり、発見が多かったです。
また、最終的には自分の悩みに対する指針のようなものが見えました。

つまり、最高だったということですね。

反省

「よくわからんから任せよう!」というスタンスになってしまったのは良くなかったなー・・・という感じです。
これに150分ほど割いていただいたのですが、nitt-san側にメリットをあまりお渡しできていない感覚があるので、申し訳ない気持ちが・・・

まとめ

まじで最高でした。nitt-sanありがとうございます!

herokuでサブディレクトリをデプロイする

まえおき

herokuを使いたいなーと思って調べています。

herokuにデプロイするときに、 build-pack というものを使用します。
これは、デプロイされるアプリケーションの言語などを自動で推定してくれるやつです。これを設定しないとデプロイできません。

我々はphperなので、 heroku/php というものを使うのですが、公式ドキュメントにあるように、トップディレクトリに composer.json または index.php が必要になります。

Heroku PHP Support will be applied to applications only when the application has a file named composer.json in the root directory. Even if an application has no Composer dependencies, it must include an empty composer.json in order to be recognized as a PHP application.

が、僕はルートディレクトリは

という構成でやってるので、ルートディレクトリに composer.json がなくてデプロイできませんでした。
個人的にこの構成は気に入っているし、わざわざデプロイのためにディレクトリ構成を変更するのもおかしな話です。

解決策

調べてみると、subdir-heroku-buildpackというものを使うと、サブディレクトリのみをデプロイできるようです。

herokuの設定値に PROJECT_PATH という変数を設定し、このbuild-packを heroku/php の前にかましてあげるだけでデプロイできるようになります。

余談

上記のように簡単に設定できるはずだったのですが、私はかなりつまづきました。
というのも、 PROJECT_PATH を設定してるにもかかわらず、 PROJECT_PATH is undefined と怒られるんです。

結局のところ、pushしているブランチが違っていて、 PROJECT_PATH で指定しているディレクトリが見つからないのが原因でした。

エラーメッセージと原因が違うってどうなのよ??となったので、Forkして、ちゃんとエラーメッセージが出る版を作りました。

github.com

よければ使ってやってください。

composerで特定のリビジョンのパッケージを取得する

こちらがわかりやすいです。

akamist.com

なるほどなー!

"{vendor}/{package}" : "dev-{branch}#{hash}"

って書けばええんやな!やったろ!

"laravel/socialite": "dev-3.0#79316f3"

実行!

> composer update laravel/socialite
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.   

あれっいかない!
となったわけです。

ドキュメントにちゃんと書いてありました。

When branch names look like versions, we have to clarify for composer that we're trying to check out a branch and not a tag. In the above example, we have two version branches: v1 and v2. To get Composer to check out one of these branches, you must specify a version constraint that looks like this: v1.x-dev. The .x is an arbitrary string that Composer requires to tell it that we're talking about the v1 branch and not a v1 tag (alternatively, you can name the branch v1.x instead of v1). In the case of a branch with a version-like name (v1, in this case), you append -dev as a suffix, rather than using dev- as a prefix.

getcomposer.org

つまるところ、「ブランチ名がバージョン名っぽい感じのときは最後に .x-devってつけてね」とのこと。

こちらが正解でした。

"laravel/socialite": "3.0.x-dev#79316f3"

hyper + powershellで文字に色が付かないとき

hyper + powershellで文字に色が付かずに ?[39m などと出てしまう現象に遭遇しました。

とりあえず私は以下の方法で対処できたので、記しておきます。

  1. hyperを3系に上げましょう。

    githubから落とせます。

  2. Windowsのバージョンを 1809 まで上げましょう。

    windows version 1809

以上です。

参考:

github.com

Laravel JP Conferenceに行ってきました

タイトルのとおりです。

2/16日にLaravel JP Conferenceに行ってきました。
今回はPHPカンファレンス仙台2019に引き続き、Speaker+Sponsor+Staffのスリーエスで参加しました。

スポンサーとして

スポンサーとしては実質あまり動いてなく、カンファレンスが動きやすいように会社に締め切りつっついたり、会社がアピールしやすいようにカンファレンスに働きかけたりしてました。
二重スパイみたいなもんですね。

スピーカーとして

今回は人生初のレギュラートークをしてきました。
内容は「ServiceProvider, ServiceContainer入門」です。

自分でもしっかりと理解できていない部分があったので、発表の準備をする際にしっかり調査をしました。
そこでDIの色々な説明を見たのですが、その多くがDIとDIコンテナをまとめて説明していたり、DIと型システム(インターフェースや継承など)を混同しているなと感じました。
そこで、今回の発表ではそれらの構成要素をバラして説明することで、サービスコンテナをより深く、よりわかりやすくしようというコンセプトをとりました。
いちおうTwitterの反響では特にマサカリもなかったので、成功だったのかなーという印象です。

ちょっとスライドを準備する時期が遅くなってしまい、前日に発表練習をしてみたのですが、発表練習をすると色々な学びがありました。

スクリーンショット 2019-02-20 16.47.22.png (109.3 kB)

「初めて発表するぞ!」という人は、いちど発表練習をしてみることをおすすめします。
自分の発表を客観的に見れて、学びが深いです。

スタッフとして

コアスタッフとして参加してきました。
個人的にドタバタしていてあまりコミットできず、申し訳ないです。。。
あまり主体的に動けなかったので、そこは課題です。

当日もセッションとワークショップに追われてほぼスタッフ業をできなかったので、事前準備や撤収でちょっとだけ頑張らせていただきました。

今思い返すと、熱量高いチームですごい良かったなぁ・・・という感じです。
熱量あれば何とかなる!みんなもスタッフやろう!

ワークショップスタッフとして

エンジニアの登壇を応援する会にてワークショップをやらせていただきました。
コンテンツの準備などは他のメンバーにお任せして、自分は機材レンタルなどの裏方をやってました。
メンバーが優秀で、かなり周到に用意ができたので、大きな問題もなく進んだなーという感じです。

開催を終えて

スクリーンショット 2019-02-20 17.06.08.png (318.4 kB)

色々な人からフォローされました! でも、あんま技術的なお話してないねんな・・・

スクリーンショット 2019-02-20 17.07.41.png (268.8 kB)

来年の開催は決まってないので、ここらへんの話が気になるところです。

PHPでエラーと呼ばれているものまとめ

PHPでエラーと呼ばれているものをまとめてみました。

誰が見てもエラーとわかるもの

Error

<?php
try {
    $a = $b / $c;
} catch (DivisionByZeroError $e) {
    $a = 0;
}

PHP7から導入されたError
オブジェクトとして扱えて、try, catchできます。
便利ですね。

エラー

Fatal error: Call to undefined method Controller::index() in Controller.php on line 6

PHP5おなじみのこれ。
良い子は @error_reporting(0); を使ってはいけませんよ。

Fatal errorParse error のみをエラーと呼ぶ流派もいるそうです。

エラーか微妙なライン

エラー例外

<?php
function exception_error_handler($severity, $message, $file, $line) {
    throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("exception_error_handler");

自作フレームワークを作ったことがある人なら誰もがとおるアレ

これをエラーと識別するか例外と識別するかは意見が分かれるところ。

できればエラーと呼ばないでほしい

例外

<?php
try {
    $model->save();
} catch(Exception $e) {
    // 握りつぶしてやる!
}

例外はエラーじゃないのよ!   例外とエラーの違いについては色んな記事があるから読んでみるといいかも。

SPL例外みんなもっと使っていきましょ。

Throwable

例外とErrorのインターフェースがThrowableです。
エラーを含んでいますが、エラーじゃないものも含んでいるのです。

思ってたのと違う

trueが返るはずですがfalseが返ってきました。エラーです。

それはエラーじゃない!ただのバグ!

真っ白い画面

何も表示されないんです。エラーです。

たぶんエラーでてると思うけど、レスポンス返してないだけかも。
とりあえずエラーログ出てないか見てみるのと、 display_errorserror_reporting確認してみよ?