上传问题(权限被拒绝)

Posted

技术标签:

【中文标题】上传问题(权限被拒绝)【英文标题】:Upload problem (permission denied) 【发布时间】:2011-03-09 16:12:29 【问题描述】:

我目前正在使用 vork 框架中的文件组件来上传文件,并且一直收到此错误:

警告:move_uploaded_file(/uploads) [function.move-uploaded-file]:无法打开流:/var/www/rto-vork/mvc/components/file 第 105 行的权限被拒绝

警告:move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/php3WC6QP' to '/uploads' in /var/www/rto-vork/mvc/components/file on line 105 string(32) "无法移动上传的文件" 成功

我相信组件本身没问题,上传目录已经被chmod为777

这是上传的代码 文件 id 被正确传入

public function uploadFile($id, $destination, $imagesOnly = false) 

    $return = false;

    if (substr($_FILES[$id]['name'], 0, 1) == '.') 

        $return = 'File names must not begin with a dot';

     else 

        $isInvalidUpload = $this->isInvalidUpload($id, $imagesOnly);

        if ($isInvalidUpload) 

            $return = $isInvalidUpload;

         else 

            if (move_uploaded_file($_FILES[$id]['tmp_name'], $destination)) 

                if (is_dir($destination)) 

                    if ($destination[-1] != '/' && $destination[-1] != '\\') 

                        $destination .= '/';

                    

                    $destination .= $_FILES[$id]['tmp_name'];

                

                chmod($destination, 0777);

             else 

                $return = 'Could not move the uploaded file';

            

        

    

    return $return;


【问题讨论】:

终于通过结合 Mar B 和 Col. Shrapnel 提供的两个修复程序使其正常工作。谢谢大家:) 【参考方案1】:

你的代码有缺陷:

public function uploadFile($id, $destination, $imagesOnly = false) 
   ...
   if (move_uploaded_file(...)) 
       if (is_dir(...)) 
           ...
       
     else 
       $return = 'Could not move the uploaded file';
    

你用uploadFile('somename', '/uploads')调用方法,所以代码首先尝试将上传的文件直接移动到/uploads,但这是一个目录。 move_uploaded_file() 不像常规的文件系统“移动”命令,源和目标都必须是文件名。因此,您的初始移动尝试失败,它返回 false,并且事情直接跳转到“无法移动文件”返回调用。它甚至从不尝试将 $destination 作为目录处理

你应该重组方法如下:

public function uploadFile(...) 
    ...
    // if $destination is a directory, handle that fact
    if (is_dir($destination)) 
       $destination .= '/' . $new_file_name;
    
    // THEN try to move the file
    if (move_uploaded_file($source, $destination)) 
       return('worked');
     else 
       return('failed');
    

另外,请注意,虽然不太可能,但 PHP 分配的临时文件名 NOT 保证随着时间的推移是唯一的。完全有可能在某个时刻再次生成相同的随机名称,并且您将覆盖较旧的上传。您应该使用保证唯一的文件名,例如来自数据库或其他非重复数据源的主键“id”字段。

【讨论】:

【参考方案2】:

在我看来,您正在尝试移动目录本身,或者您正在尝试写入目录而不是文件。

Warning: move_uploaded_file**(/uploads)** [function.move-uploaded-file]: failed to open stream: Permission denied in /var/www/rto-vork/mvc/components/file on line 105

验证您正在使用生成的临时文件名,并且您正在指定一个文件名来保存文件。

【讨论】:

【参考方案3】:

错误信息非常清楚:您无法写入目录/uploads。 难怪 - 在 unix 系统上没有人让你写入系统根目录:) 那是您的问题 - 您弄乱了 Web 根目录和文件系统根目录。 一般来说,如果其他代码没问题,这段代码应该会有所帮助:

$destination = $_SERVER['DOCUMENT_ROOT'].$destination;

但我怀疑其余代码是否正常 比如说,$destination .= $_FILES[$id]['tmp_name']; 是非常无意义的代码。 我认为您最好为自己找到另一个组件或编写自己的组件

【讨论】:

以上是关于上传问题(权限被拒绝)的主要内容,如果未能解决你的问题,请参考以下文章

文件上传权限被拒绝 Godaddy 共享主机

上传文件时Django的权限被拒绝错误

Apache上传文件/tmp权限被拒绝

无法打开流:权限被拒绝[上传照片]

文件传输权限被拒绝

Apache spark:上传到作业暂存目录的文件的权限被拒绝