如何修改PHP代码实现URL传文件名的curl自动文件上传
解决方案
你之前的思路存在一个认知偏差:文件上传不需要通过URL参数传递文件名,HTTP文件上传的标准格式是multipart/form-data的POST请求,文件本身、文件名都会包含在请求体中,你原有的PHP代码已经可以处理手动表单上传,只要用curl构造相同格式的请求就能实现自动上传,几乎不需要修改代码。
1. 直接可用的curl上传命令
在Unix主机执行以下命令即可完成自动上传,和网页手动上传的请求格式完全一致:
# 把@后面的路径替换成你本地test.txt的实际路径,如果文件在当前执行目录直接写@test.txt即可 curl -F "fname=@/your/local/path/test.txt" http://myserver.com/upload.php
参数说明:
-F用于指定提交multipart/form-data格式的表单数据,和网页表单的提交格式完全匹配fname=@本地文件路径中的fname对应你PHP代码里$_FILES['fname']的字段名,@符号是curl识别本地文件的标记,执行时curl会自动读取本地文件内容、带上文件名test.txt发起请求,PHP端的$_FILES['fname']['name']会自动获取到test.txt,和手动选文件上传的效果完全相同- 你可以把这条命令写到crontab或者shell脚本里,就能实现定时/自动上传,因为文件名固定,每次执行都会覆盖服务器端download目录下的旧test.txt,正好匹配你“文件内容动态变动、文件名固定”的需求
2. PHP代码优化(补全校验、修复安全隐患)
你原来的代码定义了允许txt后缀但没有实际写校验逻辑,也缺少基础的安全判断,优化后手动上传、curl自动上传都能正常运行:
<?php if(isset($_FILES['fname'])){ $errors = array(); $file_name = $_FILES['fname']['name']; $file_tmp = $_FILES['fname']['tmp_name']; $file_size = $_FILES['fname']['size']; $file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); $allowed_ext = array("txt"); // 补全缺失的格式校验 if(!in_array($file_ext, $allowed_ext)){ $errors[] = "仅支持上传txt格式文件"; } // 限制文件大小,可按需调整数值,这里设置为最大5MB if($file_size > 5 * 1024 * 1024){ $errors[] = "文件大小不能超过5MB"; } if($file_size == 0){ $errors[] = "上传文件内容为空"; } if(empty($errors)){ // 自动创建存储目录,避免目录不存在导致移动文件失败 if(!is_dir("download/")){ mkdir("download/", 0755, true); } move_uploaded_file($file_tmp, "download/".$file_name); echo "Success"; }else{ print_r($errors); } } ?> <html> <body> <form action="" method="post" enctype="multipart/form-data"> <input type="file" name="fname" /> <input type="submit"/> </form> </body> </html>
3. 可选:支持URL参数自定义保存文件名
如果你确实需要通过URL参数指定服务器端保存的文件名,可以在代码里增加对应逻辑,必须加安全过滤避免路径遍历漏洞:
// 在获取$file_name的位置增加以下逻辑 if(isset($_GET['fname']) && !empty($_GET['fname'])){ // 用basename()过滤掉路径字符,防止传入../../xxx这类参数恶意覆盖服务器其他文件 $file_name = basename($_GET['fname']); $file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); }
对应的curl命令调整为:
curl -F "fname=@/your/local/path/test.txt" "http://myserver.com/upload.php?fname=test.txt"
安全提示:绝对不要直接使用未经过滤的
$_GET/$_POST参数拼接文件存储路径,否则会产生严重的文件覆盖、任意文件写入漏洞。
内容的提问来源于stack exchange,提问作者joeejo
相关产品推荐
相关产品推荐

