アクセスログのパースはたまにしかやらないけど、忘れるので書いとこう

<?php
$fp = fopen('access_log','r');
while ($d = fgets($fp, 8192)){
  var_dump(parse_log($d));
}

function parse_log($line){
  
  if (preg_match('@^([\d\.]+) \- \- \[(.*)\] "(GET|POST|HEAD) ([^ ]+) HTTP/([^ ]+)" (.*) (.*) "(.*)" "(.*)"$@', rtrim($line), $matches)) {
    // 4xx エラーコードは処理しない
    $ip = $matches[1];
    $status = $matches[6];
    if (preg_match('@^4\d{2}$@',$status)) return;
    $parts = preg_split("@[: /]@", $matches[2]);
    $epoch = strtotime(sprintf("%d %s %d %d:%d:%d", $parts[0], $parts[1], $parts[2], $parts[3], $parts[4], $parts[5]));
    $t = strftime("%Y-%m-%d %H:%M:%S", $epoch);
    $req = $matches[4];
    $ref = $matches[8];
    $ua = $matches[9];
    return compact("ip","status","req","ref","ua","t");
  }
}