Slide 1

Slide 1 text

CONFOO 2024 | MONTREAL, CANADA @afilina@phpc.social | @afilina Semi-Automated Refactoring and Upgrades with Rector

Slide 2

Slide 2 text

I Stand With Ukraine -array_push($items, $item); +$items[] = $item;

Slide 3

Slide 3 text

I Stand With Ukraine What is Rector What is does, what it doesn’t do How I upgrade How I leverage automated tools

Slide 4

Slide 4 text

I Stand With Ukraine Anna Filina • Coding since 1997. • PHP, Java, C#, etc. • Legacy archaeology. • Test automation. • Talks and workshops. • YouTube videos. • Filina Consulting.

Slide 5

Slide 5 text

I Stand With Ukraine • 4M lines of code • PHP 5 or lower • register_globals • undefined vars • dead libraries • removed extensions

Slide 6

Slide 6 text

I Stand With Ukraine

Slide 7

Slide 7 text

I Stand With Ukraine • CLI tool • Has out-of-the box rules • Written in PHP, for PHP

Slide 8

Slide 8 text

I Stand With Ukraine EOL: 2017 PHPExcel PHPSpreadsheet Actively maintained

Slide 9

Slide 9 text

I Stand With Ukraine Source: https://getrector.com/blog/how-to-migrate-from- phpexcel-to-phpspreadsheet-with-rector-in-30-minutes $ composer require rector/rector-phpoffice --dev $ vendor/bin/rector init return function (RectorConfig $rectorConfig): void { $rectorConfig->import( PHPOfficeSetList::PHPEXCEL_TO_PHPSPREADSHEET ); }; $ vendor/bin/rector process src

Slide 10

Slide 10 text

I Stand With Ukraine -$worksheet->getDefaultStyle(); +$worksheet->getParent()->getDefaultStyle(); -$worksheet->setSharedStyle($sharedStyle, $range); +$worksheet->duplicateStyle($sharedStyle, $range); -$cell = $worksheet->setCellValue('A1', 'value', true); +$cell = $worksheet->getCell('A1')->setValue('value’); -PHPExcel_Cell::absoluteCoordinate() +PhpOffice\PhpSpreadsheet\Cell\Coordinate::absoluteCoordinate()

Slide 11

Slide 11 text

I Stand With Ukraine Static Analysis Rules hook into relevant nodes references to PHPExcel_Cell class Fix is applied rename references to PhpOffice\PhpSpreadsheet \Cell\Coordinate

Slide 12

Slide 12 text

I Stand With Ukraine -function save() {} +function save(): void {}

Slide 13

Slide 13 text

I Stand With Ukraine public function search(int $id) { $this->fetch($id); } -private function fetch($id) +private function fetch(int $id) { }

Slide 14

Slide 14 text

I Stand With Ukraine - /** - * @Route("/path", name="action") - */ + #[Route(path: '/path', name: 'action')]

Slide 15

Slide 15 text

I Stand With Ukraine • Framework rules: Symfony • Library rules: Doctrine, PHPUnit, PHPSpreadsheet • Upgrade rules: PHP 5.3, 5.4, etc. • Configurable rules: add arg to method signature and its references • Can write your own custom rules.

Slide 16

Slide 16 text

What It Does and Doesn’t Do

Slide 17

Slide 17 text

I Stand With Ukraine $db = new Db();

Slide 18

Slide 18 text

I Stand With Ukraine class SomeClass { - public function SomeClass() + public function __construct() { } }

Slide 19

Slide 19 text

I Stand With Ukraine class ChildClass extends ParentClass { - public function SomeClass() + public function __construct() { $this->ParentClass(); } } Fatal error: Uncaught Error: Call to undefined method ChildClass::ParentClass()

Slide 20

Slide 20 text

I Stand With Ukraine - $this->ParentClass() + ParentClass::__construct() https://www.zend.com/php-migration/function-name- restrictions/removed-php4-style-constructor

Slide 21

Slide 21 text

I Stand With Ukraine Use all available automated tools, not just one.

Slide 22

Slide 22 text

I Stand With Ukraine Don’t blindly rely on automation.

Slide 23

Slide 23 text

How I Upgrade

Slide 24

Slide 24 text

I Stand With Ukraine 5.3 ~ 3 months 7.4 5.3 ~ 10 months 8.3

Slide 25

Slide 25 text

I Stand With Ukraine 5.3 ~ 3 months 7.4 7.4 ~ 7 months 8.3 Running a supported version

Slide 26

Slide 26 text

I Stand With Ukraine Make changes Did behavior change? Write tests 5,000 changes 3,000 changes 7,000 changes

Slide 27

Slide 27 text

I Stand With Ukraine npm install cypress

Slide 28

Slide 28 text

I Stand With Ukraine npx cypress open

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

How I Leverage Automated Tools

Slide 31

Slide 31 text

I Stand With Ukraine PHPCompatibility FILE: /var/www/upgrade/my_account.php ------------------------------------------------------------------------------------------------------------- FOUND 2 ERRORS AND 1 WARNING AFFECTING 3 LINES ------------------------------------------------------------------------------------------------------------- 33 | WARNING | INI directive 'track_errors' is deprecated since PHP 7.2 202 | ERROR | Function split() is deprecated since PHP 5.3 and removed since PHP 7.0; Use preg_split() instead 208 | WARNING | The variable '$php_errormsg' is deprecated since PHP 7.2; Use error_get_last() instead -------------------------------------------------------------------------------------------------------------

Slide 32

Slide 32 text

I Stand With Ukraine

Slide 33

Slide 33 text

I Stand With Ukraine 1 > 'a' // 8.3: false // 5.6: true

Slide 34

Slide 34 text

I Stand With Ukraine ini_set('date.timezone', 'UTC'); date('Y-m-d H:i', $timestamp); // 5.6: string(16) "2024-01-01 12:00" // 8.3: string(16) "1970-01-01 00:00"

Slide 35

Slide 35 text

I Stand With Ukraine AccountController indexAction() viewAction() Account\IndexHandler ZF1 Mezzio Account\ViewHandler

Slide 36

Slide 36 text

@afilina@phpc.social | @afilina Thank you!