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.