The JavaScript gets compiled nearly 1:1, so 10^9 loops with not much flesh in it run as fast as the CPU allows (here: 2.14s. with an old node, version v0.10.25 ).
PHP on the other side does a lot, especially the Zend machine. If you dump the op-codes of your little program with VLD you get (php 7.0.5):
$ php -d vld.active=1 -d vld.execute=0   -f benchmark.php
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 14
Branch analysis from position: 14
Jump found. Position 1 = 16, Position 2 = 4
Branch analysis from position: 16
Jump found. Position 1 = -2
Branch analysis from position: 4
Jump found. Position 1 = 10
Branch analysis from position: 10
Jump found. Position 1 = 12, Position 2 = 6
Branch analysis from position: 12
Jump found. Position 1 = 16, Position 2 = 4
Branch analysis from position: 16
Branch analysis from position: 4
Branch analysis from position: 6
Jump found. Position 1 = 12, Position 2 = 6
Branch analysis from position: 12
Branch analysis from position: 6
filename:       benchmark.php
function name:  (null)
number of ops:  21
compiled vars:  !0 = $a, !1 = $b, !2 = $j, !3 = $i
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, 3.14159
   3     1        ASSIGN                                                   !1, 2.718
   5     2        ASSIGN                                                   !2, 0
         3      > JMP                                                      ->14
   6     4    >   ASSIGN                                                   !3, 0
         5      > JMP                                                      ->10
   7     6    >   ADD                                              ~8      !0, !1
         7        ASSIGN                                                   !0, ~8
   6     8        POST_INC                                         ~10     !3
         9        FREE                                                     ~10
        10    >   IS_SMALLER                                       ~11     !3, 100000000
        11      > JMPNZ                                                    ~11, ->6
   5    12    >   POST_INC                                         ~12     !2
        13        FREE                                                     ~12
        14    >   IS_SMALLER                                       ~13     !2, 10
        15      > JMPNZ                                                    ~13, ->4
  10    16    >   ROPE_INIT                                     3  ~15     'a+%3D+'
        17        ROPE_ADD                                      1  ~15     ~15, !0
        18        ROPE_END                                      2  ~14     ~15, '%0A'
        19        ECHO                                                     ~14
        20      > RETURN                                                   1
branch: #  0; line:     2-    5; sop:     0; eop:     3; out1:  14
branch: #  4; line:     6-    6; sop:     4; eop:     5; out1:  10
branch: #  6; line:     7-    6; sop:     6; eop:     9; out1:  10
branch: # 10; line:     6-    6; sop:    10; eop:    11; out1:  12; out2:   6
branch: # 12; line:     5-    5; sop:    12; eop:    13; out1:  14
branch: # 14; line:     5-    5; sop:    14; eop:    15; out1:  16; out2:   4
branch: # 16; line:    10-   10; sop:    16; eop:    20; out1:  -2
path #1: 0, 14, 16, 
path #2: 0, 14, 4, 10, 12, 14, 16, 
path #3: 0, 14, 4, 10, 6, 10, 12, 14, 16, 
The difference between your two versions is
1,10c1,10
< branch: #  0; line:     2-    5; sop:     0; eop:     3; out1:  14
< branch: #  4; line:     6-    6; sop:     4; eop:     5; out1:  10
< branch: #  6; line:     7-    6; sop:     6; eop:     9; out1:  10
< branch: # 10; line:     6-    6; sop:    10; eop:    11; out1:  12; out2:   6
< branch: # 12; line:     5-    5; sop:    12; eop:    13; out1:  14
< branch: # 14; line:     5-    5; sop:    14; eop:    15; out1:  16; out2:   4
< branch: # 16; line:    10-   10; sop:    16; eop:    20; out1:  -2
< path #1: 0, 14, 16, 
< path #2: 0, 14, 4, 10, 12, 14, 16, 
< path #3: 0, 14, 4, 10, 6, 10, 12, 14, 16, 
---
> branch: #  0; line:     2-    5; sop:     0; eop:     3; out1:  13
> branch: #  4; line:     6-    6; sop:     4; eop:     5; out1:   9
> branch: #  6; line:     7-    6; sop:     6; eop:     8; out1:   9
> branch: #  9; line:     6-    6; sop:     9; eop:    10; out1:  11; out2:   6
> branch: # 11; line:     5-    5; sop:    11; eop:    12; out1:  13
> branch: # 13; line:     5-    5; sop:    13; eop:    14; out1:  15; out2:   4
> branch: # 15; line:    10-   10; sop:    15; eop:    19; out1:  -2
> path #1: 0, 13, 15, 
> path #2: 0, 13, 4, 9, 11, 13, 15, 
> path #3: 0, 13, 4, 9, 6, 9, 11, 13, 15, 
It ($a += $b) just uses a different, slightly slower(!) path. Yes, slower: my tests gave 17s. for $a = $a + $b and 20s. for $a += $b. Not much, although significant. And also not that much of a difference to JavaScript.
Two minutes for your version of PHP is quite large, even an old PHP-5 did it in 40 seconds here. I couldn't find anything in the ChangLogs but you might try an update if possible. Or try different optimizations if you compiled it yourself because a MAC is still different from a "normal" PC.