GAE/SE PHP 7.2 標準で提供されていない拡張を使用する

# はじめに

GAE/SE PHP 7.2 環境は 2018/08/30 現在 ベータ版です。この記事で書いた内容が GA になるまでに仕様が変わる可能性もあるかと思いますので、ご注意ください。

# Google App Engine PHP 7.2 Standard Environment 

Google App Engine Standard Envirionment (GAE/SE) の PHP は、長らく 5.5 という今となってはサポートが切れたバージョンが提供されていたのですが、2018/08 に PHP 7.2 の環境がベータ版になりました。

PHP 7.2 環境は、PHP 5.5 環境とは違い、gVisor を使った 2nd Gen としての提供となります。

このあたりの話に関しては、 2018/08/29 に開催された [第129回 PHP勉強会@東京](https://phpstudy.doorkeeper.jp/events/78717) で発表してきたので、今までとの違い等はその資料を参照してみてください。

https://speakerdeck.com/kunit/google-app-engine-php-7-dot-2

# GAE/SE PHP 7.2 においての拡張の扱い

GAE/SE PHP 7.2 環境では、以下の拡張がデフォルトでロードされます。
MySQL/PostgreSQL の両方共使えるようになっていますし、intl 拡張があるのはわかってる感があります。

- BCMath
- bz2
- Calendar
- core
- cgi
- ctype
- cURL
- date
- dba
- dom
- enchant
- Exif
- fcgi
- fileinfo
- filter
- FTP
- GD
- gettext
- GMP
- hash
- iconv
- intl
- json
- LDAP
- libxml
- mbstring
- MYSQLi
- mysqlnd
- MySQL (PDO)
- OPcache
- OpenSSL
- PCNTL
- pcre
- PDO
- pgsql
- Phar
- posix
- PostgreSQL (PDO)
- Reflection
- session
- Shmop
- SimpleXML
- SOAP
- Sockets
- SPL
- SQLite (PDO)
- SQLite3
- standard
- test
- tidy
- tokenizer
- XML
- XMLreader
- XMLrpc
- XMLwriter
- XSL
- zend
- Zip
- Zlib

また、以下の拡張はデフォルトではロードされませんが、php.ini に設定を書くことによりロードすることができます。

- Memcached
- gRPC
- protobuf
- MongoDB
- ImageMagick
- OpenCensus
- PHPRedis
- Stackdriver Debugger

それぞれ、以下のように php.ini に書けばいいだけです。

```php.ini
extension=memcached.so
extension=grpc.so
extension=protobuf.so
extension=mongodb.so
extension=imagick.so
extension=opencensus.so
extension=redis.so
extension=stackdriver_debugger.so
```

このあたりの話は、以下のURLで説明されています。

- https://cloud.google.com/appengine/docs/standard/php7/runtime#dynamically_loadable_extensions

# 標準以外の拡張が使いたい場合はどうしたらいいのか？

標準で用意されているものでも結構行けそうな気がしなくもないですが、用意されていないものが使いたくなった場合はどうしたらいいんだろうということで、試してみたところ、以下のような方法でいけました。

- Linux 環境で拡張を build し、xxx.so を作る(elfバイナリを準備する)
- それをデプロイするディレクトリに含まれるように配置する
- xxx.so ごと、gcloud app deploy する

例えば、 APCu が現時点では標準では使用することができません。
APCu を使うとすると以下のような手順を踏むことになります。

- build するための Linux 環境を準備する(※注意 追記に書きましたが、Ubuntu 18.04 環境を準備するのがいいと思います)
- APCu のソースを取得する
- build する (phpize; ./configure; make みたいな手順)
- modules/apcu.so ができるので、それをアプリのディレクトリコピー

今回以下の拡張を build して、デプロイして、ロードされていることを確認しました。

- APCu
- uopz
- runkit7
- timecop
- xdebug

上記の拡張を modules ディレクトリにコピーしておいて、以下のような php.ini を書いてデプロイしました。

```php.ini
extension=/srv/modules/apcu.so
extension=/srv/modules/uopz.so
extension=/srv/modules/runkit.so
extension=/srv/modules/timecop.so
zend_extension=/srv/modules/xdebug.so
```

## APCu

![gae-php72-apcu.png](https://qiita-image-store.s3.amazonaws.com/0/111934/fb16460d-fa81-2235-7900-a77ea211a461.png)

## uopz

![gae-php72-uopz.png](https://qiita-image-store.s3.amazonaws.com/0/111934/f6e7c0b4-8129-cef3-0478-268fab70e565.png)

## runkit7

![gae-php72-runkit.png](https://qiita-image-store.s3.amazonaws.com/0/111934/69bfa703-45a7-4ca7-2acf-2b854466f6b0.png)

## timecop

![gae-php72-timecop.png](https://qiita-image-store.s3.amazonaws.com/0/111934/1013562e-52f8-f0b5-a57a-6d9ddd2de4be.png)

## xdebug

![gae-php72-xdebug.png](https://qiita-image-store.s3.amazonaws.com/0/111934/e25ce21f-713b-3377-fe07-46526fb525d4.png)
![gae-php72-xdebug-2.png](https://qiita-image-store.s3.amazonaws.com/0/111934/396d0d4b-7ba5-ae2c-2349-2d433154b2f6.png)

# PaaS の自由度

PHP の場合、機能を追加するのが拡張というバイナリになるため、PaaS だとそれが自由に追加できないために、IaaS を使うみたいなことがあったと思うのですが、GAE/SE PHP 2nd Gen であれば、ある程度は自由がきくようです。

といっても、APCu くらいは標準で入っておいてほしいとは思う(memcached 同様に、自由に on/off できる形でいい)ので、標準で入れといてほしいものはリクエストしたほうが良いと思います。

リクエストの仕方は以下のURL に記載されていますので、リクエストしてみてはいかがでしょうか？

- https://cloud.google.com/appengine/docs/standard/php7/reference/enabled-extensions#requesting_a_package

# 最後に

GAE/SE PHP は 7.2 という使いやすいバージョンの提供が始まるので、今後いろんな活用ができるのではないかと思っています。

引き続きいろいろとしらべて、なにかいい感じのことがわかったらまた記事を書きます。

# 2018/08/31 追記

xxx.so が libc に依存するから、build する環境と実行環境の libc のバージョンがあってないとだめなのでは？という指摘をいただきました。今回で言うと Ubuntu 18.04 上で build したものがちゃんと動いたということになります。

# 2018/08/31 追記2

更に中身をみてみたら、Ubuntu 18.04 ベースの Docker Container が動いているっぽいので、今回はたまたまストライクだったっぽい。