
本文介绍如何通过 cURL 命令行自动上传文件至 PHP 服务器,并让服务端从 URL 参数(如 ?fname=test.txt)安全获取目标文件名,避免硬编码或手动表单提交,适用于 Linux 环境下的自动化部署场景。
本文介绍如何通过 curl 命令行自动上传文件至 php 服务器,并让服务端从 url 参数(如 `?fname=test.txt`)安全获取目标文件名,避免硬编码或手动表单提交,适用于 linux 环境下的自动化部署场景。
在自动化运维中,常需将本地生成的固定名称文件(如 test.txt)定时上传至 PHP 服务端。虽然原始代码已支持通过 HTML 表单上传,但无法直接响应带 ?fname=test.txt 的 URL 请求——因为 $_FILES['fname'] 中的 'fname' 是表单字段名,而非 URL 参数名。关键在于:URL 中的 fname 参数与文件上传字段名是两个独立概念,不能混用;服务端需显式读取 $_GET['fname'] 并结合 $_FILES 数据完成安全落盘。
✅ 正确的实现思路
- 客户端(cURL):使用 -F 参数模拟 multipart 表单提交,无需在 URL 中传递文件名(URL 参数易被篡改,不推荐用于关键逻辑);
- 服务端(PHP):优先从 $_GET['fname'] 获取期望文件名(若存在),再校验其合法性,最后与上传的临时文件绑定保存。
⚠️ 注意:原始答案中“curl -F "uploadedfile=@..." + ?fname=”的组合虽可行,但存在安全隐患——若未校验 $_GET['fname'],攻击者可构造恶意路径(如 ../etc/passwd)。必须严格过滤。
CurlShip Directory Submission下载向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
✅ 推荐的 PHP 服务端代码(增强安全性)
<?php
// 允许从 URL 获取期望文件名(可选),默认 fallback 到上传原始名
$expectedName = isset($_GET['fname']) ? trim($_GET['fname']) : null;
$errors = [];
// 检查是否收到文件
if (!isset($_FILES['uploadedfile']) || $_FILES['uploadedfile']['error'] !== UPLOAD_ERR_OK) {
$errors[] = 'No file uploaded or upload error.';
}
if (empty($errors)) {
$tmpFile = $_FILES['uploadedfile']['tmp_name'];
$originalName = $_FILES['uploadedfile']['name'];
// 决定最终文件名:优先用 URL 参数(需严格校验),否则用原始名
$finalName = $expectedName ?: $originalName;
// ✅ 强制白名单校验:仅允许字母、数字、下划线、短横线和点号,且扩展名限定为 .txt
if (!preg_match('/^[a-zA-Z0-9_.\-]+\.txt$/i', $finalName)) {
$errors[] = 'Invalid filename: must be alphanumeric with .txt extension.';
}
// ✅ 防止路径遍历:移除所有 ../ 和空字节
$finalName = basename($finalName);
$uploadDir = 'download/';
$targetPath = $uploadDir . $finalName;
// 确保目录存在且可写
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
if (empty($errors) && move_uploaded_file($tmpFile, $targetPath)) {
echo "Success: {$finalName} uploaded.";
} else {
$errors[] = 'Failed to save file.';
}
}
if (!empty($errors)) {
http_response_code(400);
echo "Error: " . implode('; ', $errors);
}
?>✅ 安全可靠的 cURL 命令示例
# 方式1:仅上传文件(服务端用原始名) curl -F "uploadedfile=@/path/to/test.txt" http://myserver.com/upload.php # 方式2:上传文件 + 指定目标文件名(服务端读取 ?fname=) curl -F "uploadedfile=@/path/to/test.txt" "http://myserver.com/upload.php?fname=test.txt" # 方式3:带调试输出,便于排查 curl -v -F "uploadedfile=@/path/to/test.txt" "http://myserver.com/upload.php?fname=test.txt"
? 关键要点总结
- $_FILES 数组中的键(如 'uploadedfile')对应 cURL 的 -F 字段名,与 URL 参数无关;
- $_GET['fname'] 是独立的查询参数,需主动读取并严格校验(正则 + basename());
- 永远不要直接拼接 $_GET 或 $_FILES['name'] 构造文件路径,防止路径遍历攻击;
- 生产环境建议增加 MIME 类型校验($_FILES['uploadedfile']['type'])、文件大小限制(upload_max_filesize)、以及鉴权机制(如 token 校验)。
通过以上改造,即可实现完全自动化、安全可控的文件上传流程,无需人工干预,也规避了常见 Web 安全风险。



















