★ Automatically convert your code to PHP 7.4 syntax using Rector
Tags: php, tool
Published: 2020-01-02 23:44:18

---
title: ★ Automatically convert your code to PHP 7.4 syntax using Rector
published: true
date: 2019-12-03 08:14:49 UTC
tags: php, tool
canonical_url: https://freek.dev/1518-automatically-convert-your-code-to-php-74-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](https://twitter.com/freekmurze/status/1200862682825609217) and [typed properties](https://twitter.com/freekmurze/status/1200864051137527808). Even though [an IDE can help with converting to the new syntax](https://twitter.com/freekmurze/status/1200864518076846082), 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.

<!--more-->
## Using Rector #

[Rector](https://github.com/RectorPHP/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:

```yml
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).

```bash
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](https://github.com/freekmurze/dotfiles/blob/586981e79565f848ebe9978cf0355a6c61262e9e/shell/.functions#L78-L80) to make it even easier.

```bash
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.

```bash
rector app
```

## Some caveats #

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

```php
// in a class

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

to this

```php
// 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.

```php
// 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](https://github.com/RectorPHP/Rector).