doujuxin7392 2014-08-20 20:54
浏览 54
已采纳

多文件上传 - 当所有文件上传失败时,只输入少量文件时工作正常

I have this form in which it is required to upload multiple files(upto 10 files). Here's what the html looks like:

<form action="fileupload.php" method="post" enctype="multipart/form-data">
<tr><td><input type="hidden" name="consultant_id" value="<?php echo $consult_id; ?>"></td></tr>

<tr><td>Offer letter:</td><td> Doc: <input type="file" name="myfile[]"></td></tr>
<tr><td>Project acceptance agreement:</td><td> Doc: <input type="file" name="myfile[]"></td></tr>
<tr><td>Employee book:</td><td> Doc: <input type="file" name="myfile[]"></td></tr>
<tr><td>W4 :</td><td> Doc: <input type="file" name="myfile[]"></td></tr>
<tr><td>State W4 :</td><td> Doc: <input type="file" name="myfile[]"></td></tr>
<tr><td><input type="submit" name="submit" value="Upload">  </td></tr>
</form></table>

I want to upload the files to the server and store their respective paths in database(MySql). Now the following php code works awesome when I give input to all file fields(upload all 10 files) but fails when I want to upload only some files(say 5). Here's the code :

        <?php
    $consultant_id = $_POST['consultant_id'];
    echo $consultant_id;
    $verified_start_date = $_POST['verified_start_date'];

    // Assign valid types
    $valid_mime = array(
        'application/pdf',
        'image/jpeg',
        'image/jpg',



     );

    function upload($files, $dir, $size_limit=1024, $prevent_duplicate=false){
        global $valid_mime;

    // $files must be given.
    if(!isset($files)) return false;

    // Look for $valid_mime array.
    isset($valid_mime) and is_array($valid_mime) or die('Error in data resources, valid_mime array not found.');

    // Make directory if it does not exists. set permission to 0777.
    is_dir($dir) and chmod($dir, 0777) or mkdir($dir, 0777, true);
    //is_dir($consultant_id) and ($dir, 0777) or mkdir($dir/$consultant_id, 0777, true);
    $count = 1;
    foreach($files as $file){
        $file['error'] === UPLOAD_ERR_OK or die('Error in uploading file(s).');

        // Check uploaded-file type.
        in_array($file['type'], $valid_mime) or die();

        // Set size_limit in KB.
        $file['size'] > $size_limit*1024 and die('The uploaded file exceeds the maximum file size.');


        $file_extension = strrchr($file['name'], '.');
        $filename = basename($file['name'], $file_extension);

        $file_path = "{$dir}/{$filename}{$file_extension}";

        // Move uploaded-file from php temp folder to desire one.
        move_uploaded_file($file["tmp_name"], $file_path);

        // Make an array of filepaths
        $output[] = $file_path;
    }

    // Change permission of folder according to security issues.
    chmod($dir, 0755);

    return $output; 
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////  Controller Section  ////////////////////////////////

// Assign tmp_arr from $_FILES['myfile'] and do die if there is any problem.
$tmp_arr = (isset($_POST['submit']) and isset($_FILES['myfile'])) ? $_FILES['myfile'] : die('Error in posting data.');


// Create an array with desired structure.
for($i=0; $i<count($tmp_arr['name']); $i++){
    $files[] = array(
        'name'      =>  $tmp_arr['name'][$i],
        'type'      =>  $tmp_arr['type'][$i],
        'tmp_name'  =>  $tmp_arr['tmp_name'][$i],
        'error' =>  $tmp_arr['error'][$i],
        'size'      =>  $tmp_arr['size'][$i],
    );
}

// size_limit in KB
$path_arr = upload($files, './public/'.$consultant_id, 1024, true);
?>

I have not mentioned the part where data is entered in database, as I know the problem is somewhere in $tmp_arr['error'][$i] or $file['error'] === UPLOAD_ERR_OK or die('Error in uploading file(s).');

Please take a look.

  • 写回答

1条回答 默认 最新

  • 普通网友 2014-08-20 21:27
    关注

    The problem appears to be that when you have a blank file input, it returns an 'error' value of 4 which means UPLOAD_ERR_NO_FILE. So since the field doesn't match UPLOAD_ERR_OK you immediately stop all code by calling die stopping any files after the first blank from copying over. If the first field was blank, nothing would get get to the move_uploaded_file. If the third out of ten was blank, then the first two files would get copied and when the third was processed it would stop any further files. But you would still just see the error "Error in uploading file(s)."

    Edit:

    <?php
    $consultant_id = $_POST['consultant_id'];
    echo $consultant_id;
    $verified_start_date = $_POST['verified_start_date'];
    
    // Assign valid types
    $valid_mime = array(
        'application/pdf',
        'image/jpeg',
        'image/jpg',
    
    
    
     );
    
    function upload($files, $dir, $size_limit=1024, $prevent_duplicate=false){
        global $valid_mime;
    
        // $files must be given.
        if(!isset($files)) return false;
    
        //please use proper if statements. This is confusing.
        //isset($valid_mime) and is_array($valid_mime) or die('Error in data resources, valid_mime array not found.');
    
        // Look for $valid_mime array.
        if(!isset($valid_mime) || !is_array($valid_mime)) {
            die('Error in data resources, valid_mime array not found.');
        }
    
        //please use proper if statements. This is confusing.
        // is_dir($dir) and chmod($dir, 0777) or mkdir($dir, 0777, true);
    
        // Make directory if it does not exists. set permission to 0777.
        if(!is_dir($dir)) {
            mkdir($dir, 0777, true);
        } else {
            //try to chmod if the directory does exist
            chmod($dir, 0777);
        }
    
        if(!is_writable($dir)){
            die('Error unable to write to specified directory.');
        }
    
        foreach($files as $key=>$file){
            //switch case on the error code
            //you can find a list of these error codes at: http://php.net/manual/en/features.file-upload.errors.php
            switch($file['error']){
                default:
                    //triggered if an unknown error happened. Newer php versions might bring new constants.
                    //log error for this file
                    $output[$key] = array('error'=>true, 'message'=>'An unknown error occurred');
                    break;
                case UPLOAD_ERR_INI_SIZE:
                    //log error for this file
                    $output[$key] = array('error'=>true, 'message'=>'File size exceeds ini setting');
                    break;
                case UPLOAD_ERR_FORM_SIZE:
                    //log error for this file
                    $output[$key] = array('error'=>true, 'message'=>'File size exceeds MAX_FILE_SIZE setting');
                    break;
                case UPLOAD_ERR_PARTIAL:
                    //log error for this file
                    $output[$key] = array('error'=>true, 'message'=>'File was only partially uploaded');
                    break;
                case UPLOAD_ERR_NO_FILE:
                    //log error for this file
                    $output[$key] = array('error'=>true, 'message'=>'File input was blank');
                    break;
                case UPLOAD_ERR_NO_TMP_DIR:
                    //log error for this file
                    $output[$key] = array('error'=>true, 'message'=>'Missing temporary folder');
                    break;
                case UPLOAD_ERR_CANT_WRITE:
                    //log error for this file
                    $output[$key] = array('error'=>true, 'message'=>'Failed to write file to disk');
                    break;
                case UPLOAD_ERR_OK:
                    //upload worked fine
                    // Check uploaded-file type.
                    if(in_array($file['type'], $valid_mime)){
                        // Set size_limit in KB.
                        if($file['size'] <= $size_limit*1024){
                            //get the file extension.
                            $file_extension = strrchr($file['name'], '.');
                            //get the filename
                            $filename = basename($file['name'], $file_extension);
                            //full filename and path
                            $file_path = "{$dir}/{$filename}{$file_extension}";
    
                            // Move uploaded-file from php temp folder to desire one.
                            // function returns true if the move was successful
                            if(move_uploaded_file($file["tmp_name"], $file_path)){
                                $output[$key] = array('error'=>false, 'message'=>'File was uploaded successfully', 'file'=>$file_path);
                            } else {
                                $output[$key] = array('error'=>true, 'message'=>'Unspecified error when moving the uploaded file');
                            }
                        } else {
                            //log error for this file
                            $output[$key] = array('error'=>true, 'message'=>'The uploaded file exceeds the maximum file size');
                        }
                    } else {
                        //log error for this file
                        $output[$key] = array('error'=>true, 'message'=>'Failed to write file to disk');
                    }
            }
        }
    
        // Change permission of folder according to security issues.
        chmod($dir, 0755);
    
        return $output; 
    }
    
    /////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////  Controller Section  ////////////////////////////////
    
    // Assign tmp_arr from $_FILES['myfile'] and do die if there is any problem.
    $tmp_arr = (isset($_POST['submit']) and isset($_FILES['myfile'])) ? $_FILES['myfile'] : die('Error in posting data.');
    
    
    // Create an array with desired structure.
    for($i=0; $i<count($tmp_arr['name']); $i++){
        $files[] = array(
            'name'      =>  $tmp_arr['name'][$i],
            'type'      =>  $tmp_arr['type'][$i],
            'tmp_name'  =>  $tmp_arr['tmp_name'][$i],
            'error' =>  $tmp_arr['error'][$i],
            'size'      =>  $tmp_arr['size'][$i],
        );
    }
    
    // size_limit in KB
    $path_arr = upload($files, './public/'.$consultant_id, 1024, true);
    

    If I were doing this, this is the function I would use. If one uploaded file has a problem, it won't stop the remaining files from uploading and translates the 'error' key from $_FILES into a more user friendly message. You could easily loop over the return array and check the boolean 'error' key to see if a specific file has a problem. If 'error' is true, you could echo the message for the user to see. If there was no error, the message 'File was uploaded successfully' can be displayed. The keys from the return array correspond to the same keys found in the array passed in. So $file[0] is the same file as $returnResult[0] for easy reference.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配