$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));