WordPressに挿入する画像をルート相対パス化する(いきなり応用編)

記事に挿入する画像は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年ぶりにコードを改良してみました。

WordPress リンクの相対パス化 Ver2
HTMLソース内のリンク相対パス化をより強化してみました。
スポンサーリンク