Fixing Short Echo Tags With CS Fixer

I’m currently working on a legacy PHP application which has a variety of partial HTML files using this style of code:

1
<?php echo 'hello';>

I think it looks nicer using the short code version, but only for simple statements like the above. Given a choice, I would rather it looked like this:

1
<?= 'hello';>

Changing it manually is a bit fiddly and error prone, as you can imagine. Moreover, I was rather surprised that PHPStorm doesn’t already cater for this with it’s reformatting rules which I wrote about in a previous blog post.

There is a solution though: CS Fixer, and this brief blog post will show you how to install it in PHPStorm and automatically correct those kinds of code styles. Once installed, you can of course get it to do much, much more.

Installing the Binary

There are only a few short steps but let’s start with where we’re going to install the fixer. Begin by changing directory to your project root folder. For this, let’s assume mine is: c:\temp\project.

Now use composer to install CS Fixer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ composer require --working-dir=c:/temp/project friendsofphp/php-cs-fixer
Using version ^3.0 for friendsofphp/php-cs-fixer
./composer.json has been created
Running composer update friendsofphp/php-cs-fixer
Loading composer repositories with package information
Updating dependencies
Lock file operations: 28 installs, 0 updates, 0 removals
- Locking composer/semver (3.2.4)
- Locking composer/xdebug-handler (2.0.1)
...
6 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
22 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

I’ve chopped the above output a little for brevity at the three elipsis, of course. Running this will produce much more logging.

Adding a Configuration File

We’ve got the fixer installed but need to now tell it how to handle those short tags. For this, create a file named: .php-cs-fixer.dist.php in the project’s root folder. This configuration was based on the one from the original repo and should be placed inside it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php

/*
* This file is part of PHP CS Fixer.
*
* (c) Fabien Potencier <fabien@symfony.com>
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

$header = <<<'EOF'
This file is part of PHP CS Fixer.

(c) Fabien Potencier <fabien@symfony.com>
Dariusz Rumiński <dariusz.ruminski@gmail.com>

This source file is subject to the MIT license that is bundled
with this source code in the file LICENSE.
EOF;

$finder = PhpCsFixer\Finder::create()
->exclude('tests/Fixtures')
->in(__DIR__)
->append([
__DIR__.'/dev-tools/doc.php',
// __DIR__.'/php-cs-fixer', disabled, as we want to be able to run bootstrap file even on lower PHP version, to show nice message
])
;

$config = new PhpCsFixer\Config();
$config
->setRiskyAllowed(true)
->setRules([
'echo_tag_syntax' => ['format' => 'short', 'shorten_simple_statements_only' => true],
])
->setFinder($finder)
;

// special handling of fabbot.io service if it's using too old PHP CS Fixer version
if (false !== getenv('FABBOT_IO')) {
try {
PhpCsFixer\FixerFactory::create()
->registerBuiltInFixers()
->registerCustomFixers($config->getCustomFixers())
->useRuleSet(new PhpCsFixer\RuleSet($config->getRules()))
;
} catch (PhpCsFixer\ConfigurationException\InvalidConfigurationException $e) {
$config->setRules([]);
} catch (UnexpectedValueException $e) {
$config->setRules([]);
} catch (InvalidArgumentException $e) {
$config->setRules([]);
}
}

return $config;

There’s a lot of information there, but for now, focus your attention on this part:

1
2
3
4
5
6
7
$config
->setRiskyAllowed(true)
->setRules([
'echo_tag_syntax' => ['format' => 'short', 'shorten_simple_statements_only' => true],
])
->setFinder($finder)
;

Inside the rule array, we’ve added one which CS Fixer will recognise related to short tags (echo_tag_syntax). You can find out the full options on this page, but basically, we are choosing to replace the long form tags with the short, and only in cases where we are simply echoing items.

Configuring PHPStorm to use CS Fixer

Everything is ready to use - we just need to tell PHPStorm all about it, which is what we’ll do now.

  • Go to settings via File > Settings... or Control-Alt-S
  • Click on Tools > External Tools
  • Click on the + icon at the top-left of the panel on the right. The following screen (albeit unfilled) will appear:

Now set the following fields as shown:

  • Name > CS Fixer
  • Description > Fixes files automatically – not essential
  • Program > Path to the CS Fixer program. For me, that’s: c:\temp\project\vendor\bin\php-cs-fixer.bat
  • Arguments > --verbose --config=c:\temp\project\.php-cs-fixer.dist.php fix "$FileDir$/$FileName$"
  • Working Directory > $ProjectFileDir$
  • Finally click OK

Adding a Key Binding

We’re almost done. To make things a little easier, let’s bind some keys to run CS Fixer automatically. In PHPStorm, do the following:

  • Control-Alt-S or File > Settings...
  • Click on Keymap > External Tools > External Tools > CS Fixer
  • Press Enter (or click the pencil icon above)
  • Click Add Keyboard Shortcut
  • Press your key combination you would like to use:
    • I chose Control-#
    • PHPStorm will warn you if you choose one that is already assigned, though, so press away
  • Click OK.

Testing CS Fixer

Open up a PHP file which uses the long tag echo format, and press your key combo. An output window will pop-up, followed by a lot of verbose output and then CS Fixer will hopefully do its magic!

Here’s some example output when I ran it last.

1
2
3
4
5
6
7
8
9
10
11
12
13
c:\temp\project\vendor\bin\php-cs-fixer.bat --verbose --config=c:\temp\project\.php-cs-fixer.dist.php fix C:\temp\project\partial.phtml
PHP CS Fixer 3.0.0 Constitution by Fabien Potencier and Dariusz Ruminski
Runtime: PHP 7.4.2
Loaded config default from "c:\temp\project\.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
Paths from configuration file have been overridden by paths provided as command arguments.
1) partial.phtml (echo_tag_syntax)

Fixed all files in 0.020 seconds, 12.000 MB memory used
F 1 / 1 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error

Process finished with exit code 0

Final Words

In this example, I installed CS Fixer into the project folder, but you might choose to install it somewhere centrally for all projects. Just adapt the commands above when you run composer and remember to point the configuration file parameter to somewhere central, too.


Hi! Did you find this useful or interesting? I have an email list coming soon, but in the meantime, if you ready anything you fancy chatting about, I would love to hear from you. You can contact me here or at stephen ‘at’ logicalmoon.com