🐷
WordPressで画像のURLに最終更新日時をクエリパラメータとして追加する方法
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とサイズ指定(例:
2x
や300w
)を適切に分離して処理
使用例と結果
通常の画像
<!-- 変更前 -->
<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