Phalcon

phalcon3から5にバージョンアップした際のMVC、Loaderの対応

phalcon3から5にバージョンアップした際にMVC・Module周り、Loaderで発生したHTTP ERROR 500やDeprecated対応

Phalcon\Loader not found

FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Class "Phalcon\Loader" not found in {path}

Phalcon\LoaderがPhalcon\Autoload\Loaderに変わったので修正。
https://docs.phalcon.io/5.0/ja-jp/upgrade > 一般的なメモ

Call to undefined method Loader::registerNamespaces()

FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined method Phalcon\Autoload\Loader::registerNamespaces() in {path}

registerNamespaces()がsetNamespaces()にリネームされたので修正。
https://docs.phalcon.io/5.0/ja-jp/upgrade#autoload

Call to undefined method Loader::registerClasses()

FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined method Phalcon\Autoload\Loader::registerClasses() in {path}

registerClasses()がsetClasses()にリネームされたので修正。
https://docs.phalcon.io/5.0/ja-jp/upgrade#autoload

Mvc\Application::handle() expects exactly 1 argument, 0 given

FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught ArgumentCountError: Phalcon\Mvc\Application::handle() expects exactly 1 argument, 0 given in {path}

handle()に$_SERVER["REQUEST_URI"]を渡す必要があるので、handle()の引数に$_SERVER["REQUEST_URI"]を追加。

-handle()
+handle($_SERVER["REQUEST_URI"])

https://docs.phalcon.io/5.0/ja-jp/application > 概要

ついでにhandle()周りの返却方法も変わっていたので修正。

続きを読む

phalcon3から5にバージョンアップした際のログイン、Securityの対応

phalcon3から5にバージョンアップした際にログイン回りで発生したエラー、Deprecated対応

Phalcon\Security not found

Class "Phalcon\Security" not found

https://docs.phalcon.io/5.0/ja-jp/upgrade#%E4%B8%80%E8%88%AC%E7%9A%84%E3%81%AA%E3%83%A1%E3%83%A2

「Phalcon\Security」から「Phalcon\Encryption\Security」に変更になったので、use文を変更。

Deprecated: Phalcon\Encryption\Security::checkHash()

[08-Jun-2023 10:06:48 UTC] PHP Warning:  Attempt to read property "password" on null in /{pathto}/app/controllers/IndexController.php on line 83
[08-Jun-2023 10:06:48 UTC] PHP Deprecated:  Phalcon\Encryption\Security::checkHash(): Passing null to parameter #2 ($passwordHash) of type string is deprecated in /{pathto}/app/library/util/Hash.php on line 49

ユーザー情報を取得できなかった場合に、比較するパスワードがnullのためエラーになっています。
ユーザー情報を取得できなかった場合、checkHash()しないようにしていたが、チェックが走るようになってしまっているのが原因。

findFirst()でユーザー情報を取得していたのだが、データがなかった場合にfindFirst()はfalseではなくnullを返すように変更されていました。
なので「$userData !== false」で比較していたところを「$userData !== null」に変更。

undefined method Session\Manager::isStarted()

Call to undefined method Phalcon\Session\Manager::isStarted()

sessionが開始しているかはisStarted()ではなくexists()を使う
https://docs.phalcon.io/5.0/ja-jp/session#exists

The session save path [/var/lib/php/session] is not writable

The session save path [/var/lib/php/session] is not writable

Sessionの保存先に書き込み権限がないので、権限付与かディレクトリのユーザー変更

今回は、/etc/php-fpm.d/www.confでUserとGroupをnginxに設定しているので、User:root,Group:apacheをnginxに変更

$ chown nginx:nginx /var/lib/php/session

そのほかのアップグレードで発生したエラー対応

phalcon3から5にバージョンアップした際のformの対応

phalcon3から5にバージョンアップした際にページネーションで発生したエラー、Deprecated対応

unexpected token "=>", expecting ")"

syntax error, unexpected token "=>", expecting ")"
#0 [internal function]: Phalcon\Mvc\View\Engine\Volt->render()
#1 [internal function]: Phalcon\Mvc\View->engineRender()
#2 [internal function]: Phalcon\Mvc\View->processRender()
#3 [internal function]: Phalcon\Mvc\View->render()
#4 {pathto}/public/index.php(30): Phalcon\Mvc\Application->handle()
#5 {main}

voltのform()の引数が変わったためにエラー。

引数を配列で渡せばOK

before

{{ form('login', 'id': 'loginForm', 'class': 'bf_form', 'onbeforesubmit': 'return false') }}

after

{{ form(['action': 'login', 'id': 'loginForm', 'class': 'bf_form', 'onbeforesubmit': 'return false']) }}

ただしこのままだと出力されるActionが変わってしまいます。
https://{ドメイン}/xxxxx だったのが、ドメイン無しのxxxxxになります。

今まで通りのActionで出力したい場合は、url()かformLegacy()を使用。

url()を使う場合は、form()の関数名はそのままで、'action'のパラメータにurl()を使用

{{ form(['action': url('login'), 'id': 'loginForm', 'class': 'bf_form', 'onbeforesubmit': 'return false']) }}

formLegacy()を使う場合は、'action'のパラメータはそのままで、form()の関数名を変更

{{ formLegacy(['action': 'login', 'id': 'loginForm', 'class': 'bf_form', 'onbeforesubmit': 'return false']) }}

formLegacy()について
https://docs.phalcon.io/5.0/ja-jp/upgrade#volt

Validator\PresenceOf not found

Class "Phalcon\Validation\Validator\PresenceOf" not found

phalcon 5.0のバリデーションのマニュアルを見るとClassの場所が変わっていました。
なのでuse文を変更。

-use Phalcon\Validation\Validator\PresenceOf;
+use Phalcon\Filter\Validation\Validator\PresenceOf;

Validator\Email not found

Class "Phalcon\Validation\Validator\Email" not found

PresenceOfと同様にClassの場所が変わっています。
use文を変更。

-use Phalcon\Validation\Validator\Email;
+use Phalcon\Filter\Validation\Validator\Email;

基本的にPhalcon\ValidationはPhalcon\Filter\Validationに移動されているようです。

checkboxにデフォルトチェックがつかない

エラーログは出ていませんでしたが、checkboxにデフォルトチェックがついていませんでした。
input要素をレンダリングする際のcheckedオプションの指定方法が変わったようです。

デフォルトチェックをつける場合、checkedオプションに'checked'を設定していましたが、valueと同じ値を設定する必要があるようです。

-{{ form.render('category', ['value': categoryId, 'checked':(postCategoryId === categoryId) ? 'checked':null]) }}
+{{ form.render('category', ['value': categoryId, 'checked':(postCategoryId === categoryId) ? categoryId:null]) }}

https://docs.phalcon.io/5.0/ja-jp/upgrade#phalconformselementcheck

そのほかのアップグレードで発生したエラー対応

phalcon3から5にバージョンアップした際のページネーション対応

phalcon3から5にバージョンアップした際にページネーションで発生したエラー、Deprecated対応

Call to undefined method Model::getPaginate()

Call to undefined method Phalcon\Paginator\Adapter\Model::getPaginate()のエラー対応

total_pages

PHP Notice:  Access to undefined property Phalcon\Paginator\Repository::total_pages

https://docs.phalcon.io/4.0/ja-jp/upgrade#paginator
total_pagesがなくなって、lastを使う

before

PHP Notice:  Access to undefined property Phalcon\Paginator\Repository::before

https://docs.phalcon.io/4.0/ja-jp/upgrade#paginator
beforeがなくなって、previousを使う

そのほかのアップグレードで発生したエラー対応

Call to undefined method Phalcon\Paginator\Adapter\Model::getPaginate()のエラー対応

Phalcon 5.xにバージョンアップした際に以下のエラーが発生

Call to undefined method Phalcon\Paginator\Adapter\Model::getPaginate()
#0 [internal function]: App\Controllers\RecipeController->searchAction()
#1 [internal function]: Phalcon\Dispatcher\AbstractDispatcher->callActionMethod()
#2 [internal function]: Phalcon\Dispatcher\AbstractDispatcher->dispatch()
#3 {pathto}/public/index.php(30): Phalcon\Mvc\Application->handle()
#4 {main}

getPaginate()エラーの対応方法

Phalcon 4.xにアップグレードされたときにfunction名が変わったようです。
https://docs.phalcon.io/4.0/ja-jp/upgrade#paginator

getPaginate()からpaginate()に変更

call_user_func()エラー発生

続いて以下のエラーが発生

call_user_func(): Argument #1 ($callback) must be a valid callback, first array member is not a valid class name or object
#0 [internal function]: call_user_func()
#1 {pathto}/controllers/RecipeController.php(65): Phalcon\Paginator\Adapter\Model->paginate()
#2 [internal function]: App\Controllers\RecipeController->searchAction()
#3 [internal function]: Phalcon\Dispatcher\AbstractDispatcher->callActionMethod()
#4 [internal function]: Phalcon\Dispatcher\AbstractDispatcher->dispatch()
#5 {pathto}/public/index.php(30): Phalcon\Mvc\Application->handle()
#6 {main}

これは、new Phalcon\Paginator\Adapter\Model()の時に渡すパラメータが間違っているため。
phalcon 5.xの使い方に合わせて以下の3つのどれかに修正する必要があります。

注意点として、Phalcon\Paginator\Adapter\Modelは多数のレコードのページネーションに使わないでとなっているので、DBからデータを取得してページネーションを使うならPhalcon\Paginator\Adapter\QueryBuilderにしとくのが良さげです。