- php-cs-fixer: Пишем свой фиксер
- Фиксер?
- Фиксим
- Token в PHP
- Token в php-cs-fixer
- Пишем фиксер
- Что дальше
- PHP Coding Standards Fixer¶
- Supported PHP Versions¶
- Documentation¶
- Installation¶
- Usage¶
- Editor Integration¶
- Community¶
- Who is behind the PHP Coding Standards Fixer?¶
- Saved searches
- Use saved searches to filter your results more quickly
- License
- PHP-CS-Fixer/PHP-CS-Fixer
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
php-cs-fixer: Пишем свой фиксер
Качество кода не только в том, как он работает, но и в том как выглядит. То, что единый в рамках кампании code style — это очень важная вещь — в наши дни убеждать уже никого не нужно. Код должен быть не только написан, но и оформлен. В плане оформления PHP кода, утилита php-cs-fixer давно уже стала стандартом. Использовать ее довольно просто, есть куча правил и можно удобно забиндить ее запуск на какую-нибудь комбинацию клавиш в шторме или на pre-commit hook в гите. Все это легко гуглится и подробно разбирается в сотнях статей. А мы сегодня поговорим о другом. Хотя в php-cs-fixer есть большое количество разных фиксеров, но что, если нам понадобится такой, которого там нет? Как написать собственный фиксер?
Фиксер?
Вообще, что такое фиксер? Фиксер, это небольшой класс, который фиксит ваш код, приводит его к какому-то виду. Я не стал выдумывать глупые или сложные кейсы для нового фиксера, и решил взять какой-нибудь вполне реальный. Например, приведение всех ключевых слов в коде к нижнему регистру. За это отвечает фиксер LowercaseKeywordsFixer. Давайте на его примере научимся создавать собственные фиксеры.
Фиксим
git clone https://github.com/FriendsOfPHP/PHP-CS-Fixer.git composer install
Наш подопытный фиксер состоит из двух частей:
Сам фиксер:
src/Fixer/Casing/LowercaseKeywordsFixer.php
И тест:
tests/Fixer/Casing/LowercaseKeywordsFixerTest.php
LowercaseKeywordsFixer.php — это файл, который содержит класс фиксера. Каждый фиксер должен наследоваться от абстрактного класса PhpCsFixer\AbstractFixer, а значит содержать методы:
getDefinition(); isCandidate(Tokens $tokens); applyFix(\SplFileInfo $file, Tokens $tokens);
К этим методам мы еще вернемся. Давайте теперь рассмотрим очень важное для нас понятие: Token.
Token в PHP
Если вы хорошо знакомы с PHP, то понятие токенов для вас не ново. На русском их еще иногда называют “метками”. Токены — это языковые лексемы PHP. Например, если взять такой простенький код:
и разбить его на токены, то получим массив из 54 элементов. Вторым элементом будет:
Array ( [0] => 334 [1] => foreach [2] => 3 )
Где 334 — это идентификатор токена. То есть не этого конкретного токена, а этого типа токенов. Другими словами, все токены, представляющие конструкцию foreach — будут иметь идентификатор 382. Этому идентификатору соответствует константа T_FOREACH. Список всех констант можно посмотреть в документации.
Очень важный момент. Идентификаторы меняются от версии к версии PHP интерпретатора, ваш код никогда не должен зависеть от конкретных цифр, только константы!
Подробнее про токены можно почитать в документации.
Token в php-cs-fixer
В php-cs-fixer есть два класса для работы с токенами:
PhpCsFixer\Tokenizer\Tokens для работы с массивом токенов, и
PhpCsFixer\Tokenizer\Token для работы с одним токеном.
Рассмотрим некоторые полезные методы.
equals($other, $caseSensitive = true)
Проверяет, что переданный первым параметром токен эквивалентен текущему. Это самый правильный способ проверить, что токены равны.
equalsAny(array $others, $caseSensitive = true);
Проверяет, что один из переданных в первом параметре токенов равен текущему.
Получить содержимое токена.
Был ли токен уже модифицирован.
isKeyword(); isNativeConstant(); isMagicConstant(); isWhitespace();
findBlockEnd($type, $searchIndex, $findEnd = true);
Найти конец блока типа $type (фигурные, квадратные или круглые скобки), начиная от токена с индексом $searchIndex. Если третьим параметром передать true — то метод будет искать начало блока, а не конец.
findGivenKind($possibleKind, $start = 0, $end = null);
Найти токены заданного типа (типов, если передать массив) начиная с токена под индексом $start и до токена под индексом $end.
Сгенерировать PHP код из набора токенов.
generatePartialCode($start, $end);
getNextTokenOfKind($index, array $tokens = array(), $caseSensitive = true);
Найти следующий токен определенного типа
getNextMeaningfulToken($index); getPrevMeaningfulToken($index);
Найти следующий/предыдущий токен, содержащий что-то, кроме пробелов и комментариев.
Пишем фиксер
Теперь к самому фиксеру.
Напомню, что мы пишем фиксер, который приводит все ключевые слова PHP к нижнему регистру. Класс фиксера будет находиться в файле
src/Fixer/Casing/LowercaseKeywordsFixer.php
Для начала нам нужно определить, попадает ли код под наш кейс. В нашем случае нам надо обработать любой код, который содержит ключевые слова php. Определим метод isCandidate.
public function isCandidate(Tokens $tokens) < return $tokens->isAnyTokenKindsFound(Token::getKeywords()); >
public function getDefinition() < return new FixerDefinition( 'PHP keywords MUST be in lower case.', array( new CodeSample( '> CATCH(\Exception $e) < EXIT(1); >> ' ), ) ); >
Этот метод возвращает объект FixerDefinition, конструктор которого принимает два параметра: короткое описание фиксера (оно будет в документации в файле README.rst) и небольшой пример кода для исправления (он нигде отображаться не будет, но участвует в тестах).
Также мы можем реализовать метод
public function getPriority()
Который возвращает приоритет фиксера, если нам понадобится запускать свой фиксер до или после других фиксеров. В нашем случае, наш фиксер никак не зависит от остальных, так что можно не реализовывать метод, оставив значение 0 из родительского класса.
Все приготовления закончены, давайте реализуем метод, который будет фиксить код.
Нам нужно, пробежать по всему коду, если токен — ключевое слово, то привести его к нижнему регистру:
protected function applyFix(\SplFileInfo $file, Tokens $tokens) < foreach ($tokens as $token) < if ($token->isKeyword()) < $token->setContent(strtolower($token->getContent())); > > >
В итоге должен получиться примерно такой файл.
Что дальше
У нас есть работающий фиксер. Это здорово. Осталось совсем чуть-чуть. Давайте напишем для него тест. Наш тест будет находиться в файле
tests/Fixer/Casing/LowercaseKeywordsFixerTest.php
Это обычный PHPUnit тест, разве что у него есть свой метод
doTest($expected, $input = null, \SplFileInfo $file = null)
который первым параметром принимает ожидаемый результат, а вторым — первоначальный код. Тестовый метод:
/** * @param string $expected * @param null|string $input * * @dataProvider provideExamples */ public function testFix($expected, $input = null) < $this->doTest($expected, $input); >
public function provideExamples() < return array( array('', ''), array('', ''), ); >
Тест работает, и если запустить только его, то все пройдет успешно. А вот общий тест сфейлится, т.к. данных о нашем фиксере нет в документации. Документация в php-cs-fixer авто-генерируемая, значит, достаточно запустить:
php php-cs-fixer readme > README.rst
И информация о нашем фиксере добавится в документацию.
Теперь нужно проверить оба наших файла на предмет соответствия код стайлу:
Если все прошло успешно, то ваш собственный фиксер готов. Далее можно сделать пулл реквест и через какое-то время ваше творение появится в php-cs-fixer.
PHP Coding Standards Fixer¶
The PHP Coding Standards Fixer (PHP CS Fixer) tool fixes your code to follow standards; whether you want to follow PHP coding standards as defined in the PSR-1, PSR-2, etc., or other community driven ones like the Symfony one. You can also define your (team’s) style through configuration.
It can modernize your code (like converting the pow function to the ** operator on PHP 5.6) and (micro) optimize it.
If you are already using a linter to identify coding standards problems in your code, you know that fixing them by hand is tedious, especially on large projects. This tool does not only detect them, but also fixes them for you.
Supported PHP Versions¶
Documentation¶
Installation¶
The recommended way to install PHP CS Fixer is to use Composer in a dedicated composer.json file in your project, for example in the tools/php-cs-fixer directory:
$ mkdir --parents tools/php-cs-fixer $ composer require --working-dir=tools/php-cs-fixer friendsofphp/php-cs-fixer
For more details and other installation methods, see installation instructions .
Usage¶
Assuming you installed PHP CS Fixer as instructed above, you can run the following command to fix the files PHP files in the src directory:
$ tools/php-cs-fixer/vendor/bin/php-cs-fixer fix src
See usage , list of built-in rules , list of rule sets and configuration file documentation for more details.
If you need to apply code styles that are not supported by the tool, you can create custom rules .
Editor Integration¶
Native support exists for:
Dedicated plugins exist for:
Community¶
The PHP CS Fixer is maintained on GitHub at https://github.com/PHP-CS-Fixer/PHP-CS-Fixer. Bug reports and ideas about new features are welcome there.
You can reach us at https://gitter.im/PHP-CS-Fixer/Lobby about the project, configuration, possible improvements, ideas and questions, please visit us!
Who is behind the PHP Coding Standards Fixer?¶
The PHP Coding Standards Fixer is brought to you by Fabien Potencier, the creator of the Symfony framework, and Dariusz Rumiński. It is released under the MIT license.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
A tool to automatically fix PHP Coding Standards issues
License
PHP-CS-Fixer/PHP-CS-Fixer
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
PHP Coding Standards Fixer
The PHP Coding Standards Fixer (PHP CS Fixer) tool fixes your code to follow standards; whether you want to follow PHP coding standards as defined in the PSR-1, PSR-2, etc., or other community driven ones like the Symfony one. You can also define your (team’s) style through configuration.
It can modernize your code (like converting the pow function to the ** operator on PHP 5.6) and (micro) optimize it.
If you are already using a linter to identify coding standards problems in your code, you know that fixing them by hand is tedious, especially on large projects. This tool does not only detect them, but also fixes them for you.
Note Each new PHP version requires a huge effort to support the new syntax. That’s why the latest PHP version might not be supported yet. If you need it, please, consider supporting the project in any convenient way, for example with code contribution or reviewing existing PRs. To run PHP CS Fixer on yet unsupported versions «at your own risk» — leverage the PHP_CS_FIXER_IGNORE_ENV.
The recommended way to install PHP CS Fixer is to use Composer in a dedicated composer.json file in your project, for example in the tools/php-cs-fixer directory:
mkdir -p tools/php-cs-fixer composer require --working-dir=tools/php-cs-fixer friendsofphp/php-cs-fixer
For more details and other installation methods, see installation instructions.
Assuming you installed PHP CS Fixer as instructed above, you can run the following command to fix the files PHP files in the src directory:
tools/php-cs-fixer/vendor/bin/php-cs-fixer fix src
See usage, list of built-in rules, list of rule sets and configuration file documentation for more details.
If you need to apply code styles that are not supported by the tool, you can create custom rules.
Dedicated plugins exist for:
The PHP CS Fixer is maintained on GitHub at https://github.com/PHP-CS-Fixer/PHP-CS-Fixer. Bug reports and ideas about new features are welcome there.
You can reach us at https://gitter.im/PHP-CS-Fixer/Lobby about the project, configuration, possible improvements, ideas and questions, please visit us!
The tool comes with quite a few built-in fixers, but everyone is more than welcome to contribute more of them.
About
A tool to automatically fix PHP Coding Standards issues