Slide 1

Slide 1 text

The Path to PHP 7 Mark Taylor | @willCodeForAle

Slide 2

Slide 2 text

Why Upgrade? ● End of life for PHP 5.6 – no more security updates. ● Speed and optimised memory usage - entirely new engine from Zend Engine II called PHPNG. ● Type hints for primitive types on function parameters and return values are sooooo nice. ● Handling of fatal errors with EngineException.

Slide 3

Slide 3 text

Backwards Incompatible Changes ● http://php.net/manual/en/migration70.incompatible.php - review what is applicable to you. ● Global name space classes called Error – unfortunately we had several widely used. ● No legacy constructors - rare, but there were a few. ● Usage of ereg – replace with preg, plus no preg_replace \e flag. ● set_magic_quotes_runtime (some old 3rd party code). ● Warn when counting non-countable types (7.1 → 7.2). ● Migrated some 3rd party code committed to our repo long ago which was in violation. ● The big gotcha for us was the legacy MySQL extension. Time for a temporary compromise!

Slide 4

Slide 4 text

The Gotcha – Legacy MySQL ● Extensive direct use of mysql_query etc. in our legacy code base, impractical to replace. ● The temporary solution – add MySQL legacy extension back in! Works like a charm.

Slide 5

Slide 5 text

PHP 7 Upgrade Analysis Tools ● PHP 7 Compatibility Checker (php7cc) – unmaintained, so I discounted it. ● Phan – Proved to be extremely slow, so I discounted it. ● PHP_CodeSniffer (phpcs) + PHP 7 Compatibility sniffs – very nice, seems comprehensive. ● PHP 7 Migration Assistant (php7mar) – Nice and simple, also seemed to do the job well yet didn’t find quite as much as phpcs. Easy to tweak the checks! composer global require phpcompatibility/php-compatibility phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility/ phpcs -p -s --colors --extensions=php –standard=PHPCompatibility \ --exclude=PHPCompatibility.Extensions.RemovedExtensions --runtime-set testVersion 7.2 . git clone https://github.com/Alexia/php7mar.git php php7mar/mar.php -f=”/path/to/check” -r=”/path/for/output”

Slide 6

Slide 6 text

Infrastructure Changes ● DealTrak run everything in Docker, and we build a new production image for PHP 7.2. ● Configured two environments for testing, UAT and Live Beta. ● UAT environment ran PHP7 variant Docker container against non production resources. ● Live Beta used a separate AWS ECS cluster, along with separate target group and sub domain. ● Resource allocation is easily scalable in ECS, useful for testing cost vs performance testing. ● Separate Ansible playbook for beta deployments.

Slide 7

Slide 7 text

How did we test all this? ● Lots and lots of manual testing by our QA team. ● Run Behat test suites for legacy mostly utilising selenium. ● Test all our APIs using Behat and Soap UI, compare results with live API calls. ● Monitoring of any new warnings and errors via New Relic.

Slide 8

Slide 8 text

Performance testing ● Important to check we weren’t adversely affecting performance. ● Apache Bench testing multiple URLs in parallel with concurrency. ● Used a separate AWS ECS cluster with a test sub domain. ● Allocate resources were identical for accurate test results. ● We found an average of 40% speed increase vs current production PHP 5.6. ● This should allow us to save cost, as less resources are required. ● My (very) basic bash script follows...

Slide 9

Slide 9 text

spamspamspam.sh: -------------------------------------------------------------------------------- #!/usr/bin/env bash baseUrl=$1 sessionId=$2 now=`date '+%Y-%m-%d-%H:%M:%S'` resultFile="$now-results.txt" if [ ! -f $resultFile ]; then touch $resultFile fi # spam spam spam spam spam and egg and chips and spam pages=( "main" "quotes" "proposal/main?proposal_id=123457" "logs/proposal" "branch_control/my_branch" # ... and so on ) for page in ${pages[@]}; do ab -n 1000 -c 10 -C PHPSESSID=$sessionId $baseUrl/$page >> $resultFile & done

Slide 10

Slide 10 text

Deployment strategy ● Deploy out of production hours, late evening when the site is quiet. ● Merge any code changes to master. ● Build latest version of the PHP7 Docker Image (including code) and push up to ECR. ● Deploy a new task revision via ECS which uses the new image. ● Test all major functionality after deployment. ● If revert is required, it’s just a case of deploying the previous application image.

Slide 11

Slide 11 text

No content