

php:7.2-fpm-alpine3.12
コンテナイメージが、vscode-v1.77
以降のDevContainersでvscode-serverの起動エラーでコンテナに接続出来なくなったので、alpine-v3.16
以降の
コンテナイメージへのアップグレードの必要に迫られた。
[[VsCode v1.77以降のDevContainers拡張でalpine v3.12コンテナに接続できない]]
php公式イメージで要件を満たすもっとも世代の近いイメージphp:7.4-fpm-alpine3.16
でphp-v7.4
に対応するphalcon
のバージョン要件がv4
以降のため、phalconをv3
からv4
にメジャーアップデートする際の対応録。
イメージビルド編
ベースイメージの変更
# FROM php:7.2-fpm-alpine
FROM php:7.4-fpm-alpine3.16
oniguruma
docker-php-ext-install
ツールでmbstring
をインストールしようとすると依存ライブラリのoniguruma
がないといってビルドに失敗する。
が、php:7.4-fpm-alpine3.16
にはそもそもoniguruma
非依存のmbstring
がセットアップ済みのため、追加インストールなど不要だったのでシンプルにdocker-php-ext-install
からmbstring
を削除して解決。
FROM php:7.4-fpm-alpine3.16
RUN docker-php-ext-install pdo_mysql mysqli mbstring < これ
#5 15.29 configure: error: Package requirements (oniguruma) were not met:
#5 15.29
#5 15.29 Package 'oniguruma', required by 'virtual:world', not found
#5 15.29
#5 15.29 Consider adjusting the PKG_CONFIG_PATH environment variable if you
#5 15.29 installed software in a non-standard prefix.
#5 15.29
#5 15.29 Alternatively, you may set the environment variables ONIG_CFLAGS
#5 15.29 and ONIG_LIBS to avoid the need to call pkg-config.
#5 15.29 See the pkg-config man page for more details.
備忘録として
こちらさまによるとphp-v7.4
らへんのmbstring
ビルドではoniguruma
という荒々しい名の正規表現ライブラリに依存するようになったらしく、libonig-dev
というパッケージに収納されているとのこと。apk
ではこちらさまのとおりoniguruma-dev
というパッケージ名で配布されていた。oniguruma-dev
のインストール追加でイメージビルドは成功した。
# RUN docker-php-ext-install pdo_mysql mysqli mbstring
# docker-php-ext-installからmbstringを削除してapkでoniguruma-devをインストールする
RUN docker-php-ext-install pdo_mysql mysqli mbstring
apk add --no-cache oniguruma-dev < これ
phalcon
phalconのソースをバージョンを4.0系のlatestバージョンv4.0.6
に変更
RUN cd /usr/local \
# phalconのビルドソースを3系から4系に変更
# && git clone https://github.com/phalcon/cphalcon.git -b v3.4.3 \
&& git clone https://github.com/phalcon/cphalcon.git -b v4.0.6 \
&& cd cphalcon/build \
&& sh install \
&& echo "extension=phalcon.so" > /usr/local/etc/php/conf.d/phalcon.ini \
psr
コンテナを起動してhttpアクセスするとphpワーニングでUncaught Error: Class 'Phalcon\Config' not found
え?メジャーアップデートでnamespaceがっつり変わった?と焦るも、公式見てもPhalcon\Config
は健在だ。
ビルド失敗している?と思ってphpのロードモジュールを確認すると、psr
モジュールがローディングできてない?からphalconモジュールがローディングできていないようだ。
php -m | grep phalcon
PHP Warning: Cannot load module 'phalcon' because required module 'psr' is not loaded in Unknown on line 0
phalcon-v4
からpsr
に対応するためライブラリ依存するようだ。
Fatal error: Uncaught Error: Class 'Phalcon\Config' not found
Php can not load module phalcon
Installation - Phalcon Documentation
Dockerfileにpecl-psrのインストールコマンドを追加して、phalconモジュールのローディングの前にローディングする
Phalconをdocker imageに詰め込みたいとき
# xdebugのインストール
RUN pecl install psr \
&& docker-php-ext-enable psr \
&& echo "extension=psr.so" >> /usr/local/etc/php/conf.d/phalcon.ini \
&& echo "extension=phalcon.so" >> /usr/local/etc/php/conf.d/phalcon.ini \
xdebugバージョン
xdebug3.2.0でphp7がサポート対象外になったのでDockerfileを直した
xdebug-v3.2.0
以降、php-v7
がサポート対象外になったため、xdebugはバージョン指定でアーカイブDLする
[ 5/17] RUN pecl install xdebug && docker-php-ext-enable xdebug:
> #9 5.238 pecl/xdebug requires PHP (version >= 8.0.0, version <= 8.2.99), installed version is 7.3.29
> #9 5.238 No valid packages found
> #9 5.238 install failed
peclではxdebug-{バージョン}
でアーカイブがディストリビュートされている
RUN pecl install xdebug-3.1.6 && docker-php-ext-enable xdebug
アプリケーション編
How to upgrade - Phalcon Documentation
Class 'Phalcon\Session\Adapter\Files' not found
サーバーセッションのファイルアダプタクラスはv4でPhalcon\Session\Adapter\Stream
に置き換えられた
Phalcon 4.0 setting up Session
# => Class 'Phalcon\Session\Adapter\Files' not found
$di->setShared('session',function(){
$session = new \Phalcon\Session\Adapter\Files();
$session->start();
return $session;
});
// 保存先`savePath`を指定する
$di->setShared('session',function(){
$session = new Phalcon\Session\Manager();
$files = new Phalcon\Session\Adapter\Stream( [
'savePath' => '/tmp',
]);
$session->setAdapter($files)->start();
return $session;
});
Fatal error: Uncaught Error: Call to undefined method
Phalcon\Logger\Adapter\Stream::log()
v3ではPhalcon\Logger\Adapter\Stream
が出力log()
と出力先のストリームアダプタを担っていたが、v4から出力はPhalcon\Logger
に分離されてPhalcon\Logger\Adapter\Stream
を利用する形に変更となった。ログのインターフェースはpsr-3準拠。
ということでアダプタがlog()など知らんと言っている。
Fatal error: Uncaught Error: Call to undefined method Phalcon\Logger\Adapter\Stream::log() - Discussion - Phalcon Framework
Phalcon logger - Phalcon Documentation
PSR-3: Logger Interface 読了 #PHP - Qiita
$formatter = new Phalcon\Logger\Formatter\Line("[%date%] %message%");
$formatter->setDateFormat('Y/m/d H:i:s');
$adapter = new Phalcon\Logger\Adapter\Stream("php://stdout");
$adapter->setFormatter($formatter);
$logger = new Phalcon\Logger(
// ロガーに名前をつけられるがマニュアルに書いてないのでとりあえず任意名
// public function __construct( string $name, array $adapters = [] );
'hoge',
[
// 任意名のラベル名。Loggerからラベルに対してアダプタを選択したりできる。
'stdout' => $adapter,
]
);
$logger->info('this is log message');
$application->handle(); triggers a "Wrong number of parameters"
フレームワークのエントリポイントapplication#handle()で
はリクエストURIをとるようになった
$application->handle(); triggers a "Wrong number of parameters" error after last upgrade - Discussion - Phalcon Framework
// Handle the request
$application = new Phalcon\Mvc\Application();
# $application->handle(); triggers a "Wrong number of parameters"
$response = $application->handle();
$response->send();
// Handle the request
$application = new Phalcon\Mvc\Application();
$request = new Phalcon\Http\Request();
$response = $application->handle($request->getURI());
$response->send();
Phalcon\Mvc\Router#handle()
も同じく
// triggers a "Wrong number of parameters"
$router->handle();
$request = new Phalcon\Http\Request();
$router->handle($request->getURI());
Class 'Phalcon\Mvc\Url' not found
Phalcon\Mvc\Url
はv4でPhalcon\Url
になった。そしてv5ではまさかのPhalcon\Mvc\Url
になった
VoltEngine#setOptionsのキーが変わった
compiled
プレフィックスがなくなった
How to disable volt cache - Discussion - Phalcon Framework
$volt = new Phalcon\Mvc\View\Engine\Volt()
$volt->setOptions(
[
'compiledPath' => BASE_PATH . $config->application->cacheDir,
'compiledExtension' => '.compiled',
'compiledSeparator' => '_',
'stat' => true,
'compiledAlways' => true
]
);
$volt = new Phalcon\Mvc\View\Engine\Volt()
$volt->setOptions(
[
'path' => BASE_PATH . $config->application->cacheDir,
'extension' => '.compiled',
'separator' => '_',
'stat' => true,
'always' => true
]
);
Too few arguments to function {closure}(), 2 passed …
DIに渡すクロージャに設定していた引数がエラーになったので、キャプチャで渡す。変更になったのか元々バグっていてpsrで顕在化したのかな。
Task Too few arguments to function {closure}(), 2 passed and exactly 4 expected · Issue #4576 · swoole/swoole-src
// $di->setShared('voltService', function ($view, $di) use ( $config ){
$di->setShared('voltService', function () use ($config){
$di = Phalcon\DI::getDefault();
$volt = new Volt($di->get('view'), $di);
$volt->setOptions(
[
'path' => BASE_PATH . $config->application->cacheDir,
'extension' => '.compiled',
'separator' => '_',
'stat' => true,
'always' => true
]
);
return $volt;
}
);
Fatal error: Cannot override final method Phalcon\Mvc\Model::getSource()
Model::getSource()
はオーバーライド不可となったのでイニシャライザにModel::setSource('テーブル名')
で指定する
Fatal error: Cannot override final method Phalcon\Mvc\Model::getSource() - Discussion - Phalcon Framework
public function initialize()
{
$this->setSchema("phalcon_demo-app");
$this->setSource("users");
}
Fatal error: Uncaught Error: Class 'Phalcon\Validation\Validator' not found
カスタムバリデーションの実装で問題が発生
-
Phalcon\Validation\Validator
はアブストラクトクラスPhalcon\Validation\Validator
に置き換えられた - PHP7型宣言の厳格化でオーバーライドに戻り値の宣言が必要
// phalcon v4でのカスタムバリデーションクラス実装
class CustomEmailValidator extends \Phalcon\Validation\AbstractValidator implements \Phalcon\Validation\ValidatorInterface
{
public function validate(Validation $validation, $attribute): bool { ... }
}
Fatal error: Declaration of { 関数宣言 } must be compatible with { 関数宣言 }: string
PHP7型宣言の厳格化でオーバーライドに戻り値の宣言が必要
Phalcon\Model::findFirst to return null instead of false if no record was found
Phalcon\Model::findFirstで結果が無い場合に戻り値false
がnull
になった
変更箇所が多岐にわたるので、モデルクラスでfindFirstをオーバーライドしてnullの場合はfalseを返却して後方互換性を維持する
Model::saveのホワイトリストが効かない
The save() method no longer accepts parameters to set data. You can use assign instead.
// フィールドnullになる
$model->save($assign_key_val, $whitelist_key);
// assignに変更
$model->assign($assign_key_val);
$model->save();