Avoid Ref Multidim Array
ID |
php.avoid_ref_multidim_array |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Php |
Tags |
arrays, reliability |
Description
Reports the reference operator & applied to an element of a multidimensional array, either in
a reference assignment ($cell = &$matrix[1][2];) or as a by-reference function argument
(foo(&$matrix[1][2]);). References into a single dimension or to the whole array are not
flagged.
Rationale
PHP arrays use copy-on-write. When a reference is taken into a nested element, that copy-on-write sharing is broken in surprising ways: the engine frequently has to materialise a full copy of the outer array, and the resulting alias can mutate sub-arrays the caller never intended to change. The behaviour of references into nested structures is a long-standing source of hard-to-trace bugs, and the cost of the hidden copy can be significant for large matrices.
<?php
function tweak(array $matrix): void
{
$cell = &$matrix[1][2]; // FLAW - reference into a two-dimensional element
$row = &$matrix[1]; // OK - single dimension reference
$copy = $matrix[1][2]; // OK - plain copy, no reference
}
Remediation
Prefer working with a plain copy of the element ($cell = $matrix[1][2];) and writing the result
back explicitly, or restructure the data so the value you need to alias lives at a single level.
When a reference is genuinely required, bind it to a one-dimensional sub-array first
($row = &$matrix[1]; $cell = &$row[2];) so the aliasing is explicit and contained.