はじめに
filemtime() を使っている箇所で、しばしばログに E_Warning が出ていました。例の SJIS 上の「表」などの文字の問題です。
やれやれと思いながら調べると下記の記事を見つけました。
参考:Windows版 PHP(7.1前) での日本語パスの対応状況と暫定回避策
簡単には行きませんでした。
実装
上記の記事を参考に、「dir /T:w」を使用して filemtime() を実装しました。
<?php
// Windows 専用の filemtime()
function filemtime_win($filename)
{
$ret = FALSE;
$dirCmdError = null;
$m = null;
if (!ob_start()) {
return FALSE;
}
passthru('dir /T:w ' . $filename . ' 2>nul', $dirCmdError);
if ($dirCmdError !== 0) {
ob_end_clean();
return FALSE;
}
foreach (explode("¥r¥n", ob_get_contents()) as $line) {
if (preg_match('/^¥d{4}¥/¥d{2}¥/¥d{2}¥s*¥d{2}:¥d{2}/', $line, $m)) {
$ret = strtotime($m[0]);
break;
}
}
ob_end_clean();
return $ret;
}
// 「表」配下の「ン」配下の「可能.pdf」にアクセスしてみる
$filename = "表¥¥ン¥¥可能.pdf";
$utf8 = mb_convert_encoding($filename, 'UTF-8', 'CP932');
if ($filename !== mb_convert_encoding($utf8, 'CP932', 'UTF-8')) {
echo 'ERR: file name encoding error.', PHP_EOL;
die;
}
$mtime = filemtime_win(escapeshellarg($filename));
if ($mtime === FALSE) {
echo 'ERR: file mtime error.', PHP_EOL;
die;
}
echo Date('Y/m/d H:i:s', $mtime);
escapeshellarg() は外に出しました。