无法使用 PHP 上传文件?

Posted

技术标签:

【中文标题】无法使用 PHP 上传文件?【英文标题】:Cant upload a file using PHP? 【发布时间】:2014-07-10 23:41:36 【问题描述】:

谁能看看我的代码?人们可以单击上传按钮上传一些文件,代码应该将其移动到新位置并保存。我通过上传图像文件对其进行了测试,但在我指定的文件夹中找不到该文件。我确定目录是正确的,因为我使用的目录是文件夹,它可以通向我希望它所在的文件夹。因为下面的目录有我的名字,所以我用“1”代替。提前谢谢!

我根据答案更改了代码,但它仍然给我返回错误: 警告:move_uploaded_file(/Users/angeloliiao/Documents/Screen.tiff):无法打开流:第 16 行 /usr/local/zend/apache2/htdocs/JuvoliciousProductViewer/5.php 中的权限被拒绝

警告:move_uploaded_file():无法将 '/usr/local/zend/tmp/phpdfCRD3' 移动到 /usr/local/zend/apache2/htdocs/JuvoliciousProductViewer 中的 '/Users/angelolio/Documents/Screen.tiff' /5.php 第 16 行

我尝试在终端上使用以下命令更改文件夹的权限:sudo chown -R 0755 /Users/angeloliiao/Documents.它跑了。

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
</head>
<body>
   <form enctype="multipart/form-data" method="POST">
       <input type="file" name="file" />
       <input type="submit" name="submit" value="upload" />
   </form>
   <?php
   if ($_FILES) 
       $name = $_FILES['file']['name'];
       $temp = $_FILES['file']['tmp_name'];
       $dir = "/Users/angeloliao/Documents/";
   if (move_uploaded_file($temp,$dir.$name)) 
       echo "File is valid, and was successfully uploaded.\n";
     
      else 
         echo "Possible file upload attack!\n";
   
   ?>
</html>

【问题讨论】:

您没有进行任何错误检查。您的代码应该检查错误并报告它们。这样,您就有机会在此处发布之前诊断出问题。查看 PHP 部分 Handling File Uploads - 特别是关于错误的部分 - 并检查 move_uploaded_file() 的返回值。 别忘了Documents/ 后面的斜杠,还有很多东西要让它安全或避免错误 我还建议将其发布到单独的页面,然后重定向回以清除提交的数据,没有人喜欢多次上传,但这有点解释工作。 这真的很危险。您永远不应该使用提供的文件名称来存储在您的服务器上。相反,您应该使用某种随机数(可能是散列的)。根据您的 php.ini 设置(和文件权限),想象如果有人上传了一个名为“../../../usr/local/bin/php”的文件。然后他们可以用执行恶意代码的东西替换你的 php 解释器。 + 点划线(目录遍历),听@PhpMyCoder 【参考方案1】:
<!DOCTYPE html>
<html>
   <head>
    <meta charset="UTF-8">
</head>
<body>
    <form enctype="multipart/form-data" method="POST">
        <input type="file" name="file" />
        <input type="submit" name="submit" value="upload" />
    </form>
    <?php
        $name = $_FILES['file']['name'];
        $temp = $_FILES['file']['tmp_name'];
        $dir = "/Users/1/Documents/";
        move_uploaded_file($temp,$dir.$name);
    ?>
</body>

应该是 _ 而不是 + 并且目录应该是带有斜杠的“Documents/”

【讨论】:

【参考方案2】:

根据the PHP documentation,临时名称位于$_FILES['file']['tmp_name'] 而不是$_FILES['file']['tmp+name']。另外,做一个var_dump()$dir.$name。如果您上传的文件是“image.jpg”,那么它将是/Users/1/Documentsimage.jpg。注意缺少的斜线。

更改此设置将使您的代码正常工作,但它仍然不能处理所有可能的错误,也不安全!上传可能会失败。如果是这样,您将在 $_FILES['file']['error'] 中找到错误代码 (the docs has a reference that lists them all)。您应该在移动临时文件之前检查上传是否成功(如果表单已经提交,您也应该只执行移动命令)。

此外,使用上传者提供的名称也不安全。考虑$_FILE['file']['name'] 是否为../../../usr/local/bin/php。然后上传者可以用恶意的可执行文件替换你的 PHP 解释器。这是危险的!永远不要相信用户输入!在这种情况下,最好的做法是随机生成一个不依赖于原始文件名的文件名(即不要只散列提供的文件名,因为如果两个人上传同名文件怎么办?)。

if($_POST['submit'] === 'upload')   // only process form if it has been submitted

    if($_FILES['file']['error'] !== UPLOAD_ERR_OK) 

        exit('There was an error uploading your file');
    

    $uploads_dir = '/Users/1/Documents/';
    $upload_name = sha1(mt_rand().microtime(true)); // you should actually pick
                                                    // something more unique
                                                    // (collisions are possible)

    move_uploaded_file($FILES['file']['tmp_name'], $uploads_dir . $upload_name);

【讨论】:

◎PhpMyCoder 请参考我编辑的代码。它仍然无法正常工作,错误通知(权限被拒绝)。我试图更改文件夹权限,但它不起作用 @Angelo 再次查看我的代码并重新阅读我的答案。你还没有完全实现它。您更新的版本仍然存在漏洞。您需要为 apache 用户 chown 文件(通常是 www-data,但它取决于系统)。您可以通过访问 httpd.conf 进行检查。您也可以运行 ps aux | grep '(httpd|apache)'(假设您正在运行 apache)并检查用户。 感谢您的回答。我有另一个相关的问题。我现在正在使用 Zend 服务器,根据 httpd.conf 文件,apache 用户是“守护进程”。我现在正在自己的电脑上开发网站。我应该将上传的文件设置到哪个目录?从更安全和更好的实践角度来看。

以上是关于无法使用 PHP 上传文件?的主要内容,如果未能解决你的问题,请参考以下文章

无法上传文件,php和angularjs

无法使用 gd 库 php 上传图像

解决nginx和php使用ckfinder无法上传大文件的问题

解决nginx和php使用ckfinder无法上传大文件的问题

无法将 pdf 文件上传到 mysql 数据库并使用 PHP 检索它?

IIS+php服务器无法上传图片(500 错误)