概要
PHP Extensionとして追加したいモジュールがあったので、まずはdockerを利用し、その開発環境を構築しました。
dockerの設定
以前、Docker Toolboxを利用し、Webアプリのローカル開発環境(Apach+PHP, MySQL)を構築しました。
こちらの設定を変更し、環境構築していきます。
docker関連ファイルの編集
- フォルダ・ファイル構成
./docker/
|-- docker-compose.yml
|-- web
| |-- Dockerfile
|-- html
|-- index.php
docker-compose.ymlは、以下のように編集します。
dbは必要ないので設定から削除します。
$ vim docker-compose.yml
version: '2'
services:
web:
build: ./web
ports:
- '80:80'
volumes:
- ./html:/var/www/html
web/Dcokerfileは、以下のように編集します。
Webサーバ(apache)の設定は、ブラウザでphpinfoの設定を確認したり、動作確認・デバッグなどに利用したいため残しています。
$ vim web/Dcokerfile
FROM php:5.6-apache
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]
RUN ["apt-get", "install", "-y", "git"]
COPY ./php.ini /usr/local/etc/php/php.ini
以下のPHP設定ファイル(php.ini)を用意し、ゲスト環境にコピーします。
enable_dl = On
することで、拡張ライブラリ(dllやsoファイル)の読み込みを有効にします。デフォルトではOffでPHP Extensionで開発したライブラリを読み込むことができないため有効にします。(その他の設定はオプション)
$ vim web/php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
enable_dl = On
ブラウザでのPHP設定情報確認のためindex.phpはphpinfo()を呼んでいます。
$ vim html/index.php
<?php phpinfo();
設定変更後、リビルドしコンテナを起動します。
$ docker-compose build
.....
Successfully built 033265de3a17
$ docker-compose up -d
Creating network "docker_default" with the default driver
Creating docker_web_1
PHPのソースダウンロード
PHPのソースコードをローカルにダウンロードするため公式PHPのミラーリポジトリをクローンします。
$ docker-compose run web bash
$ git clone https://github.com/php/php-src.git
webコンテナのPHPバージョンが5.6なので、同一バージョンのソースをチェックアウトします。
$ php -v
PHP 5.6.30 (cli) (built: Mar 21 2017 23:01:57)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
$ cd php-src/
$ git checkout -b PHP-5.6.30 origin/PHP-5.6.30
PHP Extensionスケルトンプロジェクトの作成
PHP Extensionのスケルトンプロジェクトを作成します。
作成にあたり、以下のサイトを参考にさせていただきました。
DSAS開発者の部屋
Born Too Late
$ cd ext/
$ ./ext_skel --extname=helloworld
Creating directory helloworld
Creating basic files: config.m4 config.w32 .gitignore helloworld.c php_helloworld.h CREDITS EXPERIMENTAL tests/001.phpt helloworld.php [done].
以下のようにビルドに必要な設定(16-18行目をコメントイン)を反映します。
$ cd helloworld/
$ vim config.m4
16 PHP_ARG_ENABLE(helloworld, whether to enable helloworld support,
17 Make sure that the comment is aligned:
18 [ --enable-helloworld Enable helloworld support])
以下のようにビルドします。
$ phpize
Configuring for:
PHP Api Version: 20131106
Zend Module Api No: 20131226
Zend Extension Api No: 220131226
$ ./configure
.....
creating libtool
appending configuration tag "CXX" to libtool
configure: creating ./config.status
config.status: creating config.h
$ make
.....
Build complete.
Don't forget to run 'make test'.
正常にビルドが完了すると、以下のモジュールができます。
$ ls modules/
helloworld.la helloworld.so
動作確認の前に、拡張モジュールのディレクトリを確認し、作成したモジュールをそのディレクトリにコピーします。
ブラウザでphpinfoとして出力されたextension_dirを確認しても大丈夫です。
$ php -i | grep extension_dir
extension_dir => /usr/local/lib/php/extensions/no-debug-non-zts-20131226 => /usr/local/lib/php/extensions/no-debug-non-zts-20131226
$ cp modules/helloworld.so /usr/local/lib/php/extensions/no-debug-non-zts-20131226/helloworld.so
最後に動作確認します。helloworld.php
はビルド時に自動で生成されたファイルです。
$ php helloworld.php
Functions available in the test extension:
confirm_helloworld_compiled
Congratulations! You have successfully modified ext/helloworld/config.m4. Module helloworld is now compiled into PHP.
また、以下のようにtest.phpを作成し、動作確認もしてみます。confirm_helloworld_compiled
は自動で生成された確認用関数です。
$ vim test.php
<?php
dl('helloworld.so');
$str = confirm_helloworld_compiled("helloworld");
echo "$str\n";
?>
$ php test.php
Congratulations! You have successfully modified ext/helloworld/config.m4. Module test is now compiled into PHP.
以上で、PHP Extensionのdocker開発環境が構築できました。
コンテナを再起動すると、extension_dirにコピーしたモジュールが消えてしまうので、docker-compose.ymlを以下のように設定し、リビルドしておきましょう。
$ vim docker-compose.yml
version: '2'
services:
web:
build: ./web
ports:
- '80:80'
volumes:
- ./html:/var/www/html
- ./html/php-src/ext/helloworld/modules/helloworld.so:/usr/local/lib/php/extensions/no-debug-non-zts-20131226/helloworld.so
参考