PHP 7(.4)のDockerコンテナ(fpm-alpine)にphp-mecabを導入してPHPでMeCabを使う

DockerのPHPイメージにMeCabとmecab-ipadic-NEologdを導入して、PHPから使えるように設定する方法を紹介します🌱

PHPフレームワークやWebサーバーを導入せず、PHPでMeCabを使えるかどうかまで確認します。ここで導入できたら必要なものを追加しましょう✨

PHPのイメージは次を用いて確認しています。

```dockerfile:Dockerfile
FROM php:7.4.12-fpm-alpine
```

## docker-composeの設定

起動・終了を簡単にするためdocker-composeを用います。次の `docker-compose.yml` をプロジェクトのルートに作成します。

 * PHPコンテナにMeCabをインストールしてカスタムでコンテナを作るため、新規作成するDockerfileの場所を`build`の`dockerfile`で指定します
 * `volumes` にはPHPでMeCabを使うサンプルスクリプトを配置するホスト側のディレクトリとコンテナ側のディレクトリをマウントします
 * PHPのコンテナを起動させ続けるために `tty` をtrueにしておきます

```yaml:docker-compose.yml
version: '3'

services:
  php-mecab:
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - ./src:/app
    tty: true
```

## MeCabとmecab-ipadic-NEologdを導入する

同じくプロジェクトのルートに`Dockerfile` を作成して、PHPのコンテナにMeCabとmecab-ipadic-NEologdを導入します。  

古い記事ですが、PHP7.4.12の現在もこちらの記事と同じ方法で構築できます。
https://qiita.com/nownabe/items/4171776aec1f05de9f28

```dockerfile:Dockerfile
FROM php:7.4.12-fpm-alpine

## ここから
# https://qiita.com/nownabe/items/4171776aec1f05de9f28#dockerfile
RUN apk add --update --no-cache build-base

ENV MECAB_VERSION 0.996
ENV IPADIC_VERSION 2.7.0-20070801
ENV mecab_url https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE
ENV ipadic_url https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM
ENV build_deps 'curl git bash file sudo openssh'
ENV dependencies 'openssl'

RUN apk add --update --no-cache ${build_deps} \
  # Install dependencies
  && apk add --update --no-cache ${dependencies} \
  # Install MeCab
  && curl -SL -o mecab-${MECAB_VERSION}.tar.gz ${mecab_url} \
  && tar zxf mecab-${MECAB_VERSION}.tar.gz \
  && cd mecab-${MECAB_VERSION} \
  && ./configure --enable-utf8-only --with-charset=utf8 \
  && make \
  && make install \
  && cd \
  # Install IPA dic
  && curl -SL -o mecab-ipadic-${IPADIC_VERSION}.tar.gz ${ipadic_url} \
  && tar zxf mecab-ipadic-${IPADIC_VERSION}.tar.gz \
  && cd mecab-ipadic-${IPADIC_VERSION} \
  && ./configure --with-charset=utf8 \
  && make \
  && make install \
  && cd \
  # Install Neologd
  && git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git \
  && mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y \
  # Clean up
  && apk del ${build_deps} \
  && rm -rf \
    mecab-${MECAB_VERSION}* \
    mecab-${IPADIC_VERSION}* \
    mecab-ipadic-neologd
    
## ここまで
```

## php-mecabを導入する

MeCabをPHPで使う場合はphp-mecabモジュールを導入する必要があります。Dockerfileを作るポイントとしては次のとおりです。

* `autoconf` を導入しないとphp-mecabのビルドに必要な `configure` が生成されない
* `php-config`, `mecab-config` は `/usr/local/bin/` 以下に配置されている

このポイントを踏まえてphp-mecabを導入するため **Dockerfileに追記すると** 次のようになります。

```dockerfile:Dockerfile
# ...
## ここまで

## ここから追記する
ENV build_deps_phpmecab 'git autoconf'
COPY php.mecab.ini /usr/local/etc/php/conf.d/
RUN apk add --update --no-cache ${build_deps_phpmecab} \ 
  && git clone https://github.com/rsky/php-mecab.git \
  && cd ./php-mecab/mecab \
  && phpize \
  && ./configure --with-php-config=/usr/local/bin/php-config --with-mecab=/usr/local/bin/mecab-config \
  && make \
  && make test \
  && make install \
  # Clean up
  && cd  \
  && rm -rf php-mecab \
  && apk del ${build_deps_phpmecab}

# ▼▼このコマンドが最後に来るようにしてください
RUN docker-php-ext-install pdo pdo_mysql
```

`php.mecab.ini` をCOPYしていますが、次の手順でこのファイルを作成します。


### PHPからMeCabモジュールを読み込む

導入したphp-mecabのモジュールをPHPで有効にするため、PHPの設定ファイル(`php.mecab.ini`)を作成して`mecab.so`を指定します。

```ini:php.mecab.ini
extension=mecab.so
```

最終的には次のファイル構成になります。

```
$ tree
.
├── Dockerfile
├── docker-compose.yml
└── php.mecab.ini

```

## PHPでMeCabを使う

PHP7向けに `MeCab_Tagger` から `\MeCab\Tagger` に変更されています。 **バックスラッシュもそのまま使います。**

```php:sample_php_mecab.php
<?php
        $str     = 'センテンススプリングでも文春でもどっちでもいいだろ';
        $options = array('-d', '/usr/local/lib/mecab/dic/mecab-ipadic-neologd');
        $mecab = new \MeCab\Tagger($options);
        $nodes = $mecab->parseToNode($str);
        echo $str . "\n";
        foreach ($nodes as $n) {
            $stat = $n->getStat();
            // 単語かどうか
            if ($stat != 0) {
                continue;
            }
            $features = explode(',', $n->getFeature());
            if ($features[0] !== '名詞') {
                continue;
            }
            // 単語
            echo "Surface: " . $n->getSurface() . "\n";
        }
```

```
docker-compose up --build -d php-mecab
docker-compose exec php-mecab /bin/sh
php /app/sample_php_mecab.php
```

これでMeCabが使えるPHPのコンテナが作成できます。
この構成ではWebブラウザで表示して確認することはできないので、

 * Laravelなどのフレームワークを導入して開発用サーバーを立ち上げる
 * 別途NginxなどのWebサーバーのコンテナを導入して、このPHPコンテナで動作しているFPMと接続させる

などの作業は必要です。

## 参考

Alpine LinuxでMeCab with NEologd - Qiita
https://qiita.com/nownabe/items/4171776aec1f05de9f28

phpでmecab - Qiita
https://qiita.com/kojirock5260/items/1787d70b9cfca3e43d12

phpizeでエラー : てるてる坊主
http://teru2-bo2.blogspot.com/2012/05/phpize.html

PHP7.0+mecabでハマった事 - Qiita
https://qiita.com/murota/items/3c76cc3ca0fd819dbac7