DEV Community

Freek Van der Herten
Freek Van der Herten

Posted on • Originally published at freek.dev on

★ Automatically convert your code to PHP 7.4 syntax using Rector

In PHP 7.4, two new features were introduced that I'd like to use in my packages and projects: short closures and typed properties. Even though an IDE can help with converting to the new syntax, I'd don't want to manually hunt down all the places where the new syntax can be used. Lucky there's a tool that can do this work automatically.

Using Rector

Rector is a fantastic tool to convert code written for an older version of PHP to use all the shiny new features of newer PHP versions. It can be used to use short closures and typed properties automatically.

To use it, you must create a file called rector.yaml in your project or package with this content:

parameters:
    php_version_features: '7.4'
services:
    Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector: ~
    Rector\Php74\Rector\Property\TypedPropertyRector: ~

Rector can be used via Docker (I couldn't use it via composer global because of conflicting dependencies). Just issue this command in the root of your project or package (replace app with the directory you want to convert).

docker run -v $(pwd):/project rector/rector:latest process /project/app --config="/project/rector.yaml" --autoload-file /project/vendor/autoload.php

If you have a place in your environment where you can define bash functions, you can use this one from my dotfiles to make it even easier.

function rector() {
   docker run -v $(pwd):/project rector/rector:latest process /project/$1 --config="/project/rector.yaml" --autoload-file /project/vendor/autoload.php
}

With this in place, you only need to issue this command to convert the app directory.

rector app

Some caveats

There are two caveats. First, Rector won't remove DocBlocks that become unnecessary. Rector will convert this

// in a class

/** @var string */
protected $myString

to this

// in a class

/** @var string */
protected string $myString

so you'll need to remove that line containing @var manually.

The second caveat is that, sometimes, Rector will break your code. It will try to use typed properties wherever possible. If a class overrides a non-typed property and you try to type that, PHP will throw an error.

In Laravel projects, this becomes apparent when Rector types the properties of console commands and Eloquent models.

// this will break

class MyCommandDescription extends Command
{
    protected string $signature = 'my-command-signature';

    protected string $description = 'My command description';

    ...
}

The easiest solution is to remove those added types by performing a few search/replaces.

In general, I recommend only using Rector on a project or a package that has a solid test suite, so you can easily verify if everything works correctly after Rector converted the code.

In closing

Rector can has a lot more options then the ones mentioned in this blogpost. To know more head over the Rector repo on GitHub.

Top comments (0)