Files
MoYuBan/api/save_picture.php
2025-11-18 14:18:28 +08:00

67 lines
2.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// 保存图片到本地不做清理保存目录按照远程URL的路径结构组织
header('Content-Type: application/json; charset=utf-8');
function respond($ok, $message = '', $path = '') {
echo json_encode(['success' => $ok, 'message' => $message, 'path' => $path], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
// 读取JSON输入
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
$url = $data['url'] ?? '';
if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
respond(false, 'URL无效');
}
// 只允许 http/https
$scheme = parse_url($url, PHP_URL_SCHEME);
if (!in_array(strtolower($scheme), ['http','https'])) {
respond(false, '仅支持http/https图片地址');
}
$root = __DIR__ . '/../pictures';
if (!is_dir($root)) { @mkdir($root, 0777, true); }
// 解析远程路径:按照域名后的路径作为保存文件夹结构
$path = parse_url($url, PHP_URL_PATH) ?: '';
if (!$path) { respond(false, '无法解析远程路径'); }
// 将路径拆分并进行安全过滤,避免非法字符与上级目录
$segments = array_values(array_filter(explode('/', $path), function($s){ return $s !== ''; }));
if (!count($segments)) { respond(false, '路径为空'); }
$filename = array_pop($segments);
$safeSegs = array_map(function($seg){
$seg = preg_replace('/[^A-Za-z0-9._-]+/u', '_', $seg);
return trim($seg, '._-') ?: 'unk';
}, $segments);
$safeName = preg_replace('/[^A-Za-z0-9._-]+/u', '_', $filename);
if (!$safeName) { $safeName = 'image_' . time() . '.jpg'; }
$targetDir = $root;
foreach ($safeSegs as $seg) { $targetDir .= DIRECTORY_SEPARATOR . $seg; if (!is_dir($targetDir)) { @mkdir($targetDir, 0777, true); } }
$targetPath = $targetDir . DIRECTORY_SEPARATOR . $safeName;
// 如果文件已存在则跳过下载
if (file_exists($targetPath)) {
respond(true, '文件已存在,跳过下载', str_replace($_SERVER['DOCUMENT_ROOT'], '', $targetPath));
}
// 下载保存
try {
$read = @fopen($url, 'rb');
if (!$read) { respond(false, '无法读取远程图片'); }
$write = @fopen($targetPath, 'wb');
if (!$write) { respond(false, '无法写入文件'); }
stream_copy_to_stream($read, $write);
fclose($read);
fclose($write);
} catch (Throwable $e) {
respond(false, '保存失败: ' . $e->getMessage());
}
respond(true, '保存成功', str_replace($_SERVER['DOCUMENT_ROOT'], '', $targetPath));