This commit is contained in:
toom1996
2025-07-29 11:28:34 +08:00
parent 994b7366cd
commit a8d4390ff3
5 changed files with 176 additions and 371 deletions

View File

@ -0,0 +1,111 @@
<?php
namespace App\Helpers;
use function Hyperf\Support\env;
class ArticleHelper
{
public static function saveImagesFromArticle(string $html, string $savePath = '/www/wwwroot/uploads/', string $srcPrefix = '/uploads/')
{
// 创建保存图片的目录,如果没有的话
if (!file_exists($savePath)) {
mkdir($savePath, 0777, true);
}
// 正则匹配所有 img 标签的 src 属性
preg_match_all('/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $html, $matches);
// $matches[1] 包含所有 img 标签的图片 URL
$imageUrls = $matches[1];
// 遍历所有图片 URL 下载并保存
foreach ($imageUrls as $imageUrl) {
// 解析图片的文件名
$imageName = basename(parse_url($imageUrl, PHP_URL_PATH));
// 获取文件扩展名(如果没有扩展名,需要根据图片内容判断)
$extension = pathinfo($imageName, PATHINFO_EXTENSION);
if (empty($extension)) {
$imageContent = file_get_contents($imageUrl);
$finfo = finfo_open(FILEINFO_MIME_TYPE); // 获取 MIME 类型
$mimeType = finfo_buffer($finfo, $imageContent);
finfo_close($finfo);
// 根据 MIME 类型设置文件扩展名
if ($mimeType == 'image/jpeg') {
$extension = 'jpg';
} elseif ($mimeType == 'image/png') {
$extension = 'png';
} elseif ($mimeType == 'image/gif') {
$extension = 'gif';
} elseif ($mimeType == 'image/webp') { // 添加对 webp 的支持
$extension = 'webp';
} else {
continue; // 如果无法判断,跳过这张图片
}
// 用新的扩展名更新文件名
$imageName .= '.' . $extension;
}
// 本地保存路径
$localPath = $savePath . $imageName;
// 使用带 Cookie 的 cURL 下载图片
$result = self::downloadImageWithCookie($imageUrl, $localPath);
if ($result) {
// 更新 HTML 中 img 标签的 src 为本地路径
$html = str_replace($imageUrl, $srcPrefix . $imageName, $html);
}
}
return $html;
}
private static function downloadImageWithCookie($imageUrl, $savePath) {
// 2. 构造 HTTP 请求头 (Headers)
// 复制浏览器中的大部分 Header提高请求成功率
$headers = [
'accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
'accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'cache-control: no-cache',
'cookie: ASP.NET_SessionId=tcth0to5f4rctrr2ejcxoley; User_Behavior_Cache=JXO3LM97XAP5BK1EKNAENZ76L2ZOT9DY; _gid=GA1.2.1692255419.1753689656; _ga=GA1.1.574649996.1753689655; _ga_L98EL3NEEE=GS2.1.s1753694736$o2$g1$t1753695112$j60$l0$h0',
'pragma: no-cache',
'referer: https://news.vobao.com/',
'sec-ch-ua: "Not)A;Brand";v="8", "Chromium";v="138", "Microsoft Edge";v="138"',
'sec-ch-ua-mobile: ?0',
'sec-ch-ua-platform: "Windows"',
'sec-fetch-dest: image',
'sec-fetch-mode: no-cors',
'sec-fetch-site: same-site',
'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0',
];
// 3. 初始化 cURL
$ch = curl_init();
// 4. 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $imageUrl); // 设置请求URL
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 设置请求头
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将结果作为字符串返回,而不是直接输出
curl_setopt($ch, CURLOPT_HEADER, false); // 不返回响应头部分
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
curl_setopt($ch, CURLOPT_ENCODING, ''); // 处理所有受支持的编码如gzip
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用SSL证书验证 (在某些环境下需要)
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时时间为30秒
// 5. 执行 cURL 请求
$imageData = curl_exec($ch);
// 6. 检查是否有错误发生
if (curl_errno($ch)) {
echo 'cURL 请求错误: ' . curl_error($ch);
return false;
}
// 8. 关闭 cURL 句柄
curl_close($ch);
return file_put_contents($savePath, $imageData);
}
}