記事に挿入する画像はfunctions.phpにコードを追加して自動的にルート相対パス化されるようにしていましたが、simplicity2.3.1のAMP対応化後からPHP Warningが出るようになってしまいました。原因が分かったので対策してみます。
※過程が不要な場合は「3.原因がわかったので対策する」に進んでください。
1.PHPエラーの発覚
apacheのerror_log(ssl_error_log)に大量のPHP warningが記録されるようになりました。
# cat /var/log/httpd/ssl_error_log [Fri Oct 14 11:49:58 2016] [error] [client 66.249.79.83] PHP Warning: getimagesize(/wp-content/uplo ads/2016/10/2_yokohama-okurayama_wakaba_cheesedorayaki.jpg): failed to open stream: No such file or directory in /var/html/wp-content/themes/simplicity2/lib/amp.php on line 176 ...
エラーはsimplicity2.3.1以降から追加された「amp.phpファイルが画像ファイルにアクセスできない」というもの。ファイルは間違いなく存在しますし、パーミッションにも問題なし。何より、ほぼ同一構成の検証環境ではエラーが発生しないので原因が不明でした。
2.PHPエラーの原因
2~3日調べてようやく原因が分かりました。「PHP Warning: getimagesize()」で調査するとヒットする生地は()の中が「絶対パス」なのに、本エラーには「ルート相対パス」(プロトコルとドメイン名が省略されたパス)が表示されているのです。
そうなると根本原因はfunctions.phpに追加した以下のコードだということが分かりました。
// Posting The Relative URL(image,link)
function delete_host_from_attachment_url( $url ) {
$regex = '/^http(s)?:\/\/[^\/\s]+(.*)$/';
if ( preg_match( $regex, $url, $m ) ) {
$url = $m[2];
}
return $url;
}
add_filter( 'wp_get_attachment_url', 'delete_host_from_attachment_url');
add_filter( 'attachment_link', 'delete_host_from_attachment_url' );
このコードによりamp.phpの以下のコードが参照する画像ファイルのパスも影響を受けているようです。
//画像URLから幅と高さを取得する(同サーバー内ファイルURLのみ)
function get_image_width_and_height($image_url){
$wp_upload_dir = wp_upload_dir();
$uploads_dir = $wp_upload_dir['basedir'];
$uploads_url = $wp_upload_dir['baseurl'];
$image_file = str_replace($uploads_url, $uploads_dir, $image_url);
$imagesize = getimagesize($image_file);
if ($imagesize) {
$res = array();
$res['width'] = $imagesize[0];
$res['height'] = $imagesize[1];
return $res;
}
}
3.原因がわかったので対策する
delete_host_from_attachment_urlを、記事執筆中の「メディアを追加」操作だけに反映できれば良いのです。つまり管理画面(is_admin)だけにこのコードを適用するようにすれば、PHP Warningの問題は出ないはずです。
ということで、if条件式を追加してみました。
// AdminPage Posting The Relative URL(image,link)
function admin_delete_host_from_attachment_url() {
if (is_admin() ) {
function delete_host_from_attachment_url( $url ) {
$regex = '/^http(s)?:\/\/[^\/\s]+(.*)$/';
if ( preg_match( $regex, $url, $m ) ) {
$url = $m[2];
}
return $url;
}
add_filter( 'wp_get_attachment_url', 'delete_host_from_attachment_url' );
add_filter( 'attachment_link', 'delete_host_from_attachment_url' );
}
}
add_filter( 'init', 'admin_delete_host_from_attachment_url');
コード改修後はPHP Warningが出なくなったので解決できたようです。
※2021/9/18追記
5年ぶりにコードを改良してみました。