后台上传图片成功,但前台显示 Magento 占位图,最容易误判为“缓存没清”。实际要同时满足三件事:商品媒体属性引用正确、原图文件可读、前台能生成或读取对应尺寸的缓存图。下面按文件路径走一遍,哪一步断开就修哪一步。
从商品角色图片值开始
在后台商品 Images and Videos 中确认 Base、Small、Thumbnail 至少分配了需要的图片,并切换到问题 Store View 检查是否被覆盖为 no_selection。使用 CLI 查询属性值时,先查商品 ID 与属性 ID,再读取对应 EAV 表;不要假设属性 ID 在所有环境相同。
SELECT entity_id, sku FROM catalog_product_entity WHERE sku='MISS-IMAGE-SKU';
SELECT attribute_id, attribute_code, backend_type
FROM eav_attribute
WHERE attribute_code IN ('image','small_image','thumbnail');
确认具体 backend_type 后,再在对应表按 entity_id、store_id 查询。若 Default 有值而 Store View 是 no_selection,前台会使用占位图。
把数据库路径映射到真实文件
图片值通常类似 /a/b/abc.jpg,对应文件应位于 pub/media/catalog/product/a/b/abc.jpg:
IMG='pub/media/catalog/product/a/b/abc.jpg'
stat "$IMG"
file "$IMG"
php -r '$i=getimagesize($argv[1]); var_export($i);' "$IMG"
文件不存在时检查导入路径、大小写和远程媒体同步;文件存在但 getimagesize 失败,可能是损坏或扩展名与真实格式不一致。
用 Web 用户测试读取和写入
sudo -u www-data test -r "$IMG" && echo readable
sudo -u www-data test -w pub/media/catalog/product/cache && echo cache-writable
find pub/media/catalog/product -maxdepth 3 -type d ! -perm -u+x | head
Web 用户名需按服务器实际修改。不要把整个 pub/media 设为 777;修正所有者和组权限,并确认父目录具有执行权限。
确认图片处理库与缓存生成
php -m | grep -Ei 'gd|imagick'
php -i | grep -Ei 'GD Support|JPEG Support|PNG Support|WebP Support'
tail -n 100 var/log/exception.log
find pub/media/catalog/product/cache -type f -name '*abc*' | head
如果只对 WebP、CMYK JPEG 或超大图片失败,先用一张普通 RGB JPEG 做对照。缓存目录为空且日志出现内存错误,需要调整图片尺寸或 PHP-FPM 内存,而不是无限提高 CLI 的 memory_limit。
远程媒体或 CDN 场景
对页面中的实际图片 URL 执行 HEAD 请求:
curl -sSI 'https://cdn.example.com/media/catalog/product/cache/.../abc.jpg'
源站 200、CDN 404 表示同步或缓存键问题;源站也 404 就回到文件和重写规则。检查 Nginx/Apache 是否把 /media/ 错误转给 PHP,或安全规则拒绝某些扩展名。
修复后只清理该商品相关缓存图或按维护计划执行图片缓存清理,再访问商品页触发生成。最后确认列表图、详情大图、缩略图、两个 Store View 和 CDN URL 都返回正确 MIME 类型;仅后台预览正常不算完成。

