Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

Automatically convert your code to PHP 7.4 syntax using Rector

Original – by Freek Van der Herten – 3 minute read

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.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "Automatically convert your code to PHP 7.4 syntax using Rector"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.