My team at Spatie is currently building Mailcoach, a solution to self host your e-mail newsletter. Mailcoach can be used as stand alone software or as a Laravel package. Subscribe now at Mailcoach to get a notification as soon as we release it.

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.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks 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

You can comment on this post by replying to this tweet.
Neil Carlo Faisan Sucuangco liked on 4th December 2019
Mohammed Hicham liked on 4th December 2019
Simpledev liked on 4th December 2019
Neerav Pandya liked on 4th December 2019
Dr Lynsay Shepherd liked on 4th December 2019
Ondřej Kašpar liked on 4th December 2019
? Andrew ? liked on 4th December 2019
funivan liked on 4th December 2019
Manojkiran liked on 4th December 2019
mohammad faraz liked on 4th December 2019
ali ali liked on 4th December 2019
Nasirou Wagana liked on 3rd December 2019
Musa Abbasov liked on 3rd December 2019
Fred Carlsen liked on 3rd December 2019
Sohail Ahmad liked on 3rd December 2019
Rector liked on 3rd December 2019
Salman Zafar liked on 3rd December 2019
Martins F liked on 3rd December 2019
Ionut Mihaescu liked on 3rd December 2019
i360x64 liked on 3rd December 2019
Nicolas Eeckeloo liked on 3rd December 2019
Faraz.Dev liked on 3rd December 2019
Osvaldo Mercado liked on 3rd December 2019
Tomas Votruba liked on 3rd December 2019
K. E. Olivier GBLEM liked on 3rd December 2019
ダビッド トレス liked on 3rd December 2019
이현석 Hyunseok Lee liked on 3rd December 2019
Christopher liked on 3rd December 2019
Heru Hang Tryputra liked on 3rd December 2019
theonlyub liked on 3rd December 2019
Tom Schlick liked on 3rd December 2019
shadowdroid liked on 3rd December 2019
Christian Leo-Pernold liked on 3rd December 2019
Christian Leo-Pernold retweeted on 3rd December 2019
Thibault Lavoisey liked on 3rd December 2019
Stephen Jude liked on 3rd December 2019
Stephen Jude retweeted on 3rd December 2019
!E #code_dreamer ?? replied on 3rd December 2019
Converting just got easier and better on Laravel. I can't wait to spread the arrow func across my code-blocks like M16
Brian Reeves liked on 3rd December 2019
Spatie retweeted on 3rd December 2019
?????? liked on 3rd December 2019
Jason McCreary liked on 3rd December 2019
Omar Andrés Barbosa Ortiz liked on 3rd December 2019
Ndirangu Waweru ™ liked on 3rd December 2019
Ndirangu Waweru ™ retweeted on 3rd December 2019
kanamastaka liked on 3rd December 2019
QiroLab retweeted on 3rd December 2019
Ian liked on 3rd December 2019
Ian retweeted on 3rd December 2019
Menj retweeted on 3rd December 2019
Feras Shaer ?? liked on 3rd December 2019
Menj liked on 3rd December 2019
Zubair Mohsin liked on 3rd December 2019
John Braun liked on 3rd December 2019
Lee Overy liked on 3rd December 2019
José Cage liked on 3rd December 2019
. liked on 3rd December 2019
Volkan Metin liked on 3rd December 2019
pxgamer liked on 3rd December 2019
Erik Galloway liked on 3rd December 2019
pxgamer retweeted on 3rd December 2019
ghost liked on 3rd December 2019
oluwajubelo loves VueJS ? retweeted on 3rd December 2019
حضرت شیخ ☘️ liked on 3rd December 2019
Alan Wynn ツ liked on 3rd December 2019
ghost retweeted on 3rd December 2019
大澤木小鐵 liked on 3rd December 2019
Simon Yayla liked on 3rd December 2019
codedge liked on 3rd December 2019
?️?️?️?️?️ retweeted on 3rd December 2019
Jonny Nott liked on 3rd December 2019