# Tips for golfing in PHP

What general tips do you have for golfing in PHP? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to PHP (e.g. "remove comments" is not an answer). Please post one tip per answer.

• Wait, am I doing it right?... Anyway, I'm really curious about this one. PHP is used by many people and golfers, but I almost have no idea how to golf a PHP code. – JiminP Jun 20 '11 at 14:11
• Use short tags <??> It can save a few bytes. – Mob Aug 12 '11 at 20:49

### Use short append syntax to add elements to the end of an array.

Instead of keeping track of the number of elements:

$array[++$i] = $value; Or using the explicit push function: array_push($array, $value); You can use the implicit push feature:$array[] = $value; • With a rare exception: when you need to append more than 3 elements, array_push($array, $value,$value, $value,$value); may be shorter; – manatwork Jan 5 '17 at 19:37

Use:

$array = json_decode('...'); • I think explode is also worth a shot. – Titus Jan 6 '17 at 0:08 # Switches base on arrays or strings A little collection which can save Bytes for different conditions Switch a function through an array <?=(bc.[sub,add,mul,pow][($x=$argn)&3])($x,$x); Make different Math operations <?=[0,($x=$argn)+$x,$x*$x,$x**$x][$x&3]; Ternary Operator to switch a function echo(strto.(rand()&1?low:upp).er)($c);

Using the Keys in an array as conditions

echo[ctype_alpha($s=dechex($argn))=>"Only letters",ctype_digit($s)=>"Only numbers",Mix][1]; special on strings but only not in all cases you must use a function and trim will do nothing ($bool?trim:strtolower)($string) character switch "char"[$x%4]

character only in zero cases

"c"[$x%2] ## Return two copies of an expression If you want to get two copies of the result of an expression, you can use this:$v.$v=expr But it won't be shorter than the more straightforward ($v=expr).$v if you need to append more things to the result. For 4 copies:$v.$v.=$v=expr

You cannot use it to get 3 copies.

I didn't see it listed so when using a list and explode you can use a number as the delimiter ( assuming its not in the string of course ). This lets you get rid of the quotes.

If there is backslash before the delimiter then it has to be 8 or 9 so it doesn't get confused with octal ( such as \0 )

explode(",", "one,two,buckle,my,shoe")

You can do this

explode(1, "one1two1buckle1my1shoe")

Saving 2 bytes for the quotes.

As I mentioned for backslashes

explode(",", "/ \,| .. |,\ /");

Use 8 or 9

explode(8, "/ \8| .. |8\ /");  // so you get \8 instead of \0 etc..

# seek potential in combining several expressions to one

It´s easy to see that A?B:C; is shorter than if(A)B;else C;
A&&B is shorter than if(A)B; and A||B; is shorter than if(!A)B;

But how can if(A){B;C;}else{D;E;} be golfed?

Assume that B returns something truthy and D something falsy:

if(A){B; C;}else{B; C;}  # 21 bytes
A?    B&&C  :    B||C;   # 12 bytes

another one:

if(A){$b=123;$c="hello";} # 25 bytes
A&&$b=123+!$c="hello":    # 22 bytes
A&&$c="hello".!$b=123;    # also 22 bytes

$c="hello is truthy, so !$c is false. + casts to int; so we add 0 to 123.
$b=123 is truthy, so !$b is false. . casts to string, and that´s empty for false.

I even had a case today where appending digits to the string didn´t make a difference.
(See line 5 of the breakdown.)

more examples:

for(;;$a++,print$x);
for(;;$a+=print$x);

print always returns true, so its return value can be added to $a instead of incrementing$a separately.

$a=1,$b=0
$a=!$b=0

if(X){$a=123;$b=0;}
X&&$a=123+$b=0;     # useful if you need $b to be and int (for printing) X&&$b=!$a=123; if(X){$a=123;$b=1;} X&&$b=!!$a=123; X&&$a=123*$b=1; ## advanced: combining nested loops takes a new level to combining expressions. There is no general solution or approach; and it doesn´t always make the code shorter. Good chances are when the outer loop has no body except the inner loop; imagine shifting through a 2D array or sorting one. Try for($a=1;$a<20;$a+=print"\n")for($b=$a;$b++<20;)echo$a*$b,"\t"; 61 bytes (counting the control characters as one each) that loop$a from 1 to 19, $b from$a+1 to 20
and print the products, breaking the line when $a increments. Ok, one simple two-byte saving is for($a=1;20>$b=$a;$a+=print"\n")for(;$b++<20;)echo$a*$b,"\t";

Combining the two loops to one saves another two bytes:

for($a=$b=1;$b++<20||21>$b=1+$a+=print"\n";)echo$a*$b,"\t"; And you can save two more bytes with a leading linebreak instead of a trailing one (this often saves a byte or two): for($b=20;$b++<20||21>$b=1+$a+=print"\n";)echo$a*$b,"\t"; This is a pretty easy and rewarding example; so don´t be upset if your first attempts fail on saving bytes. It may take a while until you get an eye for it. Ok, for(;20>$b=++$a;print"\n")for(;$b++<20;)echo$a*$b,"\t"; is golfier; and in PHP 7, you can even avoid trailing tabs without any costs: for(;20>$b=++$a;)for(;$b++<20;)echo$a*$b,"\n\t"[$b<20];

But imagine you have to loop $a from somewhere else but 1, like through ascii codes. I may one day come up with an example that makes more sense. No promises on these premises though. • primo also posted on combining loops in March 2014. Don´t miss out on that one! – Titus Feb 22 '19 at 15:26 When using array_values() to re-index an array with numeric keys, from PHP7.4 you can use a technique that I call splatpacking (see link for further details and a demonstration). You use the "splat/spread" operator to "unpack" the array, then immediately "repack" the elements into an empty array. Though not designed for this purpose, the result is the same -- in that limited scenario. Technique using$a representing an array:

array_values($a) // 14 characters (not counting$a)

becomes

[...$a] // 5 characters (not counting$a)

You may not always require echo, for instance:

<?php $a=f();if($a)echo'blah';

Vs

<?php $a=f();if($a)?>blah