I would like to introduce a PHP readable linter . It now contains 16 rules that should improve the readability of the code. The main advantages include:
- speed - less than a second per 1000 files
- baseline setting - you can not fix all the errors in the project at once, but create a configuration with current errors. And ignore them, but react to new ones.
- rules are easier to write than analogs (subjective)

Two important disclaimers :
- I am the main contributor, so I can be subjective. Readable was originally written for the Belgian company officient . They have been using it internally for some time now, and decided to make readable an open source project.
- It is written in JS.
Installation and launch
readable is installed via npm:
$ npm install @officient/readable --save-dev
After installation, you need to create a configuration file:
$ npx readable --init
And you can run:
$ npx readable
rules
There are currently 16 rules in readable:
- namespace-max-files - maximum number of files in the namespace
- argument-override - prohibit changing the value of function arguments
- file-max-size - the maximum number of lines in the file
- empty-catch - ban on empty
catchblock - class-comment — - ,
- forbidden-functions — (
eval,print_r...) - missing-braces —
if,for... - variable-length — (
$id,$i) - function-max-size —
- loop-max-size —
- forbidden-function-prefix — . ,
checkSomething— , ? - if-assigment —
if - complex-if —
&&||if - ternary-max-length —
- loop-max-nest —
- max-nest —
readable , . — . , - , :
- readable . , .
- . , .
Let's take the loop-max-size rule as an example . All his code:
const loops = ['for', 'foreach'];
module.exports = {
check(maxLines, tokens, report) {
tokens.matchAll(loops, (token) => {
const end = token.copy().step().stepToClosing(); // skip ()
end.step().stepToClosing();
const lines = (end.current().line - token.current().line);
if (lines > maxLines) {
report(`Loop is longer than ${maxLines} lines [${lines}].`, token.current());
}
});
},
};
The rule states:
- find everything
forandforeach. - Take the next token
.step(), it will be an open parenthesis(. Go to the closing parenthesis.stepToClosing(). - Repeat the second step but for the body of the loop (
{and}). - Check the length of the cycle body.
Instead of a conclusion
I use readable in my projects as an additional linter for code. I like everything, especially the baseline (in fairness, Psalm also has this). He has the opportunity to occupy the niche of the auxiliary linter.