Advent of code 2018/18
Ajax Direct

Answer 4899ms

Part 1 : 637550 Part 2 : 201465
function solve($grid, $time) {
    $width  = count($grid[0]);
    $height = count($grid);
    $track  = [];

    for ($t = 1; $t <= $time; $t++) {
        $next = [];
        foreach ($grid as $y=>$row) foreach ($row as $x=>$c) {
            $nc = ["|" => 0, "." => 0, "#" => 0];
            foreach (neighbors([$x, $y], true, 0, $width - 1, 0, $height - 1) as $n) {
                $nc[$grid[$n[1]][$n[0]]]++;
            }

            $next[$y][$x] = match($grid[$y][$x]) {
                "." => $nc["|"] >= 3 ? "|" : ".",
                "|" => $nc["#"] >= 3 ? "#" : "|",
                "#" => $nc["#"] >= 1 && $nc["|"] >= 1 ? "#" : ".",
            };

        }
        $grid = $next;

        $cells = set($grid)->merge();
        $track[$t] = $cells->keep("#")->count() * $cells->keep("|")->count();
    }

    return $track;
}

// ==================================================
// > PART 1
// ==================================================
$grid = array_map("str_split", explode("\n", $input->string));
$solution_1 = solve($grid, 10)[10];

// ==================================================
// > PART 2
// ==================================================
$t = $tx = 500;
$track = solve($grid, $t);              // Track 500 minutes
while ($track[--$tx] != $track[$t]);    // Find repeated pattern starting from the end
$s = array_search($track[$t], $track);  // Find start of pattern
$l = $t - $tx;                          // Length of pattern
$p = (1_000_000_000 - $s) % $l;         // Place in pattern
$solution_2 = $track[$s + $p];          // Value at that moment