Upload文件上传扩展类。属于InitPHP框架扩展类,需要通过$this->getLibrary()方法获取
$upload = $this->getLibrary('upload');
class indexController extends Controller {
public $initphp_list = array('test');
public function run() {
$upload= $this->getLibrary('upload'); //文件上传类加载
/* 参数:表单名称;上传后新的文件名;存放的文件目录;配置,包含最大文件和文件类型*/
$upload = $upload->upload('test', 'test2', 'aa', array('maxSize'=>1024,'allowFileType'=>array('gif')));
$this->view->display(); //模板显示
}
public function test() {
echo 'index.php?c=index&a=test 才会执行';
$code = $this->getLibrary('code');
$code->getcode();
}
/**
* @return testService
*/
private function getTestService() {
return InitPHP::getService('test','test');
}
}
if (!defined('IS_INITPHP')) exit('Access Denied!');
/*********************************************************************************
* InitPHP 2.1 国产PHP开发框架 扩展类库-文件上传
*-------------------------------------------------------------------------------
* 版权所有: CopyRight By initphp.com
* 您可以自由使用该源码,但是在使用过程中,请保留作者信息。尊重他人劳动成果就是尊重自己
*-------------------------------------------------------------------------------
* $Author:zhuli
* $Dtime:2011-10-09
***********************************************************************************/
class uploadInit {
const UPLOAD_ERR_INI_SIZE = 1;
const INPUT_MAX_FILE_SIZE = 2;
const UPLOAD_HALF = 3;
const UPLOAD_ERR_NO_TMP_DIR = 4;
private $params; //参数
private $defaultMaxSize = 2048; //上传文件默认最大值
private $defaultAllowFileType = array('gif','jpeg','jpg','png','bmp','swf', 'txt');
private $errorCodeArr = array(
'upload_error' => -1, //上传失败
'not_upload_files' => -2, //不是通过HTTP POST方法上传
'not_an_allowed_type' => -3, //不允许的上传类型
'file_size_is_large' => -4, //文件太大
'upload_err_ini_size' => -5, //上传文件超过服务器上传限制
'input_max_file_size' => -6, //上传文件超过表达最大上传限制
'upload_half' => -7, //只上传了一半文件
'upload_err_no_tmp_dir'=> -8, //上传的临时目录出错
'illegal_file_type' => -9, //新的文件名,命名不合法
'upload_content_error' => -10 //上传的内容不合法
); //错误码
/**
* 上传文件 主函数
* @param $name 上传文件名
* @param $newName 新的文件名 不需要类型
* @param $path 目录
* @param $params 参数配置
* @return array
*/
public function upload($name, $newName, $path, $params = array()) {
$this->params = $this->parseParams($params);
$uploadInfo = $this->init($name, $newName, $path);
if (!$uploadInfo) return $this->error('upload_error'); //是否正常上传
$errorVal = $this->checkUpload($uploadInfo['error']);
if ($errorVal !== true) return $this->error($errorVal); //检测上传错误码
if (!$this->checkIsUploadFile($uploadInfo['tmp_name'])) return $this->error('not_upload_files'); //是否通过HTTP POST上传
if (!$this->checkType($uploadInfo['ext'])) return $this->error('not_an_allowed_type'); //是否允许上传的类型
if (!$this->checkSize($uploadInfo['size'])) return $this->error('file_size_is_large'); //文件大小
if (!$this->checkNewName($newName)) return $this->error('illegal_file_type'); //新文件名是否合法
$result = $this->save($uploadInfo['tmp_name'], $uploadInfo['source'], $uploadInfo['path']);
if ($result == false) {
return $this->error('upload_error');
} else {
$checkContentResult = $this->checkContent($uploadInfo);
if ($checkContentResult !== true) return $this->error($checkContentResult); //检测上传错误码
return $uploadInfo;
}
}
/**
* 参数设置
* @param array $params array('maxSize' => 文件上传最大,'allowFileType' => 允许上传的文件类型)
* @return
*/
public function setParams($params) {
$this->params = $this->parseParams($params);
}
/**
* 装载上传文件的信息
* @param string $name 上传文件名
* @return array
*/
private function init($name, $newName, $path) {
$newName = $this->escapeStr($newName);
$path = $this->escapeDir($path);
$file = $_FILES[$name];
if (!$file['tmp_name'] || $file['tmp_name'] == '') return false;
$file['name'] = $this->escapeStr($file['name']);
$file['ext'] = strtolower(substr(strrchr($file['name'], '.'), 1));
$file['size'] = intval($file['size']);
$file['type'] = $file['type'];
$file['tmp_name'] = $file['tmp_name'];
$file['source'] = $path .'/'. $newName . '.' . $file['ext']; //路径
$file['path'] = $path; //目录
$file['newName'] = $newName. '.' . $file['ext']; //文件名
return $file;
}
/**
* 参数处理
* @param array $params 文件上传配置参数
* @return
*/
private function parseParams(array $params) {
$temp = array();
$temp['maxSize'] = (isset($params['maxSize'])) ? (int)$params['maxSize'] : $this->defaultMaxSize;
$temp['allowFileType'] = (is_array($params['allowFileType'])) ? $params['allowFileType'] : $this->defaultAllowFileType;
return $temp;
}
/**
* 保存文件
* @param $name 上传文件名
* @param $newName 新的文件名 1
* @param $path 目录
* @return bool
*/
private function save($tmpName, $filename, $path) {
$this->createFolder($path); //创建目录
if (function_exists("move_uploaded_file") && @move_uploaded_file($tmpName, $filename)) {
@chmod($filename, 0777);
return true;
} elseif (@copy($tmpName, $filename)) {
@chmod($filename, 0777);
return true;
}
return false;
}
/**
* 错误码检测
* @param int $error 错误状态
* @return string
*/
private function checkUpload($error) {
if ($error == uploadInit::UPLOAD_ERR_INI_SIZE) { //上传是否超过ini设置
return 'upload_err_ini_size';
} elseif ($error == uploadInit::INPUT_MAX_FILE_SIZE) { //上传是否超过表单设置
return 'input_max_file_size';
} elseif ($error == uploadInit::UPLOAD_HALF) { //上传一半
return 'upload_half';
} elseif ($error == uploadInit::UPLOAD_ERR_NO_TMP_DIR) { //上传临时目录创建错误
return 'upload_err_no_tmp_dir';
} else {
return true;
}
}
/**
* 文件类型检测
* @param string $uploadType 类型
* @return bool
*/
private function checkType($uploadType) {
return (empty($uploadType) || !in_array($uploadType, $this->params['allowFileType'])) ? false : true;
}
/**
* 文件大小检测
* @param int $uploadSize 大小
* @return bool
*/
private function checkSize($uploadSize) {
return ($uploadSize < 1 || $uploadSize > ($this->params['maxSize'] * 1024)) ? false : true;
}
/**
* 检测新的文件名
* @param string $newName 新文件名
* @return bool
*/
private function checkNewName($newName) {
$newName = strtolower($newName);
return (strpos($newName, '..') !== false || strpos($newName, '.php.') !== false || eregi("\.php$", $newName)) ? false : true;
}
/**
* 检测是否是上传的文件
* @param $tmpName 临时文件名
* @return bool
*/
private function checkIsUploadFile($tmpName) {
if (!$tmpName || $tmpName == 'none') {
return false;
} elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmpName) && !is_uploaded_file(str_replace('\\\\', '\\', $tmpName))) {
return false;
} else {
return true;
}
}
/**
* 文件上传后检测文件内容是否合法
* @param string $uploadInfo 文件信息
* @param string $source 文件源目录
* @return bool
*/
private function checkContent($uploadInfo) {
if ($uploadInfo['ext'] == 'txt') {
if (preg_match('/(onload|submit|post|form)/i', $this->readover($uploadInfo['source']))) {
@unlink($uploadInfo['source']);
return 'upload_content_error';
}
} elseif (in_array($uploadInfo['ext'], array('gif','jpg','jpeg','png','bmp','swf'))) {
if (!$img_size = $this->getImgSize($uploadInfo['source'], $uploadInfo['ext'])) {
@unlink($uploadInfo['source']);
return 'upload_content_error';
}
}
return true;
}
/**
* 创建目录 如果目录存在,则不创建,不存在则创建 static
* @param $path 路径
* @return
*/
public static function createFolder($path) {
if (!is_dir($path)) {
uploadInit::createFolder(dirname($path));
@mkdir($path);
@chmod($path, 0777);
@fclose(@fopen($path . '/index.html', 'w'));
@chmod($path . '/index.html', 0777);
}
}
/**
* 读取文件
* @param string $fileName 文件绝对路径
* @param string $method 读取模式
*/
private function readover($fileName, $method = 'rb') {
$fileName = $this->escapePath($fileName);
$data = '';
if ($handle = @fopen($fileName, $method)) {
flock($handle, LOCK_SH);
$data = @fread($handle, filesize($fileName));
fclose($handle);
}
return $data;
}
/**
* 获取图片的大小
* @param string $srcFile 图片地址
* @param string $srcExt 图片类型
* @return
*/
private function getImgSize($srcFile, $srcExt = null) {
empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1));
$srcdata = array();
if (function_exists('read_exif_data') && in_array($srcExt, array(
'jpg',
'jpeg',
'jpe',
'jfif'
))) {
$datatemp = @read_exif_data($srcFile);
$srcdata['width'] = $datatemp['COMPUTED']['Width'];
$srcdata['height'] = $datatemp['COMPUTED']['Height'];
$srcdata['type'] = 2;
unset($datatemp);
}
!$srcdata['width'] && list($srcdata['width'], $srcdata['height'], $srcdata['type']) = @getimagesize($srcFile);
if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, array(
'jpg',
'jpeg',
'jpe',
'jfif'
)))) { //noizy fix
return false;
}
return $srcdata;
}
/**
* 字符转换
* @param string $string 转换的字符串
* @return string 返回转换后的字符串
*/
private function escapeStr($string) {
$string = str_replace(array("\0","%00","\r"), '', $string);
$string = preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/','/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string);
$string = str_replace(array("%3C",'<'), '<', $string);
$string = str_replace(array("%3E",'>'), '>', $string);
$string = str_replace(array('"',"'","\t",' '), array('"',''',' ',' '), $string);
return $string;
}
/**
* 目录转换
* @param string $dir
* @return string
*/
private function escapeDir($dir) {
$dir = str_replace(array("'",'#','=','`','$','%','&',';'), '', $dir);
return trim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/');
}
/**
* 私用路径转换
* @param $fileName
* @param $ifCheck
* @return boolean
*/
private function escapePath($fileName, $ifCheck = true) {
$tmpname = strtolower($fileName);
$tmparray = array('://',"\0");
$ifCheck && $tmparray[] = '..';
if (str_replace($tmparray, '', $tmpname) != $tmpname) {
return false;
}
return true;
}
/**
* 上传错误提示
* @param unknown_type $msgType
*/
private function error($errorCode) {
return $this->errorCodeArr[$errorCode];
}
}