Slide 1

Slide 1 text

Upgrading Legacy to the Latest PHP Version PHPDAY | MAY 17, 2024 @[email protected] | @afilina

Slide 2

Slide 2 text

I Stand With Ukraine "I don't know whether my application works on the latest PHP."

Slide 3

Slide 3 text

I Stand With Ukraine • 4M lines of code • As low as PHP 4 • register_globals • undefined vars • dead libraries (pre-composer) • removed extensions

Slide 4

Slide 4 text

I Stand With Ukraine Anna Filina • Coding since 1997. • PHP, Java, C#, Flash, etc. • Legacy archaeology. • Test automation. • Mentoring. • Filina Consulting.

Slide 5

Slide 5 text

I Stand With Ukraine

Slide 6

Slide 6 text

I Stand With Ukraine

Slide 7

Slide 7 text

I Stand With Ukraine • Find compatibility issues. • Fix the issues. • Test the fixes.

Slide 8

Slide 8 text

I Stand With Ukraine PHPCompatibility scanner

Slide 9

Slide 9 text

I Stand With Ukraine ./vendor/bin/phpcs -p . --standard=PHPCompatibility --colors --extensions=php,inc,phtml --runtime-set testVersion 8.3

Slide 10

Slide 10 text

I Stand With Ukraine FILE: /www/src/app/controllers/MyController.php ------------------------------------------------------------------ FOUND 1 ERROR AFFECTING 1 LINE ------------------------------------------------------------------ 166 | ERROR | Using 'break' outside of a loop or switch structure | | is invalid and will throw a fatal error since PHP | | 7.0 ------------------------------------------------------------------

Slide 11

Slide 11 text

I Stand With Ukraine • php.net: docs, release notes, migration guides. • php-legacy-docs.zend.com • phplift.com (WIP) • exakat.readthedocs.io (compatibility rulesets) • Experimentation. • PHP source code.

Slide 12

Slide 12 text

I Stand With Ukraine PHPCompatibility tells us what to fix

Slide 13

Slide 13 text

I Stand With Ukraine $response = '1234567890'; $header = 'Content-length: ' . strlen($response) + 1; echo $header;

Slide 14

Slide 14 text

I Stand With Ukraine 3v4l.org run code in different PHP versions

Slide 15

Slide 15 text

I Stand With Ukraine

Slide 16

Slide 16 text

I Stand With Ukraine

Slide 17

Slide 17 text

I Stand With Ukraine

Slide 18

Slide 18 text

I Stand With Ukraine $response = '1234567890'; $header = 'Content-length: ' . (strlen($response) + 1); echo $header;

Slide 19

Slide 19 text

I Stand With Ukraine Function each() is deprecated since PHP 7.2; Use a foreach loop instead

Slide 20

Slide 20 text

I Stand With Ukraine while (list($i, $row) = each($result)) foreach ($result as $i => $row)

Slide 21

Slide 21 text

I Stand With Ukraine $key = each($result)['key']; $value = each($result)['value’]; $key = each($result)[0]; $value = each($result)[1];

Slide 22

Slide 22 text

I Stand With Ukraine $row1 = each($result); $row2 = each($result);

Slide 23

Slide 23 text

I Stand With Ukraine else if (list(, $optArg) = each($args))

Slide 24

Slide 24 text

I Stand With Ukraine final class Php56 { public static function each(array &$array) { if (current($array) === false) { return false; } $key = key($array); $value = current($array); next($array); return [ 1 => $value, 'value' => $value, 0 => $key, 'key' => $key, ]; } }

Slide 25

Slide 25 text

I Stand With Ukraine Portable, unit-tested solution wrapped in a class

Slide 26

Slide 26 text

I Stand With Ukraine mcrypt PHP

Slide 27

Slide 27 text

I Stand With Ukraine mcrypt PECL PHP

Slide 28

Slide 28 text

I Stand With Ukraine mcrypt PECL PHP libmcrypt

Slide 29

Slide 29 text

I Stand With Ukraine • Can we keep using libmcrypt? • New mcrypt extension does not behave the same.

Slide 30

Slide 30 text

I Stand With Ukraine PHP openssl

Slide 31

Slide 31 text

I Stand With Ukraine mcrypt.OFB != openssl.OFB

Slide 32

Slide 32 text

I Stand With Ukraine PHP phpseclib/mcrypt_compat

Slide 33

Slide 33 text

I Stand With Ukraine How to test mcrypt upgrade?

Slide 34

Slide 34 text

I Stand With Ukraine encrypted Old app test data New app

Slide 35

Slide 35 text

I Stand With Ukraine public function testCanDecrypt() { //... $decrypted = $security->decrypt($encrypted); self::assertEquals($original, $decrypted); }

Slide 36

Slide 36 text

I Stand With Ukraine mysql_ mysqli_ PDO

Slide 37

Slide 37 text

I Stand With Ukraine • Connection object needs to be available. • Connection object now a mysqli type. • Field metadata represented differently. • Different methods for unbuffered queries.

Slide 38

Slide 38 text

I Stand With Ukraine mysql to mysqli conversion can't be unit-tested.

Slide 39

Slide 39 text

I Stand With Ukraine mysql_connect mysql_query mysql_close mysqli_connect mysqli_query mysqli_close $connection $connection

Slide 40

Slide 40 text

I Stand With Ukraine High-level tests • Integration • Characterization • Manual (not recommended)

Slide 41

Slide 41 text

I Stand With Ukraine Cypress characterization tests

Slide 42

Slide 42 text

I Stand With Ukraine npm install cypress

Slide 43

Slide 43 text

I Stand With Ukraine npx cypress open

Slide 44

Slide 44 text

I Stand With Ukraine Make changes Write tests Execute on legacy & upgrade First test passes on upgrade

Slide 45

Slide 45 text

I Stand With Ukraine As many tests as you need to be confident

Slide 46

Slide 46 text

I Stand With Ukraine • Login: critical + simple • Reservations: critical + complex • Reporting: medium + complex • FAQ: low + simple • PDF: low + complex

Slide 47

Slide 47 text

I Stand With Ukraine Takeaways • Write high-level tests • Discover issues with PHPCompatibility • Research the rest based on failed tests • Consider many solutions (don’t decide too quickly) • Make decisions that can be changed later

Slide 48

Slide 48 text

Questions? PHPDAY | MAY 17, 2024 @[email protected] | @afilina