本文目录导读:

在 PHP 中实现响应式图片,通常涉及根据设备条件(如屏幕宽度、像素密度)动态生成或选择不同尺寸的图片,然后通过 HTML 的 srcset 和 sizes 属性让浏览器自动选择最佳图片。
以下是几种常见的实现方式:
基础原理:HTML 的 srcset + sizes
在进入 PHP 代码前,先理解最终输出的 HTML 结构:
<img src="small.jpg" srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w" sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px" alt="Responsive Image" />
- srcset:列出图片文件及其对应的实际宽度(用
w单位,如400w)或像素密度(1x,2x)。 - sizes:告诉浏览器在不同视口宽度下,图片将占据多少 CSS 像素宽度。
- 浏览器根据当前视口宽度、设备像素比(DPR)和
sizes条件,选择最合适的图片源。
PHP 生成响应式图片 HTML
假设你有一张图片的三个尺寸版本:photo-400.jpg、photo-800.jpg、photo-1200.jpg。
示例函数:
function responsiveImage($baseUrl, $alt = '', $sizes = []) {
// 默认尺寸配置:宽度 => 文件后缀或路径
$defaultSizes = [
'400w' => $baseUrl . '-400.jpg',
'800w' => $baseUrl . '-800.jpg',
'1200w' => $baseUrl . '-1200.jpg'
];
// 允许外部传入自定义尺寸映射
$images = $sizes ?: $defaultSizes;
// 构建 srcset 字符串
$srcsetParts = [];
$fallback = '';
foreach ($images as $width => $src) {
$srcsetParts[] = htmlspecialchars($src) . ' ' . $width;
// 取最后一个作为 fallback(或取中间尺寸)
$fallback = $src;
}
$srcset = implode(', ', $srcsetParts);
// 构建 sizes 属性(根据需求调整)
$sizesAttr = '(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px';
return sprintf(
'<img src="%s" srcset="%s" sizes="%s" alt="%s" loading="lazy" />',
htmlspecialchars($fallback),
$srcset,
$sizesAttr,
htmlspecialchars($alt)
);
}
// 使用
echo responsiveImage('/images/photo', '一张风景图');
输出:
<img src="/images/photo-1200.jpg" srcset="/images/photo-400.jpg 400w, /images/photo-800.jpg 800w, /images/photo-1200.jpg 1200w" sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px" alt="一张风景图" loading="lazy" />
高级:结合数据库或配置动态生成
如果图片信息存储在数据库或配置文件中:
function imageFromDatabase($imageId) {
// 假设从数据库获取了图片各尺寸路径
$imageData = [
'src_small' => '/uploads/' . $imageId . '-400.jpg',
'src_medium' => '/uploads/' . $imageId . '-800.jpg',
'src_large' => '/uploads/' . $imageId . '-1200.jpg',
'alt' => '产品图片'
];
return responsiveImage(
str_replace('-400', '', $imageData['src_small']), // 基础路径
$imageData['alt'],
[
'400w' => $imageData['src_small'],
'800w' => $imageData['src_medium'],
'1200w' => $imageData['src_large']
]
);
}
动态生成不同尺寸图片(服务端方案)
如果服务器上没有预先创建好所有尺寸,可以用 PHP + ImageMagick/GD 按需生成并缓存。
流程:
- 创建图片处理类,接收
src和width。 - 检查缓存目录是否存在该宽度的图片,存在则直接返回。
- 不存在则用
GD或Imagick缩放原图并保存到缓存目录。 - 在
srcset中引用这些动态生成的缓存图片。
简化示例(使用 GD):
function generateResponsiveSrc($originalPath, $width, $cacheDir = '/cache') {
$filename = pathinfo($originalPath, PATHINFO_FILENAME);
$ext = pathinfo($originalPath, PATHINFO_EXTENSION);
$cachePath = $cacheDir . "/{$filename}-{$width}.{$ext}";
if (file_exists($cachePath)) {
return $cachePath;
}
// 获取原图尺寸
list($origW, $origH) = getimagesize($originalPath);
$height = intval($origH * ($width / $origW));
// 创建缩略图(简化示例,需处理透明度等)
$srcImg = imagecreatefromjpeg($originalPath);
$dstImg = imagecreatetruecolor($width, $height);
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $width, $height, $origW, $origH);
// 保存缓存
imagejpeg($dstImg, $cachePath, 80);
imagedestroy($srcImg);
imagedestroy($dstImg);
return $cachePath;
}
// 使用
$src400 = generateResponsiveSrc('photo.jpg', 400);
$src800 = generateResponsiveSrc('photo.jpg', 800);
// 然后生成 srcset HTML...
⚠️ 注意:动态生成图片会增加首次请求的延迟,建议用后台任务提前生成所有尺寸。
使用 CDN 或第三方图床(推荐)
对于生产环境,更常见的做法是使用云存储 + 图片处理服务(如阿里云 OSS 图片处理、腾讯云 CI、Cloudinary、Imgix):
- 你只需上传一张原图。
- 通过 URL 参数(如
?x-oss-process=image/resize,w_400)动态获取不同尺寸。 - PHP 只负责拼接 URL。
示例:
function cloudinaryImg($publicId, $alt) {
$base = 'https://res.cloudinary.com/demo/image/upload/';
$srcset = [
$base . 'w_400/' . $publicId . ' 400w',
$base . 'w_800/' . $publicId . ' 800w',
$base . 'w_1200/' . $publicId . ' 1200w'
];
return sprintf(
'<img src="%s" srcset="%s" sizes="..." alt="%s" />',
$base . 'w_800/' . $publicId,
implode(', ', $srcset),
htmlspecialchars($alt)
);
}
总结对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| 预先生成不同尺寸图片 | 加载快,简单直接 | 维护多份文件 |
| PHP 动态生成+缓存 | 节省存储空间 | CPU/IO 消耗,首次加载慢 |
| 使用 CDN/云服务 | 省心,强大,自动优化 | 依赖外部服务,可能产生费用 |
推荐方案:
- 小型项目:预先手动生成 2~3 个尺寸,PHP 只负责输出正确的 HTML。
- 中大型项目:使用云存储 + 图片处理 API,PHP 动态构建
srcsetURL。