Tips and Tricks for Code Golfing in PHP

I see there are ‘code golf tips’ topics for some languages, but not for PHP, so let me start one.
I list some generic, non-puzzle specific tips I encountered - this is intended for beginners, as I am not a PHP pro at all. The best submissions on leaderboard seem unimaginably compact for me, so I start this topic not for altruism, but in hope that some real pros share some more tips (but not spoilers) :slight_smile:

  • Use only <? instead of <?php and you can skip the ?> at the end. No space after <? is needed.
  • Use fgets(STDIN) instead of stream_get_line. Unfortunately, it also reads the CR (end-of-line) character, but that is not a problem with integers. For real strings, you can use rtrim(fgets(STDIN))
  • If you need multiple fgets (e.g. init and per turn input), use fgets($s=STDIN) … fgets($s) instead of using fgets(STDIN) twice.
  • No space needed in input parsing format string, e.g. fscanf(STDIN,"%d%d",$y,$x)
  • Use && || logical operators instead of ‘and or’. They have different precedence, so for example this expressions does not need any parentheses: if(a<$b||$c>0&&$d=1)
  • If possible, refactor comparison expressions to use < or > instead of <=, >=, ==, !=
  • Use the PHP v7.x spaceship operator $a<=>$b instead of ($a<$b?-1:($a>$b?1:0))
  • Use the Elvis operator $a?:$b if you find a case where you can (well, to be honest, so far I didn’t)
  • To iterate on characters of a string, use foreach(str_split($M)as$m) … $m … instead of for($i=0;$i<strlen($M);$i++) … $M[$i] …
  • Use while(1) instead of while(TRUE) for endless loops
  • Use echo $a."\n"; instead of echo ($a."\n"); echo is not a function but language construct. If you need to print single variable(s) and not an expression, then echo “$a\n”; also works.
  • Use join instead of implode. Unfortunately in PHP v7.x split is no longer possible instead of explode.
  • Use $a=$b=0; instead of $a=0;$b=0; Even better if you have an unrelated for cycle beforehand, you can reuse the init part to init an extra varible, e.g. for($i=$a=0;…
  • Use ternary operator instead of if…else
  • If you need to use same library function with a long name more than twice, then name it. E.g. use $f=‘strlen’; … $f(…) … $f(…) $f(…) instead of strlen(…) … strlen(…) … strlen(…)
  • This might be obvious, but single statement block don’t need { }
  • Use post-increment operators ++ within expression. Skip 3rd section of for loop. E.g. for($j=0;$j<7;) … $p[$j++ ] …
  • use $a=[] … instead of $a=array() …
  • Actually it is very rare when PHP really needs a whitespace. Only if a variable name would mix with a reserved word, e.g. foreach($P as$p) But foreach($P[$i]as$p) is fine.

EDIT: added:

  • you don’t need \n in the echo. A real linefeed in double qutes is fine in the source code and it is 1 byte less.
  • consider using fgetcsv for input parsing of multiple, space delimited variables. E.g. [$L,$M,$X,$Y]=fgetcsv(STDIN,0,’ ')
<?=`insert your bash code here`

Okay, that’s nice and unbeatably efficient, but takes away the whole point of code golf on a given language as a fun exercise and learning the language a bit better… :slight_smile:

It is somewhat like writing a multiplayer bot that calls out to a much powerful machine on the cloud to perform the most resource intensive part of a search (i dont’ know whether it is possible or rest api calls are disabled to avoid such cheat.)

I’m not the one you have to convince. I already agree with you. But for CodinGame golf puzzles, you can’t beat a bash code most of the time. So if you want to win, this is the only choice.

If you want to have fun, you can use the others tricks.

Agree :slight_smile:
Then, this is an improvement suggestion for CG - show also a leaderboard that excludes the solutions using embedded bash or perl code.
E.g. my current solutions in PHP for the 4 puzzles (in abc order) are 302/224/136/136 characters. I am curious how far am I from what is achievable without bash but I have no way to tell.
There might be some additional language hacks which I don’t know (actually that is why I opened this topic), or there might be completely different algorithms / approaches I did not think of.