Advent of code 2017/3
Ajax Direct

Answer 115ms

Part 1 : 419 Part 2 : 295229
function spiral() {
    $x = $y = $dx = $dy =  0;
    $i = $l = 1;

    while(++$l) {
        // Get direction
        [$dx, $dy] = match (true) {
            $x > 0 && $y < 0   => [-1,  0],  // Top right
            $x < 0 && $y < 0   => [ 0,  1],  // Top left
            $x <= 0 && $y >= 0 => [ 1,  0],  // Bottom left
            $x > 0 && $y >= 0  => [ 0, -1],  // Bottom right
        };

        $length = floor($l / 2); // Size of the current side

        for ($j = 1; $j <= $length; $j++, $i++) {
            yield [$x, $y, $i];
            [$x, $y] = [$x + $dx, $y + $dy];
        }
    }
}

// ==================================================
// > PART 1
// ==================================================
foreach (spiral() as [$x, $y, $number]) if ($number == $input->int) break;
$solution_1 = abs($x) + abs($y);

// ==================================================
// > PART 2
// ==================================================
$grid = grid();
foreach (spiral() as [$x, $y, $number]) {
    $value = $number == 1 ? 1 : $grid->getNeighbors([$x, $y], true)->filter()->sum();
    $grid->set([$x, $y], $value);
    if ($value > $input->int) break;
}

$solution_2 = $value;