📜 ⬆️ ⬇️

Experience of transition of the project to phalcon from php 5.6 to 7.1

image

As time goes on, progress is paying off, every month there are new versions of this or that software. The same happens with the PHP language. Our project team krisha.kz decided that it was time to make the transition to a new version of the interpreter. We will share the experience of moving PHP from version 5.6 to 7.1, which serves our main monolith.

There is a video about the device of this monolith. Its feature is that it is based on the Phalcon version 2 framework. In this regard, in addition to updating PHP itself, we had to work on switching to the 3rd version of Phalcon.
')
Actually, the move itself was carried out on October 11, 2017 - the hands did not reach to write about it. But I think those who use the bottle will be interested.

Profit


We will start immediately with the benefits we have received.

image

The graph shows the interval of three months, the arrow indicates the moment of transition to php7.1 (October 11, 2017). The blue line on the Y axis on the right shows the number of requests. The two remaining lines along the Y axis on the left show the page rendering speed in PHP. Data is grouped by day.

As you can see, the profit is about 30% of the page speed.

Processor consumption has also decreased, but unfortunately the graphics for this data has not been preserved.

In addition to the material side, cultural changes have also occurred, so to speak, when writing PHP code. It was decided to always declare the type of the argument of the method and the type of the return value. It is clear that the performance will not increase from this, as the PHP7 developers themselves claim, but this allows you to write more predictable code.

PHP7 introduced a new batch of syntactic sugar such as “operator of association with null”, “operator of spaceship” and much more . All these innovations help to write code easier and more understandable.

There is also a negative side - due to the update of the libraries to the latest version, so that they worked on PHP7.1, we had to abandon some of the functionality of the dependent libraries. For example, when upgrading twig to version ~ 2.0, I had to abandon Traceable in the debugbar.

Phalcon update is doubly pain. It is required not only to update the code base, but also to affect the infrastructure by updating the extension. However, a detailed update guide from developers softens this point.

How it was


The task was to upgrade PHP from version 5.6 to 7.1 and Phalcon from 2.0 to 3.2.
At the time of mid-2017, PHP 7.1 proved to be stable and all the vendors that we use got support.

Phalcon 3.2 worked confidently with PHP 7.1 and there was sufficiently detailed documentation with examples of migration code for the new version.

Updating two important components of the system may seem like a hard-to-implement solution. However, after analyzing the changelog of Phalcon, we came to the conclusion that global changes in the code are not required. Backward compatibility was not greatly affected. In this task to kill two birds with one stone still happened.

It was important to avoid unnecessary refactoring and other temptations in which you can “drown” by stretching the deadline and complicating testing.

PHP update


The php7cc analyzer showed that we have several classes that should be renamed. The outdated mcrypt extension is also used.

Another error handler needed to be taught to understand Throwable.

Classes with reserved names are renamed with a postfix of the directory in which they are located. It was decided to go through the soft-reserved-words to reduce the edits during the transition to subsequent versions.

The mcrypt extension has changed in favor of openssl.

It was:

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

It became:

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

On this list of major changes in the transition to php 7.1 can be considered complete.

Phalcon update


More code has affected the changes associated with the transition to Phalcon. Although edits were more structural in nature. The DI and form validation behavior had to be remade to fit the new requirements.

The internal context of the DI has changed, making the code more logical.

It was:

 $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); 

It became:

 $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); 

To understand what has changed in the Form and Validator classes, we went to the source code for the framework. A huge plus is that zephir is syntactically similar to PHP. Thanks to this, it was easier and faster to understand the code.
Here is the main change that was made in the code of our project for working forms:

It was:

 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]); } } 

It became:

 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); } } 

We have methods for working with forms that have become incompatible with the current interface Phalcon \ Forms. Messages now accumulate in the Phalcon \ Validation \ Message \ Group object instead of an array. One form element now contains multiple validation messages.

Setting cancelOnFail changed its logic, in case of an error, validation is canceled for the whole form, skipping the rest of the elements. Previously, the process was pumped only for the field being tested and passed on to subsequent fields.

Setting up the environment


The production created new virtual backends with equivalent parameters, but with a different operating system and updated nginx.

Older:

PHP 5.6.17
php5-phalcon 2.0.8-php56 ~ jessie
nginx 1.10
Linux version 3.16.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1))

New:

PHP 7.1.10
php7.1-phalcon 3.2.2-1 + php7.1
nginx 1.11
Linux version 4.11.0-14-generic (buildd @ lcy01-08) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4))

There were no special changes to the php configuration. The servers with the cache (Redis) also did not undergo any changes, only the cache prefix was changed.

Since the release was made on new backends, there was additional insurance, so that in the event of a fiasco, it was possible to quickly switch to old backends with the version of the code for php 5.6.

The transition to PHP7 has not bypassed our CI server. Since autotests are run in a docker container with a certain version of PHP, we have created images with new versions of php and phalcon. By the way, here's how we run the tests:

 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 

This code is in the bamboo test stage. The topic of CI tuning deserves a separate light, so we will not go into it.

findings


Due to a large number of autotests in conjunction with manual testing, we managed to avoid serious problems when updating. The timeliness of the task setting made it possible to use the experience of other projects and circumvent the rake on which they stepped. Work on the transition met within 1 month. After, several minor bugs were fixed during the week.

Special thanks to comment for help in writing the article and implementing the transition to PHP7.

Source: https://habr.com/ru/post/349412/


All Articles