php用file_get_contents下载网络图片常因缺少user-agent、referer或超时导致403/空内容,需用stream_context_create配置请求头和timeout;下载前应get_headers校验状态码;文件名须用pathinfo+uniqid避免冲突。

PHP 用 file_get_contents 下载网络图片会失败?
直接用 file_get_contents 请求 HTTP 图片链接,常遇到 403、空内容或超时——多数图床(如微博、知乎、微信)会校验 User-Agent 或 Referer,甚至反爬封锁 IP。不是 PHP 不行,是默认请求头太“干净”。
- 必须手动设置
stream_context_create,带上常见浏览器User-Agent和Referer - 加
timeout参数防卡死,建议设为10秒以内 - 下载前先用
get_headers($url, 1)检查状态码,跳过404或403 - 文件名别直接用 URL 中的原始名,用
pathinfo($url, PATHINFO_EXTENSION)提取后缀,再拼上uniqid()避免冲突
PHP 生成 PPTX 要用 PHPPresentation?别踩这个坑
PHPPresentation 是个半废弃项目,不支持图片缩放锚点控制、幻灯片尺寸自定义,且插入图片后常错位或丢失。真正能稳住批量插入的只有 PhpSpreadsheet 的姊妹库:PHPOffice/PowerPoint(注意:不是旧版 PHPPresentation)。
- 装最新版:
composer require phpoffice/php-presentation - 它底层基于 OPC(Office Open XML),所有图片必须先写入临时路径,再用
$slide->createDrawingShape()加载本地路径,不能直接传 URL 或二进制流 - 插入位置单位是 EMU(English Metric Units),
9525≈ 1 cm,别用像素硬算 - 记得调用
$shape->setResizeProportional(true),否则拉伸变形
图片尺寸和幻灯片比例不匹配,PPT 里全糊了怎么办
PPT 默认幻灯片尺寸是 16:9(如 10"×5.625"),而网络图片千奇百怪。直接按原图宽高塞进去,要么留大片白边,要么裁剪失真。
- 用
getimagesize()读取下载后的图片,拿到原始$width和$height - 按幻灯片可用区域(比如宽度
9144000EMU)计算等比缩放值:min(9144000 / $width, 5143500 / $height) - 设置
$shape->setWidth()和$shape->setHeight()为缩放后值,再用setOffsetX/setOffsetY居中(偏移 = (可用宽 - 实际宽) / 2) - 跳过 GIF 动图——
PHPOffice/PowerPoint只支持 PNG/JPG,GIF 会报Invalid image type
批量跑几十张图,内存爆了或生成文件打不开
每张图都 file_get_contents + 写磁盘 + 创建 DrawingShape,不释放资源,PHP 进程内存会线性上涨;更糟的是,没显式调用 $objWriter->save() 前,对象还在内存里占着。
立即学习“PHP免费学习笔记(深入)”;
- 每次循环末尾加
unset($shape); imagedestroy($img_resource);(如果用了 GD 处理) - 下载完立刻
move_uploaded_file或rename到目标目录,别留一堆临时文件在/tmp - 生成完一个 PPT 就
gc_collect_cycles()强制回收,尤其 PHP - 最终保存用
IOFactory::createWriter($presentation, 'PowerPoint2007'),别用'ODPresentation'等冷门格式,兼容性差
最麻烦的其实是图床防盗链策略变来变去,今天好使的 User-Agent,下周可能就 403。得把下载逻辑单独抽成可重试函数,带 fallback URL 或本地备用图路径。











