PHP文件上传错误

时间:2012-04-10 02:11:06

标签: php model-view-controller file-upload

我正在使用模型 - 视图 - 控制器结构开发网站。在我的html中,我有一个允许用户浏览和选择文件的表单,然后通过单击按钮然后调用控制器代码来提交文件:

if(upload_quotes($_FILES['userfile'])){
    $msg = "Successful file upload";  
    $directory_list = array();

    // get contents of directory here
    // $directory_list = get_directory_contents($directory_list);

    include '../view/processFileUpload.php';
}else{
    $msg = "Unknown error occurred.  Error: ".print_r($_FILES);
    include '../view/errorPage.php';
}

第一行:upload_quotes()是位于模型代码中的函数。如果成功上传,则该函数返回true,如果不成功则返回false。我已经注释掉了获取目录列表的函数调用,因为它也有错误。 2个模型代码片段:

function upload_quotes($_FILES){
    $uploadfile = '../../../TestSiteDataFiles/Quotes/'.$_FILES['userfile']['name'];
    if(move_uploaded_file($_FILES['tmp_name'], $uploadfile)){
        return true;
    }else{
        return false;
    }
}

function get_directory_contents($directory_list){
    $current_dir = '../../../TestSiteDataFiles/Quotes/';
    $dir = opendir($current_dir);

    //reads and outputs the directory
    while(false !== ($file = readdir($dir)))
    //strip out the two entries of . and ..
    if($file != "." && $file !=".."){
        array_push($directory_list, $file);
    }
    closedir($dir);
    return $directory_list;
}

processFileUpload.php和errorPage.php文件相应地输出$ msg变量,但它永远不会输出成功。我花了几个小时研究我做错了什么,我对PHP的有限知识没有任何帮助。视图页面输出“发生未知错误。错误:1。浏览器上弹出的错误是:

  

警告:move_uploaded_file()[function.move-uploaded-file]:copy()函数的第二个参数不能是第17行的C:\ xampp \ htdocs \ Test Site \ model \ model.php中的目录< / p>      

警告:move_uploaded_file()[function.move-uploaded-file]:无法将'C:\ xampp \ tmp \ php487A.tmp'移动到'../../../TestSiteDataFiles/Images/'中第17行的C:\ xampp \ htdocs \ Test Site \ model \ model.php   数组([名称] =&gt;管理会计Davers Connect.txt [type] =&gt; text / plain [tmp_name] =&gt; C:\ xampp \ tmp \ php487A.tmp [error] =&gt; 0 [size] = &gt; 55)

在我看来,模型代码(upload_quotes())是错误的来源,因为它每次都返回false。 get_directory_contents()函数永远不会执行,但它也不会输出正确的结果。

我感谢所有建议并感谢您的投入。

2 个答案:

答案 0 :(得分:3)

通过将$_FILES作为参数传递给您的函数,您在实际的$_FILES超全局中混淆了文件信息的来源。由于您在函数中访问$_FILES['userfile']['name'],但是将$_FILES['userfile']传递给函数,因此未定义名称密钥,并且您收到目录错误。

使用用户输入文件名在文件系统上存储文件是非常危险的。相反,最好创建一个唯一的文件名。来自$_FILES[]['name']的原始输入文件名可用于存储在数据库中,并与磁盘上的文件关联,作为要显示的元数据,但不应将其用于存储在磁盘上。

// Use a different variable name. I've replaced it with $fileinfo
function upload_quotes($fileinfo){

    // Don't use the original filename to store it. Create one instead.
    $fname = uniqid();
    $finfo = pathinfo($fileinfo['name']);
    // Append the user's file extension to a random filename
    $fname .= "." . $finfo['extension'];

    $uploadfile = '../../../TestSiteDataFiles/Quotes/'.$fname;

    // Don't attempt to move the file unless its error container is empty
    if(empty($fileinfo['error']) && move_uploaded_file($fileinfo['tmp_name'], $uploadfile)){
        return true;
    }else{
        return false;
    }
}

更新

get_directory_contents()函数失败,因为数组$directory_list的定义超出范围。在调用函数之前,无需将其定义为数组。反而在里面做了:

function get_directory_contents($directory_list){
    $current_dir = '../../../TestSiteDataFiles/Quotes/';
    $dir = opendir($current_dir);

    // Define $directory_list as an array IN HERE
    $directory_list = array();

    //reads and outputs the directory
    while(false !== ($file = readdir($dir)))
    //strip out the two entries of . and ..
    if($file != "." && $file !=".."){
        array_push($directory_list, $file);
    }
    closedir($dir);
    return $directory_list;
}

这只是一个问题,因为您使用了array_push()而不是[]数组附加符号。 array_push()必须将现有数组作为其第一个参数,并且它本身不会创建一个。

// Would have worked since the array would get initialized if it didn't exist in scope already.
$directory_list[] = $file;

答案 1 :(得分:0)

我认为您会发现上传功能中的变量名称不匹配。

一开始你有$_FILES['userfile']['name'],但在move_uploaded_file功能中使用了$_FILES['tmp_name']

也许检查变量是否包含您的期望。您可能会发现他们正在评估一个空字符串,当您与正在设置的路径连接时会导致设置一个目录。

修改:实际上,您还将一个名为$_FILES的变量传递到upload_quotes函数中,但是$_FILES是超全局的,因此可用在所有范围内(即任何地方)。重命名upload_quotes的参数(以及相应的任何相关变量)可以解决您的问题。