Functions
The functions section decides on functions and closures (anonymous functions): whether a closure
that only returns one expression is written as an arrow function, whether a closure that does not use $this gets
static, whether true and false are passed as named arguments, and what to do with a
return at the end of a function, with a parameter default that is never used, and with a function declared inside
another function.
How a signature and its parentheses are written belongs to other sections: the spacing section covers the space after function and
fn, the braces section covers the brace of a closure, and the
types section covers the types of parameters.
functions:
arrowFunction:
oneExpression: required
trailingBareReturn: forbidden
unreachableParameterDefault: forbidden
$names = array_map(function ($user) { // The closure returning a single expression must be written as an arrow function.
return $user->name;
}, $users);
function writeLog(string $message, $level = 'info', $context) // Useless default value of `$level`, because a required parameter follows.
{
echo $message;
return; // Useless return, because the function ends right after it.
}
$names = array_map(fn($user) => $user->name, $users);
function writeLog(string $message, $level, $context)
{
echo $message;
}
A closure is rewritten to an arrow function only where the two mean the same: the closure does not capture a variable by reference, it does not touch a variable it does not name, and no comment is lost.
functions.trailingBareReturn
return; as the last statement.
forbidden: never therekeep: nothing is enforced, the code stays as it is
Default keep · standards: perCs keep, psr12 keep, nette
forbidden, symfony forbidden, laravel forbidden ·
covers no_useless_return
functions.arrowFunction.oneExpression
An arrow function written for a closure whose body is a single return, where that is equivalent: no variable
captured by reference, none reached by a name it does not spell out, no comment lost.
Not about the static of the arrow function, which functions.staticClosure decides.
required: always therekeep: nothing is enforced, the code stays as it is
Default keep · standards: perCs keep, psr12 keep, nette
required, symfony keep, laravel keep · covers
use_arrow_functions, SlevomatCodingStandard.Functions.RequireArrowFunction
functions.arrowFunction.emptyBody
fn() => null written for a closure with an empty body, one returning void, never or
by reference aside.
required: always therekeep: nothing is enforced, the code stays as it is
Default keep · standards: perCs required, psr12 keep, nette
keep, symfony required, laravel keep
functions.arrowFunctionNested
Whether a closure holding another closure or arrow function becomes one too.
yesorno
Default no · standards: perCs no, psr12 no, nette
yes, symfony no, laravel no ·
covers SlevomatCodingStandard.Functions.RequireArrowFunction
functions.namedBooleanArgument
A true or false passed by position to a parameter declared bool, written with the name
of the parameter, json_decode($json, associative: true); not where a positional argument follows it, nor in a call of
a setter, setVisible(true), or of a function PHP calls without a frame or optimizes.
required: always therekeep: nothing is enforced, the code stays as it is
Default keep · standards: perCs keep, psr12 keep, nette
keep, symfony keep, laravel keep
A named argument says what the true or false turns on or off, so the reader does not have to look up
the signature. DressCode names only arguments at the end of a call, with no positional argument after them, because PHP does not
accept a positional argument after a named one. A setter like setVisible(true) already says this in its name, so it
stays as it is. Functions that PHP calls without a stack frame, or that the compiler optimizes, such as in_array(),
also stay as they are: a named argument would cost them the optimization. You can list other functions and methods in
functions.namedBooleanArgumentExcept.
DressCode knows the parameter names of PHP functions by itself. For methods, new and the functions of your
project, it needs the types of the code; without them, it leaves such
calls alone.
functions:
namedBooleanArgument: required
namedBooleanArgumentExcept: [print_r]
$data = json_decode($json, true); // The boolean argument of `json_decode()` must be named `associative`.
$html = htmlspecialchars($text, ENT_QUOTES, 'UTF-8', false); // The boolean argument of `htmlspecialchars()` must be named `double_encode`.
echo print_r($data, true);
$data = json_decode($json, associative: true);
$html = htmlspecialchars($text, ENT_QUOTES, 'UTF-8', double_encode: false);
echo print_r($data, true);
The fix is a risky fix for a call to a method that a child class can override, such as $this->render(true) in a
class that is not final, or a call through an interface: the child class can give the parameter a different name, and the call
would then fail. Calls to a private or final method, calls to a method of a final class, calls through
self:: and parent::, and new are not risky. Risky fixes are made once you list the decision
in the fixRisky key.
functions.namedBooleanArgumentExcept
The functions and methods whose arguments stay positional, a method written with the class declaring it or the one it is called
on, Acme\Shop\Cart::add.
- a list of names
Default [] · standards: perCs [], psr12 [], nette
[], symfony [], laravel []
functions.innerFunction
A named function declared inside a function, a method, a closure or a property hook, which is only reported.
forbidden: never therekeep: nothing is enforced, the code stays as it is
Default keep · standards: perCs keep, psr12 keep, nette
forbidden, symfony keep, laravel keep · covers Squiz.PHP.InnerFunctions
functions.staticClosure
The static keyword of a closure or an arrow function that does not use $this.
required: always there,static functionkeep: nothing is enforced, the code stays as it is
Default keep · standards: perCs keep, psr12 keep, nette
keep, symfony keep, laravel keep · covers
static_lambda, SlevomatCodingStandard.Functions.StaticClosure
The fix is a risky fix: a closure can be bound to an object somewhere else, through bindTo() or
Closure::bind(), and that cannot be seen from a single file. The fix is made once you list the decision in the fixRisky key.
functions.unreachableParameterDefault
A default a required parameter after it makes unreachable.
forbidden: never therekeep: nothing is enforced, the code stays as it is
Default keep · standards: perCs keep, psr12 keep, nette
forbidden, symfony keep, laravel forbidden · covers
no_unreachable_default_argument_value,
PEAR.Functions.ValidDefaultValue, SlevomatCodingStandard.Functions.UselessParameterDefaultValue