Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The path to PHP 7

The path to PHP 7

As you may be aware PHP 5.6 has now come to its end of life meaning no more security updates, and we at DealTrak have been working on a large upgrade project in the last quarter of 2018.

My talk will be a tale about the path we have taken when upgrading our core application from PHP 5.6 to PHP 7.2. I will go through the strategy we took, the testing tools we used, and explain the various bumps we encountered along the way - including one sizeable yet short term compromise!

Mark Taylor

January 16, 2019
Tweet

More Decks by Mark Taylor

Other Decks in Programming

Transcript

  1. 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.
  2. 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!
  3. 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.
  4. 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”
  5. 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.
  6. 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.
  7. 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...
  8. 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
  9. 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.