プロジェクトをPHP 5.6から7.1にPhalconに移動した経験

画像



時間が経ち、進歩が実を結び、このソフトウェアまたはそのソフトウェアの新しいバージョンが毎月登場します。 PHP言語でも同じことが起こります。 プロジェクトチームkrisha.kzは、新しいバージョンのインタープリターに移行する時が来たと判断しました。 PHPをバージョン5.6から7.1に移行した経験を共有します。これは、主なモノリスを提供します。



このモノリスのデバイスに関するビデオがあります。 その特徴は、Phalconバージョン2フレームワークに基づいていることであり、この点で、PHP自体の更新に加えて、Phalconの第3バージョンへの移行に取り組む必要がありました。



実際、この動き自体は2017年10月11日に実施されました-手が届かないのです。 しかし、私は、ボトルを使用する人は面白いと思います。



利益



受け取ったメリットからすぐに始めましょう。



画像



グラフは3か月のギャップを示し、矢印はphp7.1への移行の瞬間を示します(2017年10月11日)。 右側のY軸の青い線は、クエリの数を示しています。 左側のY軸に沿った他の2行は、PHPでのページレンダリング速度を示しています。 データは日ごとにグループ化されます。



ご覧のとおり、利益はページ速度の約30%です。



CPU消費も減少しましたが、残念ながらこれらのデータのグラフィックは保持されていません。



材料面に加えて、いわば、PHPコードを書くときに文化的な変化がありました。 メソッド引数の型と戻り値の型を常に宣言することが決定されました。 PHP7の開発者が主張するように、これによってパフォーマンスが向上しないことは明らかですが、これにより、より予測可能なコードを書くことができます。



PHP7は、「nullを含む共用体演算子」、「宇宙船演算子」などの構文糖衣の新しいバッチを導入しました。 これらの革新はすべて、コードをより簡単かつ明確に書くのに役立ちます。



マイナス面もあります-ライブラリを最新バージョンに更新した結果、PHP7.1で動作するため、依存ライブラリの一部の機能を放棄する必要がありました。 たとえば、twigを〜2.0にアップグレードするとき、デバッグバーでTraceableを放棄する必要がありました。



Phalconの更新は二重の苦痛です。 コードベースを更新するだけでなく、拡張機能を更新してインフラストラクチャに影響を与えることも必要です。 それでも、開発者による詳細な更新ガイドはこの点を緩和します。



どうでしたか



目標は、PHPをバージョン5.6から7.1に、Phalcon c 2.0を3.2にアップグレードすることでした。

2017年半ばの時点で、PHP 7.1は安定しており、使用するすべてのベンダーがサポートを取得しました。



Phalcon 3.2はPHP 7.1で自信を持って動作し、新しいバージョンに移行するためのコードサンプルを含むかなり詳細なドキュメントがありました。



システムの2つの重要なコンポーネントをアップグレードすることは、難しい解決策のように思えるかもしれません。 ただし、変更ログPhalconを分析した結果、コードのグローバルな変更は不要であるという結論に達しました。 下位互換性はそれほど壊れていません。 このタスクでは、1つの石で2羽の鳥を殺すことができました。



リードタイムを延長し、テストを複雑にすることで「unnecessaryれる」不必要なリファクタリングやその他の誘惑を避けることが重要でした。



PHPアップデート



php7ccアナライザーは、名前を変更する必要があるいくつかのクラスがあることを示しました。 レガシーmcrypt拡張も使用されます。



Throwableを理解するには、別のエラーハンドラーを教える必要がありました。



予約された名前のクラスは、それらが配置されているディレクトリの接尾辞で名前が変更されます。 将来のバージョンに切り替えるときに編集を減らすために、ソフト予約語を使用することが決定されました。



mcrypt拡張機能はopensslに変更されました。



それは:



$ivSize = mcrypt_get_iv_size(self::MCRYPT_CIPHER, MCRYPT_MODE_CBC); $iv = mcrypt_create_iv($ivSize, self::RANDOMNESS_SOURCE);
      
      





次のようになりました:



 $ivSize = openssl_cipher_iv_length(self::OPENSSL_CIPHER); $iv = openssl_random_pseudo_bytes($ivSize);
      
      





php 7.1への移行に対する主要な変更のこのリストでは、完了と見なすことができます。



ファルコンアップデート



Phalconへの移行に関連する変更は、コードの影響をより強く受けます。 編集は本質的に構造的でしたが。 DIおよびフォーム検証の動作は、新しい要件に合わせてやり直されることになっています。



内部DIコンテキストが変更され、コードがより論理的になりました。



それは:



 $this->di->set('api', function () { //  $this    $api = new Api($this->di->config->api->toArray()); $userCookie = $this->di->config->get('cookieId'); if ($this->di->getCookies()->has($userCookie)) { $api->setUserId($this->di->getCookies()->getValue($userCookie)); } return $api; }, true);
      
      





次のようになりました:



 $this->di->set('api', function () { //  $this  \Phalcon\Di $api = new Api($this->config->api->toArray()); $userCookie = $this->config->get('cookieId'); if ($this->getCookies()->has($userCookie)) { $api->setUserId($this->getCookies()->getValue($userCookie)); } return $api; }, true);
      
      





FormクラスとValidatorクラスの変更点を理解するために、フレームワークのソースコードを調べました。 大きな利点は、 zephirが構文的にPHPに似ていることです。 これにより、コードの理解がより簡単で迅速になりました。

ここに、作業フォーム用のプロジェクトのコードに加えられた主な変更点を示します。



それは:



 public function appendMessage($message, $field, $type = null) { if (is_string($message)) { $message = new Message($message, $field, $type); } if (!is_null($this->_messages) && array_key_exists($field, $this->_messages)) { $this->_messages[$field]->appendMessage($message); } else { $this->_messages[$field] = new Message\Group([$message]); } }
      
      





次のようになりました:



 public function appendMessage($message, $field, $type = null) { if (is_string($message)) { $message = new Message($message, $field, $type); } //      if (!$this->_messages) { $this->_messages = new Message\Group([$message]); } else { $this->_messages->appendMessage($message); } }
      
      





Phalcon \ Formsの現在のインターフェイスと互換性がなくなったフォームを操作する方法があります。 メッセージは、配列ではなくPhalcon \ Validation \ Message \ Groupオブジェクトに蓄積されます。 1つのフォーム要素に多くの検証メッセージが含まれるようになりました。



cancelOnFail設定はロジックを変更しました;エラーの場合、検証はフォーム全体でキャンセルされ、残りの要素はスキップされます。 以前は、プロセスはチェックされているフィールドに対してのみダウンロードされ、後続のフィールドに渡されていました。



環境設定



本番環境では、同じパラメーターを使用して新しい仮想バックエンドが作成されましたが、異なるオペレーティングシステムと更新されたnginxが使用されました。



古い:



PHP 5.6.17

php5-phalcon 2.0.8-php56〜ジェシー

nginx 1.10

Linuxバージョン3.16.0-4-amd64(debian-kernel@lists.debian.org)(gccバージョン4.8.4(Debian 4.8.4-1))



新規:



PHP 7.1.10

php7.1-phalcon 3.2.2-1 + php7.1

nginx 1.11

Linuxバージョン4.11.0-14-generic(buildd @ lcy01-08)(gccバージョン5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1〜16.04.4))



PHPの構成に特別な変更はありません。 キャッシュを備えたサーバー(Redis)も変更されず、キャッシュプレフィックスのみが変更されました。



リリースは新しいバックエンドで行われたため、追加の保険がありました。そのため、大失敗の場合は、PHP 5.6のコードのバージョンで古いバックエンドにすばやく切り替えることができます。



PHP7に切り替えても、CIサーバーはバイパスされませんでした。 自動テストは特定のバージョンのPHPを備えたdockerコンテナで実行されるため、新しいバージョンのphpおよびphalconを使用してイメージを作成しました。 ところで、テストの実行方法は次のとおりです。



 set -eux docker pull ${bamboo.docker.base.image.php.krisha} docker run \ --rm \ --volume $(pwd):/code \ --volume /etc/passwd:/etc/passwd:ro \ --volume /etc/group:/etc/group:ro \ --user $(id -u):$(id -g) \ --workdir /code \ --interactive \ ${bamboo.docker.base.image.php.krisha} \ /code/vendor/bin/robo parallel mobile
      
      





このコードは、テスト段階の竹のタスクです。 CIチューニングのトピックは別の記事にふさわしいため、ここでは取り上げません。



結論



手動テストと組み合わせた多数の自動テストにより、深刻な更新の問題は回避されました。 問題の定式化の適時性は、他のプロジェクトの経験を活用し、彼らが踏んだレーキをバイパスすることを可能にしました。 移行作業は1か月以内に完了しました。 その後、1週間以内に、いくつかの小さなバグが修正されました。



この記事の執筆とPHP7への移行の実装を支援してくれたコメントに感謝します。



All Articles