認識できてないバグを認識するのって

ぼーっとしてたら後輩から「ねぇ、こういうバグがあったんだけど、どうやったらもっと早いフェーズで気付けるのかな?」って質問された。

そうねぇ・・・何か考えあるの?って聞いたら「僕は、コードレビューをもっとしっかりやったら見つけられると思う」って言うので。

そっか。見つけられなかった原因って何なの?って聞いたら「その部分の仕様を正しく認識できてなかったことかな」って言うので。

そっか。それは、コードレビューをしっかりやっても見つけられなさそうよね。だって認識できてないんだから。

「たしかに・・・じゃあ、認識できてないことを認識するのってどうするの?経験しないと無理なの?」

んー。今回のってコードの問題じゃなくて、仕様の認識の問題よね。仕様が詰めきれてない部分は、想像や思い込みで補われるかなぁ。

だから、誰か1人でいいから「ここは想像で進めてしまってる」って気づいて、そこで立ち止まってみんなで考えられるようなチームになるといいんじゃないかな。

あとね、いっぱいいっぱいだと「違和感ある気がするけど、たぶん気のせいだ」って言い聞かせて次に進んじゃうから、ゆとりも大切。

って話をしたのだけど。そんなんで良かったのかな。

条件分岐を使わずにFizzBuzzをJavaで

ついったーで見かけて頭の体操に面白いなーと思ってやってみた

gist.github.com

面白かったー

❯ java FizzBuzz.java
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz

Java11使ってます

娘(小4)とプログラミング日記:アルファベット

娘とは以前から「お父さんスイッチ」とか「ルビィのぼうけん」とか「スクラッチ」とかで遊んでて。今年で4年生になったので「そろそろプログラミング教えてあげようか?」って言ったら結構乗り気だったので。夏休みにこういうのを始めてみた:

bufferings.hatenablog.com

といっても、今日が2回目。

それとは別で、妻さんが「夏休みはアルファベット教えてあげとくね」って教えておいてくれたので「じゃ、ブラインドタッチ教えてあげるわー」って感じで、前回左手のa-gをやって、今回は右手のh-pを教えておいた。

PCの中だけじゃなくて実際のモノを使ったやつの方がいいのかなぁとは思いつつ。楽しんでるみたいなのでいっかな。

今のところ

こんな感じだな。年内にgolangでフィズバズくらいできたら面白いかな?自分がgolangを勉強するきっかけにもなるし。

  • これまで
    • お父さんスイッチ遊び
    • ルビィのぼうけんごっこ
    • クラッチ遊び
  • 最近やったこと
    • CSS遊び(色だけ)
    • アルファベット
  • 今やってるとこ
    • Code.orgのコース1
    • a-pまでのブラインドタッチ

次、何をやるかはその日の娘と僕の気分で決めよっと。

PhpStorm+DockerでCakePHPの開発環境を作ってみた

この土日にあーでもないこーでもないって楽しんでたんだけど、たぶんできたと思う。結構色々あったな。というか、今日の日記長い。

## 今日のコード

github.com

## 発端:Dockerでできそうじゃない?

CakePHPを勉強しようと思って、PHPBrewでPHPのバージョンを切り替えられる環境を作って

PHPに入門してみる。phpbrewとIDEA+PHPプラグインでCakePHP3の準備。 - Mitsuyuki.Shiiba

IDEとしてIntelliJ IDEA(+各種PHPプラグイン)を触って

JetBrainsのPhpStormワークショップをひととおりざっくりやってみてメモ - Mitsuyuki.Shiiba

その後にごにょごにょ触ったり色んな記事を見たりしてたら「あれ?Dockerの中のPHPを使えばホスト側にPHPなくても大丈夫そう?」と思ってしまった。

なので、PHPとPHPBrewをアンインストールして、Dockerで環境を構築してみることにした。

## 注意

1) 分かりやすいようにと思って「PhpStorm」って書いてるけど、実際はPhpStormじゃなくてIDEAにPHP系のプラグインを追加してやってる。設定画面やメニューの場所などがちょこちょこ違うけど、機能はだいたい同じなんじゃないかと思う。

IntelliJ IDEA 2018.2.3 EAP (Ultimate Edition)
Build #IU-182.4323.6, built on August 22, 2018

2) OSはUbuntuの18.04

3) PHP自体を勉強し始めたばっかりなので変なところとかあるかも

## できたこと

ホストマシンにはPHPをインストールせずに、PhpStormでApache+PHPのDockerイメージを使って、

## 感想

  • 気に入った
    • Dockerなので一度準備が整ってしまえばお手軽で良い
  • けど、最初に考えてたよりは複雑になっちゃった
    • DockerやPhpStormの仕様や、まだサポートされてない機能とかの影響で素直に実現できない部分があって、それを回避する必要があったし、実現できない機能もあった
    • もう何年かしたら色々サポートされててもっと楽なのかもしれない
    • Vagrantは今回は使わない方向でがんばったけど、使う方がシンプルになるかもなぁという気もした
  • それと、速度が心配
    • プロジェクトルートをそのままマウントして使うので、色々ファイルが増えても問題ないスピードで動くのかどうかがが心配

## shin1x1さんの記事

shin1x1さんの記事を何度も読んで、実際にやってみて、最初は「う、動くぞ!(←分かってない」って感じだったんだけど、何度か触ってるうちに仕組みがだんだん分かってきた。

blog.shin1x1.com

## PhpStormワークショップのDockerブランチ

それから、前回はPhpStormワークショップのVagrantバージョンをやったのだけど、Dockerバージョンのブランチがあるのでそっちも触ってみた。shin1x1さんのはDocker Composeだったけど、こっちはDockerなんだなーって思いながら。

https://github.com/JetBrains/phpstorm-workshop/tree/docker#getting-started

## やりたいこと

やりたいのはこういうこと

### Remote Interpreter用のイメージ

f:id:bufferings:20180826202902p:plain

  • PhpStormからPHPのツール(composerとかphpunitとか)を実行するためのphp-cliイメージ
  • プロジェクトのルートディレクトリーがマウントされてるので
  • ツールの実行結果はローカルディレクトリにも反映される(vendorとか)
  • それとphp.iniもマウントされてる

で、それとは別に

### アプリケーション実行用のイメージ

f:id:bufferings:20180826203120p:plain

  • アプリケーションの実行とリモートデバッグをするためのphp-webイメージがあって
  • これは常に起動しておく
  • こっちにもプロジェクトのルートディレクトリーとphp.iniがマウントされてる

という感じ。

### 2つイメージをそれぞれ管理するのも面倒なので

1つのDockerイメージで両方をカバーしてしまおうと思う。こんな感じ。

f:id:bufferings:20180826203247p:plain

それと、Volumeマウントとかの設定をコードとして書いておきたいのでdocker-composeを使う。

## Docker関係の準備

### Dockerfile

色々あってDockerfileはこうなった。順番に説明してく。

FROM php:7.2.9-apache

↑PHP7 + Apacheのイメージを使用。

# Xdebug
RUN pecl install xdebug \
 && docker-php-ext-enable xdebug

Xdebugを入れて有効化。

# For CakePHP
RUN apt-get update && apt-get install -y \
    git \
    libicu-dev \
    libzip-dev \
    zip \
 && rm -rf /var/lib/apt/lists/* \
 && a2enmod rewrite \
 && NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) \
 && docker-php-ext-configure zip --with-libzip \
 && docker-php-ext-install -j${NPROC} zip \
 && docker-php-ext-install -j${NPROC} intl \
 && docker-php-ext-install -j${NPROC} pdo_mysql

CakePHP動かすのにこんな感じかなぁ?と思いながら書いた。実際に動かしてみたら他にも必要なのがあるかもしれない。

# Composer
ENV COMPOSER_HOME /tmp
COPY --from=composer:1.7.2 /usr/bin/composer /usr/bin/composer

↑Copmoserは、https://github.com/docker-library/docs/tree/master/composer#suggestionsのnoteのところを参考にした。マルチステージビルドの外部からとってくるやつなんやね。

# Change DocumentRoot
WORKDIR /app
ENV APACHE_DOCUMENT_ROOT /app/webroot
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
 && sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

↑DocumentRootの変更は、https://github.com/docker-library/docs/blob/master/php/README.md#changing-documentrootを参考にした。CakePHPのプロジェクトをこの後生成するのでwebrootディレクトリにした。

# Change uid & gid of www-data
RUN usermod -o -u 1000 www-data && groupmod -o -g 1000 www-data

昨日の記事でも書いたけど、Linuxの場合はVolumeマウントしたときにuid:gidをホスト側のユーザーと揃えておかないと面倒なので1000:1000固定にしておいた。本当は実行時にuidとgidを外から設定するほうがキレイだけど自分用だし良いかなと思って。

# To switch user on runtime
RUN apt-get update && apt-get -y install \
    gosu \
 && rm -rf /var/lib/apt/lists/*
COPY entrypoint.sh /usr/local/bin/docker-php-entrypoint

php-webとしてApacheを動かすときは最初のプロセスをrootで起動する必要があるのだけど、php-cliでComposerとかのコマンドラインツールを使いたいときはwww-dataユーザーを使いたいので、gosuを入れてエントリーポイントのファイルを上書きしといた。

### entrypoint.sh

そのエントリーポイント。

#!/bin/sh
set -e

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
  set -- apache2-foreground "$@"
fi

if [ "$1" = "apache2-foreground" ]; then
  exec "$@"
else
  # use www-data for cli
  echo "gosu user to www-data"
  exec gosu www-data "$@"
fi

元々のイメージのエントリーポイント https://github.com/docker-library/php/blob/e92dfe4847c9fe74ea309e66f9d3ef0217f8525d/7.2/stretch/apache/docker-php-entrypoint にgosuの処理を加えた。

### docker-compose.yml

次はdocker-compose。

docker-compose.ymlはプロジェクトルートに置いて、Dockerfileとphp.iniはdockerディレクトリーに置いた。

❯ tree
.
├── docker
│   ├── Dockerfile
│   ├── entrypoint.sh
│   └── php.ini
└── docker-compose.yml

1 directory, 4 files

docker-compose.ymlはこんな感じ。

version: '3'
services:
  php-cli:
    build: ./docker
    command: php -v
    volumes:
      - .:/app
      - ./docker/php.ini:/usr/local/etc/php/php.ini
  php-web:
    build: ./docker
    volumes:
      - .:/app
      - ./docker/php.ini:/usr/local/etc/php/php.ini
    ports:
      - "8000:80"

CLIの方はビルドをしておきたいだけで起動しておく必要はないので適当にコマンドを指定しておいた。

### php.ini

んで、php.iniはまだ勉強してなくて全然分からないので、shin1x1さんのをコピーさせていただきました。で、2ヶ所だけ変更。

1) xdebug.remote_autostartOffにした。理由はリモートデバッグのところで書く。

2) xdebug.remote_host172.17.0.1(コンテナから見たホスト側のIPアドレス)にしておいた。今だとMacdocker.for.mac.localhostからhost.docker.internalに変わってるから、Macの場合はそっちにしといたらいいかな。Linux版にもそういう機能入れといてくれたらいいのにね。

; timezone
date.timezone = Asia/Tokyo

; error reporing
log_errors = On
error_log = /dev/stderr

; xdebug
xdebug.remote_enable = On
xdebug.remote_autostart = Off
xdebug.remote_connect_back = Off
xdebug.remote_host = 172.17.0.1
;xdebug.remote_port=9000
;xdebug.idekey=phpstorm

### ビルド

以上でファイルが揃ったのでビルド。いったんupして成功することを確認してからCTRL+Cで停止しておく。

❯ docker-compose build
❯ docker-compose up

CTRL + C

ちなみに、docker-composeを使うときは親ディレクトリの名前がイメージIDに使われる。今回僕はプロジェクトのディレクトリ名をphpstorm-docker-cakephpにしたので、イメージ名はこうなった(ちょっと長かったなって後で思ったけど)。

❯ docker-compose images
           Container                       Repository              Tag       Image Id      Size
------------------------------------------------------------------------------------------------
phpstormdockercakephp_php-cli_1   phpstormdockercakephp_php-cli   latest   92565eef7208   490 MB
phpstormdockercakephp_php-web_1   phpstormdockercakephp_php-cli   latest   92565eef7208   490 MB

ビルドが終わったので、こんな感じでコマンドが使える。

❯ docker-compose run --rm php-cli whoami
gosu user to www-data
www-data

じゃ、CakePHPプロジェクトを生成しよう。

## ComposerでCakePHPのプロジェクトを生成

### プロジェクトを作成

Composerが使えるようになったのでCakePHPのプロジェクトを生成する。

❯ docker-compose run --rm php-cli composer \
create-project --prefer-dist cakephp/app

しばらく待って、最後に「フォルダーのパーミッションセットする?」って聞かれたのでYにしといた。

### 生成したプロジェクトのファイルを移動

appってディレクトリに生成されてるので、その中身をカレントに移動することにする。

❯ mv app/* .
❯ mv app/.* .
❯ rmdir app

❯ tree -L 1
.
├── bin
├── composer.json
├── composer.lock
├── config
├── docker
├── docker-compose.yml
├── index.php
├── logs
├── phpunit.xml.dist
├── plugins
├── README.md
├── src
├── tests
├── tmp
├── vendor
└── webroot

10 directories, 6 files

### モジュールの追加

んで、PHPCS, PHPMD, PHPUnitを入れておく。PHPUnitCakePHP指定のバージョンで。

❯ docker-compose run --rm php-cli composer require --dev \
"squizlabs/php_codesniffer" \
"phpmd/phpmd" \
"phpunit/phpunit:^5.7|^6.0"

### 起動して見とく

これでアプリは動く状態なので、docker-composeでphp-webを立ち上げて見てみる。

❯ docker-compose up -d

でブラウザで localhost:8000

f:id:bufferings:20180826225449p:plain

(∩´∀`)∩ワーイ。準備はこんなとこかな。じゃ、PhpStormを起動しよう。

## PhpStorm

やるのは4つ:

ここでもう一度伝えておくと、僕が実際に使ってるのはIDEAなので、PhpStormとはちょこちょこ場所が違うかも。

## CLI Interpreterの設定

プロジェクトをインポートしたら、Settingsを開いて

Build, Execution, Deployment > Dockerで「+」を押してDockerの設定。Unix socketを選ぶとConnection sucessfulの文字が出る。

f:id:bufferings:20180826230202p:plain

次に、PHPCLI Interpreterを追加する。Language & Frameworks > PHPから、CLI Interpreterの右側の「…」をクリックして

f:id:bufferings:20180828003622p:plain

「+」ボタンを押して出たポップアップから「From Docker, Vagrant, VM, Remote...」を選ぶとこんなダイアログが表示される。

f:id:bufferings:20180828004045p:plain

ここで今回僕が選んだのは、Docker ComposeじゃなくてDocker。理由は、PhpStormがPHPCSとPHPMDを実行するのにDocker Composeだと対応してなくて、Dockerだったら対応してたから。

さっきDocker Composeでビルドしたので、イメージが作られてる。それを選択「phpstormdockercakephp_php-cli:latest」

f:id:bufferings:20180826230608p:plain

んで、OK押したら、こんな感じになるので、OKを押して

f:id:bufferings:20180828004409p:plain

PHPの設定画面で、今度は「Docker Container」という項目の一番右側のフォルダアイコンをクリックして

f:id:bufferings:20180828004714p:plain

ボリュームマウントの設定を行う。docker-compose.ymlで設定してたのと同じにしてOKを押す。

f:id:bufferings:20180827001402p:plain

これでCLIの設定終わり。

## PHPUnitの実行やデバッグ実行ができた

Language & Frameworks > PHP > Test Frameworkの設定をこんな感じにして

f:id:bufferings:20180827001549p:plain

実行したら動くー!

f:id:bufferings:20180827001741p:plain

デバッグ実行もできるー!(∩´∀`)∩ワーイ

f:id:bufferings:20180827001842p:plain

## PHPCSとPHPMDのコードインスペクションができた

### Code Snifferの設定

Code Snifferは、Language & Frameworks > PHP > Code Sniffer でConfigurationの一番右側の「…」のとこを押して

f:id:bufferings:20180828005621p:plain

開いた画面の左側の「+」の部分からさっき作成したCLIを選ぶだけ。

f:id:bufferings:20180827002045p:plain

んで、Validateボタンを押してOKとなるのを確認しておく。

f:id:bufferings:20180828005741p:plain

### Mess Detectorの設定

phpmdもLanguage & Frameworks > PHP > Mess Detectorで同じことをやる。

f:id:bufferings:20180828005954p:plain

### Inspectionの設定

は、PHPCSとPHPMDのことをまだよく分かってないので、PHPCSはPSR2を選んで

f:id:bufferings:20180827002639p:plain

PHPMDは全部チェック入れてみた

f:id:bufferings:20180827002740p:plain

### 変なコードを書くと

ちゃんと指摘してくれる!(∩´∀`)∩ワーイ

f:id:bufferings:20180827003139p:plain

だけど、メニューからの一括実行には対応してないみたい。残念。ま、そこはターミナルからやればいっか。

https://youtrack.jetbrains.com/issue/WI-33088

## CakePHPアプリケーションのリモートデバッグができた

最後にリモートデバッグをやったらおしまい!

### PHP Remote Debugの設定

RunメニューのEdit Configurations…で開いたRun/Debug Configurationsから「+」を押して「PHP Remote Debug」を追加して、「Filter debug connection by IDE key」をチェックしたら右側の「…」を押して、こんな風に設定。パスのマッピングが必要なので、Use path mappingのチェックを入れて、プロジェクトルートを/appにマッピングする。

f:id:bufferings:20180827004505p:plain

PHP Remote Debug」の設定に戻って、IDE key(session id)のところを「PHPSTORM」にしておく。

f:id:bufferings:20180828010921p:plain

OKを押す。

### リモートデバッグ用のブックマークレット

JetBrainsの「Xdebug & Zend Debugger bookmarklets generator for PhpStorm」を使う。

www.jetbrains.com

XdebugIDE keyに 初期値の「PHPSTORM」が入力された状態で「Generate」ボタンを押して表示された「Start debugger」と「Stop debugger」をブックマークバーにドラッグ&ドロップ。

f:id:bufferings:20180828012351p:plain

### いよいよデバッグ

Runメニューの下の方にある「Start Listening for PHP Debug Connections」を実行。それと、分かりやすさのために今回は「Break at first line in PHP scripts」を有効にしておく。

その後、http://localhost:8000/ をブラウザで開いて、さっきブックマークした「Start debugger」をクリックして、画面をリロードすると

f:id:bufferings:20180828012822p:plain

index.phpに入ってきたところで止まって、デバッグ情報も見れたー(∩´∀`)∩ワーイ

### remote_autostart

最初はXdebugのremote_autostartをOnにしてたんだけど、そうするとCLI系のツールが全部動かなくなってしまったので、OffにしてちゃんとIDE keyを指定するようにしたのだ。

## まとめ

ホストマシンにはPHPをインストールせずに、PhpStormでApache+PHPのDockerイメージを使って、

現在のPhpStormでは対応されていないこと

  • Docker ComposerインタープリターによるPHPCS、PHPMDの実行はできない
  • メニューからInspectionを一括実行した場合には、PHPCS、PHPMDは動作しない
  • それと、PhpStormのComposer連携はRemote Interpreter非対応みたい

感想

  • 満足したので、CakePHPの勉強をやっと始めそうな気がする。

DockerのVolumeマウントのオーナーとfixuidとeuid

なんか慣れてきた

Dockerでホスト側のディレクトリをVolumeマウントして、そこに対してコンテナの中から書き込むと、コンテナ内の実行ユーザーのuidとgidで書き込まれてしまって、ホスト側から触れない。さて、困った。ってなった。

あれー?Macのときはこんなことあったっけ?って思ってたら、Linuxの場合だけみたい。最近Dockerのそういうのばっかりひっかかってるから、なんか慣れてきた!

対応策

んで、ここにいくつか対応策が紹介されてて。そっかー。ってなった。

qiita.com

この中の最後の「実行ユーザーのuidとgidを実行時にentrypoint.shで書き換えてホスト側のものと同じにする」ってのが今の僕のやりたいことに合ってるかもなぁと思いながら・・・。

他にも面白い記事ないかなー

って探してみたら、こういう記事を見つけた。

boxboat.com

へー。コンテナの中にこのfixuidプログラムを置いて実行すれば、さっきのQiitaの記事でやってることをやってくれるっぽい。便利そう。と思いながら読んでて。

あれ?でもUSER sample:sampleみたいに実行ユーザーを指定してるのに、どうやってuidとgidを書き換えてるんだろう?と思ったので

コードを読んでみた

https://github.com/boxboat/fixuid/blob/05869a9ead4f95f7175564984a6ec52fb8ed009d/fixuid.go#L349-L379

   if err := ioutil.WriteFile("/etc/passwd", []byte(newLines), 0644); err != nil {
        return err
    }

Golang分からんけど、/etc/passwd を書き換えてるっぽい。権限なさそうなのになんで書き換えられるんだろう?と思って見てみたら、この辺。

https://github.com/boxboat/fixuid/blob/05869a9ead4f95f7175564984a6ec52fb8ed009d/fixuid.go#L48-L55

// check that script is running as root
if os.Geteuid() != 0 {
        logger.Fatalln(`fixuid is not running as root, ensure that the following criteria are met:
    - fixuid binary is owned by root: 'chown root:root /path/to/fixuid'
    - fixuid binary has the setuid bit: 'chmod u+s /path/to/fixuid'
    - NoNewPrivileges is disabled in container security profile
    - volume containing fixuid binary does not have the 'nosuid' mount option`)
}

あれ?rootで実行されてるって書いてる。

このGeteuid()ってなんだろうなー?

と思って調べたら、この記事見つけて、へーってなった。

Linuxの実効ユーザIDについて実験してみた – ブーログ

実行ファイルのオーナーがroot:rootで、パーミッションが4755だったら、一般ユーザーで実行してもroot権限で書き込めるってことなのかな。

試してみよう!

ということで、実行ファイルを作るのをGoでやってみることにした。

Go書くのはじめてだー!って思ってダウンロードしたら、既にインストールされてて、はて・・・?いつの間に?記憶にないぞ?ってなりつつバージョンアップ。

みようみまねでこんな感じのhello.goを書いた。心を込めていっこずつググりながら書いたから結構時間かかったー。

package main

import "fmt"
import "os"

func main() {
  fmt.Printf("uid: %d\n", os.Getuid())
  fmt.Printf("euid: %d\n", os.Geteuid())

  file, err := os.Create("sample.txt")
  if err != nil {
    panic(err)
  }
  defer file.Close()

  _, err = file.WriteString("Hello")
  if err != nil {
    panic(err)
  }
}

で、ビルドして実行ファイルの権限を確認。Goってお手軽だなー。

❯ go build hello.go

❯ stat --format='%a %U:%G' hello
775 bufferings:bufferings

775で、僕がオーナーになってる。

じゃ、まずは

普通のファイルには書き込めることを確認しとこう。

❯ touch sample.txt

❯ ./hello
uid: 1000
euid: 1000

❯ cat sample.txt
Hello

OKだね。

次は

権限がなかったら書き込めないことを確認。

❯ rm sample.txt

❯ sudo touch sample.txt

❯ ls -al sample.txt
-rw-r--r-- 1 root root 0  8月 26 01:33 sample.txt

❯ ./hello
uid: 1000
euid: 1000
panic: open sample.txt: permission denied

goroutine 1 [running]:
main.main()
        /path/to/project/hello.go:12 +0x1d7

OKだね。

最後に

実行ファイルのオーナーと権限を変えて実行してみよう

❯ sudo chown root:root ./hello

❯ sudo chmod 4755 ./hello

❯ stat --format='%a %U:%G' hello
4755 root:root

❯ ./hello
uid: 1000
euid: 0

❯ cat sample.txt
Hello

おー。書きこめた。こんな仕組み全然知らなかったなー。面白かった。

ところで

元々のVolumeマウントの問題は、色々考えたんだけど僕のこのマシンでしか使わないからuidとgidを1000固定でDockerfileに書いちゃうことにしようと思う。

「PHPはどのように動くのか」を読んだ。その後、Zend EngineとGCのこともちょこっと勉強。

娘の絵本を書いに行った本屋で、面白そうだなーと思って買ってみた。

books.rakuten.co.jp

感想

面白かった!流し読みしただけだけど。「俺、今、難しい本を読んでるぞ!」って雰囲気で「なるほど?」とか言うのを楽しんだ(分かってない

第2章 オペコードのパフォーマンスを考える

オペコードを見ながら「こうなるからパフォーマンスに違いがでるんだよ」って教えてくれてるの「へー!」ってなって面白かった。

第3章 PHPコアの仕組みと開発の定石を知る

zval構造体とかコピーオンライトとかHashTableの仕組みとかの説明が書いてあって面白かった。「zvalは、どの型にも対応している、美しく万能な構造体です」ってところが好き。

第4章 オブジェクト指向だとなぜ遅いのか

第5章 PHP7はなぜ速くなったか

ここまでの説明が全部つながってる感じがしたなー。PHP5とPHP7のコピーオンライトの対応の違いがzvalの作りからも分かるの嬉しい。「PHP7ではその(zvalの)美しさを捨てて、型を差別化することにしました」ってところが好き。

その後の章は

ExtensionとZend Engineのハックなので、本当にさらっと読んだ。

全体的に

自分の理解力のせいでふわっとしか分かってないけど、でも裏側でどういうことが起こってるのかを雰囲気知ることができたので、楽しかった!

読んだ後

Zend Engineの名前のルーツはなんだろう?って気になって見つけた記事。Zendって名前はそういうことなのかー。

[ThinkIT] 第1回:意外と知らないZend Engine (1/3)

Zend Engineについてのスライド。めっちゃ分かりやすい。

www.slideshare.net

そのスライドの中で紹介されてたGCのお話のスライド。これもめっちゃ分かりやすい。

www.slideshare.net

なるほど?

❯ cat hello.php
<?php

$name = "World";
echo "Hello, {$name}";

❯ phpdbg -p\* hello.php
function name: (null)
L1-5 {main}() /path/to/hello.php - 0x7fde320700a0 + 5 ops
 L3    #0     ASSIGN                  $name                "World"                                  
 L4    #1     NOP                                                                                   
 L4    #2     FAST_CONCAT             "Hello, "            $name                ~1                  
 L4    #3     ECHO                    ~1                                                            
 L5    #4     RETURN<-1>              1                                                             
[Script ended normally]

さて

普通のPHP入門の勉強に戻ろっと。

「初めてのPHP」を読んだ。うん。読んだ。

PHP初心者だからPHPの基本を知りたいなーと思って「初めてのPHP」を読んだ。

books.rakuten.co.jp

感想

疲れた(ヽ´ω`)

・・・あれ?

読みながら、フォームとは?とか、HTTPとは?Cookieとは?みたいなWebアプリの話は別にいいからPHPの文法とかの基本的な話って、いつでてくるのかなー?って半分くらいまでいったところでうすうすそんな気がしてたんだけど・・・載ってなかった!

買う本まちがえちゃったやw

気になったこと

「プログラミングやりたい!」って人が最初にこの本を読んだら結構その後大変そうだなー。と思った。仕事ではこういう書き方はしないと思うし、こういう書き方だとセキュリティの穴をいっぱい作ってしまいそう。

学び

でもまぁ面白かった。たまにはこういう基本を振り返るような本も良いね。そもそもPHPよく分かってないところからだったから雰囲気が少し分かったし、色々と学びもあったし。疑問もでてきたし。

  • 文字列が引用符の中で改行OKだからヒアドキュメントっぽく使えそうだけど、みんなはヒアドキュメントとの使い分けどうしてるんだろう?
  • 小数が、浮動小数点数しかでてこなかったけどお金の計算とかは、なんかライブラリーがあるんかな?
  • 数値の最大最小値ってどれくらいなんだろうな?longとかdoubleはないんかなー?
  • $は中括弧の外じゃなくて中に入るんやね。"{$preparation}d $meat"
  • false判定されるの色々ある。0、0.0、空文字列、文字列"0"、定数false、定数null、空の配列。あぶない匂いがする。
  • elseifJavaと違って繋がってる。(どうでもいいか
  • &&||は左側の式だけで判断できるときに、右側の式はチェックされないのかされるのかが気になる。
  • グローバル変数と同じ名前の変数を関数の中で使っても、別の変数として扱われる。
  • 引数の型宣言のbool, float, int, stringはPHP7以降。返り値の型も7以降。
  • namespaceの区切り文字はバックスラッシュ。useasで別名つけられるのいいなー。
  • ??の名前がnull合体演算子(PHP7から)。なんかすごい名前。Groovyのエルビス演算子みたいなものなのかな。
  • list構文で配列を分解して受け取ることができるのかー。
  • PHP REPL便利そう。
  • PSRっての調べておいた方が良さそう。
  • Zendとは?
  • PHPにもOOMとかあるんかな?
  • マルチスレッドみたいなの気にする?

この辺をチェックしながら勉強していこうと思うー!

文法とかなら

公式ドキュメント読むと良いよって教えてもらったので読んでみようと思う。最初にチェックしとけよって自分に言いながら。

PHP: PHP マニュアル - Manual