You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 17:21:09