OnlyWritesOnParameter
info on by defaultGroup: Unused · PhpStorm name: OnlyWritesOnParameterInspection
A parameter, closure import or local variable that is only ever written to (elements appended, incremented, concatenated onto…) but never read is dead work: the changes are lost when the function returns (by-value semantics). Likewise a closure use import that the closure body never touches, or an inline assignment whose target is never read afterwards, is unused.
Example
IGNORE_INCLUDES = false:
php
<?php
class Report
{
public function collect(array $rows, array &$sink, $tally, Closure $done, Iterator $it)
{
return function ($pending, array &$bucket) use ($rows, &$sink, $tally) {
$pending['x'] = 1;
$bucket[] = 2;
$tally[] = 3;
};
}
public function counters($hits, $misses, $sum, &$total, Iterator $it)
{
$hits++;
--$misses;
$sum *= 2;
$total++;
$it[] = 1;
}
public function inline_unused()
{
if (null !== ($pos = strpos('abc', 'b'))) {
return true;
}
$map = [];
$map[$key = 'k'] = 1;
$map[$slot = 'z'] = 2;
return $slot . count($map);
}
public function locals($flag)
{
$buffer = $other = [];
if ($flag) {
$buffer[] = 1;
}
$other .= 'x';
$kept = '';
$kept .= 'y';
echo $kept ?? '';
$alias = &$flag;
$alias .= 'z';
$unusedPlain = 5;
}
public function with_include($n, $path)
{
$n -= 1;
require $path;
}
}
function makeHandlers(ArrayObject $registry, array $plain, string $template)
{
$store = new SplObjectStorage();
$register = function ($name) use ($registry, $plain, $store) {
$registry[$name] = true; // E5b: object import, the write is visible
$store[] = $name; // E5b: inferred SplObjectStorage
$plain[$name] = true;
};
$render = function () use ($template, $registry) {
require __DIR__ . '/view.php'; // E5c: the view may read $template and $registry
};
$noop = function () use ($template) {
$inner = function () { include 'x.php'; }; // nested closure: its include does not count
};
}
function silenced(array $out)
{
/** Buffers. @noinspection OnlyWritesOnParameterInspection */
$out['a'][] = 1;
$out['b'][] = 2;
}Reported:
- line 6: Variable is never used.
- line 7: Value is only written here and never read; the write is lost.
- line 9: Value is only written here and never read; the write is lost.
- line 15: Value is only written here and never read; the write is lost.
- line 16: Value is only written here and never read; the write is lost.
- line 17: Value is only written here and never read; the write is lost.
- line 24: Variable is never used.
- line 28: Variable is never used.
- line 37: Value is only written here and never read; the write is lost.
- line 39: Value is only written here and never read; the write is lost.
- line 64: Value is only written here and never read; the write is lost.
- line 69: Variable is never used.
Options
| Option | Type | Default | Effect |
|---|---|---|---|
IGNORE_INCLUDES | bool | true | When on, write-only findings are reported even if the scope contains include/require (which could read variables). When off, such scopes produce no W findings. U findings are unaffected. |
Configure
In custos.json:
json
{
"rules": {
"OnlyWritesOnParameter": {
"enabled": false,
"options": {
"IGNORE_INCLUDES": true
}
}
}
}Suppress
Before the statement or declaration (or the first statement of the file), either of:
php
// @custos-ignore OnlyWritesOnParameter
/**
* @noinspection OnlyWritesOnParameterInspection
*/