compact()
is a problematic construct that breaks the direct code link between variable definition and variable consumption.
$someVar = 123;
return compact('someVar');
This is equivalent to
$someVar = 123;
return ['someVar' => $someVar];
Practically, this started working in PHPStorm and PHPStan because it's used extensively in the Laravel community, but it requires non-trivial hackery. From a code review and code analysis perspective, especially for any tools that didn't implement the necessary hackery, it is problematic.
At lower level, there's obviously additional work happening when using compact()
.
This is what an array declaration looks like: https://3v4l.org/XXsL2/vld
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /in/XXsL2
function name: (null)
number of ops: 4
compiled vars: !0 = $someVar
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
3 0 E > ASSIGN !0, 123
5 1 INIT_ARRAY ~2 !0, 'someVar'
2 > RETURN ~2
3* > RETURN 1
This is what a compact call looks like instead: https://3v4l.org/HDbuh/vld
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /in/HDbuh
function name: (null)
number of ops: 6
compiled vars: !0 = $someVar
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
3 0 E > ASSIGN !0, 123
5 1 INIT_FCALL 'compact'
2 SEND_VAL 'someVar'
3 DO_ICALL $2
4 > RETURN $2
5* > RETURN 1
The code for compact then emulates part of the PHP engine to try and behave as if it was PHP code: https://github.com/php/php-src/blob/d78b3fe94338b10981a71083d0d515194705ae13/ext/standard/array.c#L2480-L2517
In the above code, the function implementation will access the current stack frame, extract information from it, then produce an array structure from it.
This means that compact()
does not really behave like a function, since its inputs are contextual, and not given
explicitly: that makes it harder to spot problems in its usages.