0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

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のテーマ開発やコンテンツ管理の効率が向上します。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?