🐷

WordPressで画像のURLに最終更新日時をクエリパラメータとして追加する方法

2025/01/30に公開

WordPressでコンテンツを更新した際に、画像のキャッシュが原因で更新が反映されないことがあります。この問題を解決するため、画像URLに最終更新日時をクエリパラメータとして追加する方法を紹介します。

解決したい問題

  • WordPressで記事やページを更新しても、ブラウザキャッシュにより画像が更新されない
  • 特に、同じファイル名で画像を差し替えた場合に問題が発生
  • レスポンシブ対応のsrcset属性を使用している場合も同様の問題が発生

解決方法

functions.phpに以下のコードを追加することで、コンテンツ内の画像URLに最終更新日時をクエリパラメータとして自動的に付加できます。

/* content内の画像URLに、最終更新日時をクエリ文字として追加 */
function add_version_query_to_images($content) {
    global $post;
    $last_modified = $post->post_modified;
    $last_modified_date = new DateTime($last_modified);
    $version = $last_modified_date->format('YmdHis');

    $attributes = array('src', 'data-src0', 'data-src744', 'srcset');
    $site_url = parse_url(get_site_url(), PHP_URL_HOST);

    foreach ($attributes as $attribute) {
        if ($attribute === 'srcset') {
            // srcset属性の処理
            $pattern = '/(<source[^>]*srcset=["\'])([^"\']*)(["\'])/i';
            preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

            foreach ($matches as $match) {
                $srcset = $match[2];
                $new_srcset = $srcset;

                // カンマで区切られた各URLを処理
                $srcset_urls = explode(',', $srcset);
                foreach ($srcset_urls as $i => $srcset_url) {
                    // URLとサイズ指定を分離
                    $parts = preg_split('/\s+/', trim($srcset_url));
                    $url = $parts[0];

                    // 内部URLの場合のみ処理
                    if (strpos($url, $site_url) !== false || !preg_match('/^https?:\/\//', $url)) {
                        $separator = strpos($url, '?') !== false ? '&' : '?';
                        $new_url = $url . $separator . 'ver=' . $version;
                        // サイズ指定がある場合は保持
                        if (isset($parts[1])) {
                            $new_url .= ' ' . $parts[1];
                        }
                        $srcset_urls[$i] = $new_url;
                    }
                }
                
                // 更新したURLを結合
                $new_srcset = implode(', ', $srcset_urls);
                $content = str_replace($match[2], $new_srcset, $content);
            }
        } else {
            // 通常の画像属性の処理
            $pattern = '/(img[^\>]*' . $attribute . '=["\'])([^"\']*)(["\'])/';
            preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

            foreach ($matches as $match) {
                $url = $match[2];
                
                if (strpos($url, $site_url) !== false || !preg_match('/^https?:\/\//', $url)) {
                    $separator = strpos($url, '?') !== false ? '&' : '?';
                    $new_url = $url . $separator . 'ver=' . $version;
                    $content = str_replace($match[0], str_replace($url, $new_url, $match[0]), $content);
                }
            }
        }
    }

    return $content;
}
add_filter('the_content', 'add_version_query_to_images');

コードの解説

1. 最終更新日時の取得

global $post;
$last_modified = $post->post_modified;
$last_modified_date = new DateTime($last_modified);
$version = $last_modified_date->format('YmdHis');
  • global $postで現在の投稿オブジェクトを取得
  • post_modifiedから最終更新日時を取得
  • YmdHis形式(例:20250130175127)でバージョン文字列を生成

2. 処理対象の属性

$attributes = array('src', 'data-src0', 'data-src744', 'srcset');
  • 通常のsrc属性に加え、遅延読み込み用のdata-src属性も対象
  • レスポンシブ対応用のsrcset属性も処理

3. 内部URLの判定

$site_url = parse_url(get_site_url(), PHP_URL_HOST);
if (strpos($url, $site_url) !== false || !preg_match('/^https?:\/\//', $url))
  • サイトのドメインを含むURL、または
  • http://https://で始まらないURL(相対パス)の場合に処理

4. srcset属性の特別処理

$srcset_urls = explode(',', $srcset);
foreach ($srcset_urls as $i => $srcset_url) {
    $parts = preg_split('/\s+/', trim($srcset_url));
    $url = $parts[0];
    // ...
}
  • カンマで区切られた複数のURLに対応
  • URLとサイズ指定(例:2x300w)を適切に分離して処理

使用例と結果

通常の画像

<!-- 変更前 -->
<img src="example.jpg" alt="サンプル">

<!-- 変更後 -->
<img src="example.jpg?ver=20250130175127" alt="サンプル">

レスポンシブ画像(srcset使用)

<!-- 変更前 -->
<picture>
  <source srcset="example-sp.jpg" media="(max-width: 743.9px)">
  <img src="example.jpg" alt="">
</picture>

<!-- 変更後 -->
<picture>
  <source srcset="example-sp.jpg?ver=20250130175127" media="(max-width: 743.9px)">
  <img src="example.jpg?ver=20250130175127" alt="">
</picture>

まとめ

  • WordPressの画像キャッシュ問題を、URLにバージョンパラメータを追加することで解決
  • 内部の画像URLのみを対象とし、外部画像は影響を受けない
  • レスポンシブ対応のsrcset属性にも対応
  • 記事の更新日時を自動的に利用するため、手動での管理が不要

この方法により、コンテンツ更新時に確実に新しい画像が表示されるようになり、特にWordPressのテーマ開発やコンテンツ管理の効率が向上します。

Discussion