chriswarbo-net: cfeab4a6caf7d0d3aaf31a743129e1807d171877
1: ---
2: title: PHP Reference Silliness
3: ---
4: Today I needed to pop arrays in a loop in PHP, starting with one and falling back to another when it runs out. A naïve implementation might do this:
5:
6: ```php
7: if (count($bar)) {
8: $foo = array_pop($bar);
9: }
10: else {
11: $foo = array_pop($baz);
12: }
13: ```
14:
15: However, I always cringe when I see code like this. Why branch on a whole statement when you could just branch on the expression you care about?
16:
17: ```php
18: $foo = count($bar)? array_pop($bar) : array_pop($baz);
19: ```
20:
21: Of course, this is still redundant, since we're calling `array_pop` twice. Let's shrink the branch again:
22:
23: ```php
24: $foo = array_pop(count($bar)? $bar : $foo);
25: ```
26:
27: Aaaaaaaand... PHP dies. It won't let us pass-by-reference with a calculated expression like this ternary statement. Sad times. We can sometimes work around PHP's stupid pass-by-reference crap using `call_user_func`, but not this time. However, we **can** call-by-reference on elements inside an array, and we **can** look up those elements using a calculated expression. This means we can swap `$bar` and `$baz` for `$a = array($bar, $baz)` and use the following:
28:
29: ```php
30: $foo = array_pop($a[count($a[0]) > 0]);
31: ```
32:
33: In fact, while writing this up, I found another refactoring in the generation of `$bar` and `$baz` which lets me do away with their distinction by the time we get this far, so I can just `array_merge` them together and pop that until it's empty :)
Generated by git2html.