|
代码如下:
/** * Multi-Upload * * Extends CodeIgniters native Upload class to add support for multiple * uploads. * * @packageCodeIgniter * @subpackageLibraries * @categoryUploads */ class MY_Upload extends CI_Upload {
/** * Properties */ protected $_multi_upload_data= array(); protected $_multi_file_name_override= "";
/** * Initialize preferences * * @accesspublic * @paramarray * @returnvoid */ public function initialize($config = array()){ //Upload default settings. $defaults = array( "max_size"=> 0, "max_width"=> 0, "max_height"=> 0, "max_filename"=> 0, "allowed_types"=> "", "file_temp"=> "", "file_name"=> "", "orig_name"=> "", "file_type"=> "", "file_size"=> "", "file_ext"=> "", "upload_path"=> "", "overwrite"=> FALSE, "encrypt_name"=> FALSE, "is_image"=> FALSE, "image_width"=> "", "image_height"=> "", "image_type"=> "", "image_size_str"=> "", "error_msg"=> array(), "mimes"=> array(), "remove_spaces"=> TRUE, "xss_clean"=> FALSE, "temp_prefix"=> "temp_file_", "client_name"=> "" );
//Set each configuration. foreach($defaults as $key => $val){ if(isset($config[$key])){ $method = "set_{$key}"; if(method_exists($this,$method)){ $this->$method($config[$key]); } else { $this->$key = $config[$key]; } } else { $this->$key = $val; } }
//Check if file_name was provided. if(!empty($this->file_name)){ //Multiple file upload. if(is_array($this->file_name)){ //Clear file name override. $this->_file_name_override = "";
//Set multiple file name override. $this->_multi_file_name_override = $this->file_name; //Single file upload. } else { //Set file name override. $this->_file_name_override = $this->file_name;
//Clear multiple file name override. $this->_multi_file_name_override = ""; } } }
/** * File MIME Type * * Detects the (actual) MIME type of the uploaded file,if possible. * The input array is expected to be $_FILES[$field]. * * In the case of multiple uploads,a optional second argument may be * passed specifying which array element of the $_FILES[$field] array * elements should be referenced (name,type,tmp_name,etc). * * @accessprotected * @param$filearray * @param$countint * @returnvoid */ protected function _file_mime_type($file,$count=0){ //Mutliple file? if(is_array($file["name"])){ $tmp_name = $file["tmp_name"][$count]; $type = $file["type"][$count]; //Single file. } else { $tmp_name = $file["tmp_name"]; $type = $file["type"]; }
//We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii). $regexp = "/^([a-z-]+/[a-z0-9-.+]+)(;s.+)?$/";
/* Fileinfo Extension - most reliable method. * * Unfortunately,prior to PHP 5.3 - it's only available as a PECL extension and the * more convenient FILEINFO_MIME_TYPE flag doesn't exist. */ if(function_exists("finfo_file")){ $finfo = finfo_open(FILEINFO_MIME); if(is_resource($finfo)){ $mime = @finfo_file($finfo,$tmp_name); finfo_close($finfo);
/* According to the comments section of the PHP manual page, * it is possible that this function returns an empty string * for some files (e.g. if they don't exist in the magic MIME database). */ if(is_string($mime) && preg_match($regexp,$mime,$matches)){ $this->file_type = $matches[1]; return; } } }
/* This is an ugly hack,but UNIX-type systems provide a "native" way to detect the file type, * which is still more secure than depending on the value of $_FILES[$field]['type'],and as it * was reported in issue #750 (https://github.com/EllisLab/CodeIgniter/issues/750) - it's better * than mime_content_type() as well,hence the attempts to try calling the command line with * three different functions. * * Notes: *- the DIRECTORY_SEPARATOR comparison ensures that we're not on a Windows system *- many system admins would disable the exec(),shell_exec(),popen() and similar functions * due to security concerns,hence the function_exists() checks */ if(DIRECTORY_SEPARATOR !== ""){ $cmd = "file --brief --mime ".escapeshellarg($tmp_name)." 2>&1";
if(function_exists("exec")){ /* This might look confusing,as $mime is being populated with all of the output when set in the second parameter. * However,we only neeed the last line,which is the actual return value of exec(),and as such - it overwrites * anything that could already be set for $mime previously. This effectively makes the second parameter a dummy * value,which is only put to allow us to get the return status code. */ $mime = @exec($cmd,$return_status); if($return_status === 0 && is_string($mime) && preg_match($regexp,$matches)){ $this->file_type = $matches[1]; return; } } }
if((bool)@ini_get("safe_mode") === FALSE && function_exists("shell_exec")){ $mime = @shell_exec($cmd); if(strlen($mime) > 0){ $mime = explode("n",trim($mime)); if(preg_match($regexp,$mime[(count($mime) - 1)],$matches)){ $this->file_type = $matches[1]; return; } } }
if(function_exists("popen")){ $proc = @popen($cmd,"r"); if(is_resource($proc)){ $mime = @fread($proc,512); @pclose($proc); if($mime !== FALSE){ $mime = explode("n",$matches)){ $this->file_type = $matches[1]; return; } } } }
//Fall back to the deprecated mime_content_type(),if available (still better than $_FILES[$field]["type"]) if(function_exists("mime_content_type")){ $this->file_type = @mime_content_type($tmp_name); //It's possible that mime_content_type() returns FALSE or an empty string. if(strlen($this->file_type) > 0){ return; } }
//If all else fails,use $_FILES default mime type. $this->file_type = $type; }
/** * Set Multiple Upload Data * * @accessprotected * @returnvoid */ protected function set_multi_upload_data(){ $this->_multi_upload_data[] = array( "file_name"=> $this->file_name, "file_type"=> $this->file_type, "file_path"=> $this->upload_path, "full_path"=> $this->upload_path.$this->file_name, "raw_name"=> str_replace($this->file_ext,"",$this->file_name), "orig_name"=> $this->orig_name, "client_name"=> $this->client_name, "file_ext"=> $this->file_ext, "file_size"=> $this->file_size, "is_image"=> $this->is_image(), "image_width"=> $this->image_width, "image_height"=> $this->image_height, "image_type"=> $this->image_type, "image_size_str"=> $this->image_size_str ); }
/** * Get Multiple Upload Data * * @accesspublic * @returnarray */ public function get_multi_upload_data(){ return $this->_multi_upload_data; }
/** * Multile File Upload * * @accesspublic * @paramstring * @returnmixed */ public function do_multi_upload($field){ //Is $_FILES[$field] set? If not,no reason to continue. if(!isset($_FILES[$field])){ return false; }
//Is this really a multi upload? if(!is_array($_FILES[$field]["name"])){ //Fallback to do_upload method. return $this->do_upload($field); }
//Is the upload path valid? if(!$this->validate_upload_path()){ //Errors will already be set by validate_upload_path() so just return FALSE return FALSE; }
//Every file will have a separate entry in each of the $_FILES associative array elements (name,etc). //Loop through $_FILES[$field]["name"] as representative of total number of files. Use count as key in //corresponding elements of the $_FILES[$field] elements. for($i=0; $i//Was the file able to be uploaded? If not,determine the reason why. if(!is_uploaded_file($_FILES[$field]["tmp_name"][$i])){ //Determine error number. $error = (!isset($_FILES[$field]["error"][$i])) ? 4 : $_FILES[$field]["error"][$i];
//Set error. switch($error){ //UPLOAD_ERR_INI_SIZE case 1: $this->set_error("upload_file_exceeds_limit"); break; //UPLOAD_ERR_FORM_SIZE case 2: $this->set_error("upload_file_exceeds_form_limit"); break; //UPLOAD_ERR_PARTIAL case 3: $this->set_error("upload_file_partial"); break; //UPLOAD_ERR_NO_FILE case 4: $this->set_error("upload_no_file_selected"); break; //UPLOAD_ERR_NO_TMP_DIR case 6: $this->set_error("upload_no_temp_directory"); break; //UPLOAD_ERR_CANT_WRITE case 7: $this->set_error("upload_unable_to_write_file"); break; //UPLOAD_ERR_EXTENSION case 8: $this->set_error("upload_stopped_by_extension"); break; default: $this->set_error("upload_no_file_selected"); break; }
//Return failed upload. return FALSE; }
//Set current file data as class variables. $this->file_temp= $_FILES[$field]["tmp_name"][$i]; $this->file_size= $_FILES[$field]["size"][$i]; $this->_file_mime_type($_FILES[$field],$i); $this->file_type= preg_replace("/^(.+?);.*$/","1",$this->file_type); $this->file_type= strtolower(trim(stripslashes($this->file_type),'"')); $this->file_name= $this->_prep_filename($_FILES[$field]["name"][$i]); $this->file_ext= $this->get_extension($this->file_name); $this->client_name= $this->file_name;
//Is the file type allowed to be uploaded? if(!$this->is_allowed_filetype()){ $this->set_error("upload_invalid_filetype"); return FALSE; }
//If we're overriding,let's now make sure the new name and type is allowed. //Check if a filename was supplied for the current file. Otherwise,use it's given name. if(!empty($this->_multi_file_name_override[$i])){ $this->file_name = $this->_prep_filename($this->_multi_file_name_override[$i]);
//If no extension was provided in the file_name config item,use the uploaded one. if(strpos($this->_multi_file_name_override[$i],".") === FALSE){ $this->file_name .= $this->file_ext; //An extension was provided,lets have it! } else { $this->file_ext = $this->get_extension($this->_multi_file_name_override[$i]); }
if(!$this->is_allowed_filetype(TRUE)){ $this->set_error("upload_invalid_filetype"); return FALSE; } }
//Convert the file size to kilobytes. if($this->file_size > 0){ $this->file_size = round($this->file_size/1024,2); }
//Is the file size within the allowed maximum? if(!$this->is_allowed_filesize()){ $this->set_error("upload_invalid_filesize"); return FALSE; }
//Are the image dimensions within the allowed size? //Note: This can fail if the server has an open_basdir restriction. if(!$this->is_allowed_dimensions()){ $this->set_error("upload_invalid_dimensions"); return FALSE; }
//Sanitize the file name for security. $this->file_name = $this->clean_file_name($this->file_name);
//Truncate the file name if it's too long if($this->max_filename > 0){ $this->file_name = $this->limit_filename_length($this->file_name,$this->max_filename); }
//Remove white spaces in the name if($this->remove_spaces == TRUE){ $this->file_name = preg_replace("/s+/","_",$this->file_name); }
/* Validate the file name * This function appends an number onto the end of * the file if one with the same name already exists. * If it returns false there was a problem. */ $this->orig_name = $this->file_name; if($this->overwrite == FALSE){ $this->file_name = $this->set_filename($this->upload_path,$this->file_name); if($this->file_name === FALSE){ return FALSE; } }
/* Run the file through the XSS hacking filter * This helps prevent malicious code from being * embedded within a file. Scripts can easily * be disguised as images or other file types. */ if($this->xss_clean){ if($this->do_xss_clean() === FALSE){ $this->set_error("upload_unable_to_write_file"); return FALSE; } }
/* Move the file to the final destination * To deal with different server configurations * we'll attempt to use copy() first. If that fails * we'll use move_uploaded_file(). One of the two should * reliably work in most environments */ if(!@copy($this->file_temp,$this->upload_path.$this->file_name)){ if(!@move_uploaded_file($this->file_temp,$this->upload_path.$this->file_name)){ $this->set_error("upload_destination_error"); return FALSE; } }
/* Set the finalized image dimensions * This sets the image width/height (assuming the * file was an image). We use this information * in the "data" function. */ $this->set_image_properties($this->upload_path.$this->file_name);
//Set current file data to multi_file_upload_data. $this->set_multi_upload_data(); }
//Return all file upload data. return TRUE; } }
(编辑:安卓应用网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|