Hygiena
Sekce hygiene rozhoduje o kódu, který jde napsat jednodušeji a se stejným významem: alias
místo funkce, is_null() a intval() místo jazykové konstrukce, dirname(__FILE__) místo
__DIR__, get_class() místo ::class, call_user_func() místo přímého
volání, dvě volání isset() nebo unset() místo jednoho a argument, který PHP ignoruje nebo který
jen opakuje výchozí hodnotu.
Jazyková konstrukce je rychlá vždy a nezáleží u ní na jmenném prostoru. Ve jmenném prostoru jsou opravy rizikové
(risky fixes): nekvalifikované is_null() může být funkce App\is_null(), kterou deklaruje váš
projekt. Dokud konfigurace neřekne nameResolution: certain, čekají na svolení.
Přímé volání místo call_user_func() je rizikové ještě v souboru se strict_types:
call_user_func() předává argumenty jako volající bez striktních typů, takže přímé volání může vyhodit
TypeError tam, kde se hodnota dosud převedla. Neplatí to, kde volání přeloží na přímé už samo PHP, tedy
u globální funkce bez pojmenovaných a rozbalených argumentů. Parametr předávaný referencí riziko nepřináší, protože
PHP při něm u call_user_func() hlásí varování při každém volání a změní se jen kód, který už teď
čistě nefunguje.
hygiene:
aliasFunctions: [core]
conversionFunction: forbidden
is_null: forbidden
dirnameOfFile: forbidden
classNameNotation:
object: required
call_user_func: forbidden
$count = sizeof($items); // The alias `sizeof()` must be written `count()`.
$id = intval($row['id']); // The `intval()` call must be written as the `(int)` cast.
if (is_null($user)) { // The `is_null()` call must be written as a comparison with `null`.
$dir = dirname(__FILE__); // The `dirname(__FILE__)` call must be written `__DIR__`.
}
$type = get_class($order); // The class name must be obtained with `$order::class`.
$result = call_user_func($callback, $id); // The callable must be called directly, not through `call_user_func()`.
$count = count($items);
$id = (int) $row['id'];
if ($user === null) {
$dir = __DIR__;
}
$type = $order::class;
$result = $callback($id);
Sekce a sada cleanup nejsou totéž:
sada rozhoduje i v jiných sekcích, o nepoužitých importech nebo prázdných komentářích, a z téhle sekce bere jen
část. Do --only, fixRisky nebo severity napíšete sekci jako hygiene a sadu
jako cleanup. Stejné jméno mají jen sekce a sada types, a tak tam, kde by holé types
mohlo znamenat obojí, ho DressCode odmítne: sekci napíšete types.*, sadu types.
hygiene.classNameNotation.currentClass
self::class, static::class and parent::class for get_class(),
get_called_class(), get_parent_class() and __CLASS__.
required: always therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
required, symfony keep ·
pokrývá SlevomatCodingStandard.Classes.ModernClassNameReference
hygiene.classNameNotation.object
$object::class for get_class($object).
required: always therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
required, symfony keep · pokrývá
get_class_to_class_keyword, SlevomatCodingStandard.Classes.ModernClassNameReference
hygiene.repeatedCatchBody
Two adjacent catches of one body, written as one catch (A|B $e).
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · PHP 7.1 · standardy: perCs keep, psr12 keep,
nette forbidden, symfony keep
hygiene.unreadCatchVariable
The variable of a catch that is never read, catch (E) written instead.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · PHP 8.0 · standardy: perCs keep, psr12 keep,
nette forbidden, symfony keep ·
pokrývá SlevomatCodingStandard.Exceptions.RequireNonCapturingCatch
hygiene.aliasFunctions
The sets of functions whose aliases are written by their canonical names.
- seznam z těchto slov:
all: every set belowcore: the core functions,sizeof()iscount(),join()isimplode()imap:imap_*ldap:ldap_*mysqli:mysqli_*pg:pg_exec()ispg_query()oci:oci_*odbc:odbc_*openssl:openssl_*sodium:sodium_*ftp:ftp_quit()isftp_close()posix:posix_errno()isposix_get_last_error()pcntl:pcntl_errno()ispcntl_get_last_error()time:mktime()andgmmktime()without arguments aretime()
keep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
[core, imap, pg], symfony keep · pokrývá no_alias_functions
hygiene.call_user_func
call_user_func($f, $x) is $f($x), call_user_func_array($f, $a) is
$f(...$a).
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · PHP 7.0 · standardy: perCs keep, psr12 keep,
nette forbidden, symfony keep · pokrývá regular_callable_call
hygiene.conversionFunction
intval($x) is (int) $x; intval($x, 16) is no cast.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep · pokrývá modernize_types_casting
hygiene.__invokeCall
$f->__invoke($x) is $f($x).
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep ·
pokrývá SlevomatCodingStandard.PHP.DisallowDirectMagicInvokeCall
hygiene.dirnameOfFile
dirname(__FILE__), which is __DIR__.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep · pokrývá PhpCsFixerCustomFixers/no_useless_dirname_call,
combine_nested_dirname, dir_constant
hygiene.nestedDirname
A dirname() of a dirname(), which is one call with the levels argument.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep
hygiene.is_null
is_null($x) is $x === null.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep · pokrývá is_null
hygiene.strlenEmptyTest
strlen($s) === 0 is $s === ''.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · jen s typy · standardy: perCs keep, psr12
keep, nette forbidden, symfony keep · pokrývá
PhpCsFixerCustomFixers/no_useless_strlen, string_length_to_empty
hygiene.settype
settype($x, 'int') as a statement is $x = (int) $x.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep · pokrývá set_type_to_cast
hygiene.defaultArgument
An argument PHP ignores or that repeats the default.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep
Argument, který jen opakuje výchozí hodnotu, zmizí z volání funkce vždy. U metody, statické metody a new
potřebuje DressCode typy kódu: musí znát každou třídu, kterou příjemce
může být, a každá z nich musí deklarovat stejnou výchozí hodnotu. Potomka, který by si ji změnil, nebere v úvahu,
protože by porušil kontrakt svého typu. Příjemce neznámého typu nebo takový, který může být několika třídami
s různými výchozími hodnotami, zůstane, jak je, a bez typů zůstanou metody i new všude.
typeAnalysis: phpstan
hygiene:
defaultArgument: forbidden
$json = json_encode($data, 0); // Useless `flags` argument of `json_encode()`, because it repeats the default value.
$memcached->delete($key, 0); // Useless `time` argument of `Memcached::delete()`, because it repeats the default value.
$json = json_encode($data);
$memcached->delete($key);
hygiene.separateIssets
isset($a) && isset($b) is isset($a, $b).
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep · pokrývá combine_consecutive_issets
hygiene.separateUnsets
unset($a); unset($b); is unset($a, $b);.
forbidden: never therekeep: nic se nevynucuje, kód zůstane, jak je
Výchozí keep · standardy: perCs keep, psr12 keep, nette
forbidden, symfony keep · pokrývá combine_consecutive_unsets