KodExplorer/app/function/file.function.php

1506 lines
47 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
/*
* @link http://kodcloud.com/
* @author warlee | e-mail:kodcloud@qq.com
* @copyright warlee 2014.(Shanghai)Co.,Ltd
* @license http://kodcloud.com/tools/license/license.txt
*/
/**
* 系统函数: filesize(),file_exists(),pathinfo(),rname(),unlink(),filemtime(),is_readable(),is_wrieteable();
* 获取文件详细信息 file_info($fileName)
* 获取文件夹详细信息 path_info($dir)
* 递归获取文件夹信息 path_info_more($dir,&$fileCount=0,&$pathCount=0,&$size=0)
* 获取文件夹下文件列表 path_list($dir)
* 路径当前文件[夹]名 get_path_this($path)
* 获取路径父目录 get_path_father($path)
* 删除文件 del_file($file)
* 递归删除文件夹 del_dir($dir)
* 递归复制文件夹 copy_dir($source, $dest)
* 创建目录 mk_dir($dir, $mode = 0777)
* 文件大小格式化 size_format($bytes, $precision = 2)
* 判断是否绝对路径 path_is_absolute( $path )
* 扩展名的文件类型 ext_type($ext)
* 文件下载 file_download($file)
* 文件下载到服务器 file_download_this($from, $fileName)
* 获取文件(夹)权限 get_mode($file) //rwx_rwx_rwx [文件名需要系统编码]
* 上传文件(单个,多个) upload($fileInput, $path = './');//
* 获取配置文件项 get_config($file, $ini, $type="string")
* 修改配置文件项 update_config($file, $ini, $value,$type="string")
* 写日志到LOG_PATH下 write_log('dd','default|.自建目录.','log|error|warning|debug|info|db')
*/
// 传入参数为程序编码时,有传出,则用程序编码,
// 传入参数没有和输出无关时,则传入时处理成系统编码。
function iconv_app($str){
global $config;
$result = iconv_to($str,$config['systemCharset'], $config['appCharset']);
return $result;
}
function iconv_system($str){
//去除中文空格UTF8; windows下展示异常;过滤文件上传、新建文件等时的文件名
//文件名已存在含有该字符时,没有办法操作.
$char_empty = "\xc2\xa0";
if(strpos($str,$char_empty) !== false){
$str = str_replace($char_empty," ",$str);
}
global $config;
$result = iconv_to($str,$config['appCharset'], $config['systemCharset']);
$result = path_filter($result);
return $result;
}
function iconv_to($str,$from,$to){
if(!$from || !$to) return $str;
if (strtolower($from) == strtolower($to)){
return $str;
}
if (!function_exists('iconv')){
return $str;
}
//尝试用mb转换android环境部分问题解决
if(function_exists('mb_convert_encoding')){
$result = @mb_convert_encoding($str,$to,$from);
}else{
$result = @iconv($from, $to, $str);
}
if(strlen($result)==0){
return $str;
}
return $result;
}
function path_filter($path){
if(strtoupper(substr(PHP_OS, 0,3)) != 'WIN'){
return $path;
}
$notAllow = array('*','?','"','<','>','|');//去除 : D:/
return str_replace($notAllow,' ', $path);
}
//filesize 解决大于2G 大小问题
//http://stackoverflow.com/questions/5501451/php-x86-how-to-get-filesize-of-2-gb-file-without-external-program
function get_filesize($path){
if(PHP_INT_SIZE >= 8 ){ //64bit
return (float)(abs(sprintf("%u",@filesize($path))));
}
$fp = fopen($path,"r");
if(!$fp) return $result;
if (fseek($fp, 0, SEEK_END) === 0) {
$result = 0.0;
$step = 0x7FFFFFFF;
while ($step > 0) {
if (fseek($fp, - $step, SEEK_CUR) === 0) {
$result += floatval($step);
} else {
$step >>= 1;
}
}
}else{
static $iswin;
if (!isset($iswin)) {
$iswin = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
}
static $exec_works;
if (!isset($exec_works)) {
$exec_works = (function_exists('exec') && !ini_get('safe_mode') && @exec('echo EXEC') == 'EXEC');
}
if ($iswin && class_exists("COM")) {
try {
$fsobj = new COM('Scripting.FileSystemObject');
$f = $fsobj->GetFile( realpath($path) );
$size = $f->Size;
} catch (Exception $e) {
$size = null;
}
if (is_numeric($size)) {
$result = $size;
}
}else if ($exec_works){
$cmd = ($iswin) ? "for %F in (\"$path\") do @echo %~zF" : "stat -c%s \"$path\"";
@exec($cmd, $output);
if (is_array($output) && is_numeric($size = trim(implode("\n", $output)))) {
$result = $size;
}
}else{
$result = filesize($path);
}
}
fclose($fp);
return $result;
}
//文件是否存在,区分文件大小写
function file_exists_case( $fileName ){
if(file_exists($fileName) === false){
return false;
}
$status = false;
$directoryName = dirname( $fileName );
$fileArray = glob( $directoryName . '/*', GLOB_NOSORT);
if ( preg_match( "/\\\|\//", $fileName) ){
$array = preg_split("/\\\|\//", $fileName);
$fileName = $array[ count( $array ) -1 ];
}
foreach($fileArray as $file ){
if(preg_match("/{$fileName}/i", $file)){
$output = "{$directoryName}/{$fileName}";
$status = true;
break;
}
}
return $status;
}
function path_readable($path){
$result = intval(is_readable($path));
if($result){
return $result;
}
$mode = get_mode($path);
if( $mode &&
strlen($mode) == 18 &&
substr($mode,-9,1) == 'r'){// -rwx rwx rwx(0777)
return true;
}
return false;
}
function path_writeable($path){
$result = intval(is_writeable($path));
if($result){
return $result;
}
$mode = get_mode($path);
if( $mode &&
strlen($mode) == 18 &&
substr($mode,-8,1) == 'w'){// -rwx rwx rwx (0777)
return true;
}
return false;
}
/**
* 获取文件详细信息
* 文件名从程序编码转换成系统编码,传入utf8系统函数需要为gbk
*/
function file_info($path){
$info = array(
'name' => iconv_app(get_path_this($path)),
'path' => iconv_app($path),
'ext' => get_path_ext($path),
'type' => 'file',
'mode' => get_mode($path),
'atime' => @fileatime($path), //最后访问时间
'ctime' => @filectime($path), //创建时间
'mtime' => @filemtime($path), //最后修改时间
'isReadable' => path_readable($path),
'isWriteable' => path_writeable($path),
'size' => get_filesize($path)
);
return $info;
}
/**
* 获取文件夹细信息
*/
function folder_info($path){
$info = array(
'name' => iconv_app(get_path_this($path)),
'path' => iconv_app(rtrim($path,'/').'/'),
'type' => 'folder',
'mode' => get_mode($path),
'atime' => @fileatime($path), //访问时间
'ctime' => @filectime($path), //创建时间
'mtime' => @filemtime($path), //最后修改时间
'isReadable' => path_readable($path),
'isWriteable' => path_writeable($path)
);
return $info;
}
/**
* 获取一个路径(文件夹&文件) 当前文件[夹]名
* test/11/ ==>11 test/1.c ==>1.c
*/
function get_path_this($path){
$path = str_replace('\\','/', rtrim($path,'/'));
$pos = strrpos($path,'/');
if($pos === false){
return $path;
}
return substr($path,$pos+1);
}
/**
* 获取一个路径(文件夹&文件) 父目录
* /test/11/==>/test/ /test/1.c ==>/www/test/
*/
function get_path_father($path){
$path = str_replace('\\','/', rtrim($path,'/'));
$pos = strrpos($path,'/');
if($pos === false){
return $path;
}
return substr($path, 0,$pos+1);
}
/**
* 获取扩展名
*/
function get_path_ext($path){
$name = get_path_this($path);
$ext = '';
if(strstr($name,'.')){$ext = substr($name,strrpos($name,'.')+1);}
$isMatch = preg_match("/[0-9a-zA-Z_]+/",$ext,$match);// 只允许数字字母和下划线
return ($isMatch && $match[0]) ? strtolower($match[0]):'';
}
//自动获取不重复文件(夹)名
//如果传入$file_add 则检测存在则自定重命名 a.txt 为a{$file_add}.txt
//$same_file_type rename,replace,skip,folder_rename
function get_filename_auto($path,$file_add = "",$same_file_type='replace'){
if (is_dir($path) && $same_file_type!='folder_rename') {//文件夹则忽略
return $path;
}
//重名处理
if (file_exists($path)) {
if ($same_file_type=='replace') {
return $path;
}else if($same_file_type=='skip'){
return false;
}
}
$i=1;
$father = get_path_father($path);
$name = get_path_this($path);
$ext = get_path_ext($name);
if(is_dir($path)){
$ext = '';
}
if (strlen($ext)>0) {
$ext='.'.$ext;
$name = substr($name,0,strlen($name)-strlen($ext));
}
while(file_exists($path)){
if ($file_add != '') {
$path = $father.$name.$file_add.$ext;
$file_add.='-';
}else{
$path = $father.$name.'('.$i.')'.$ext;
$i++;
}
}
return $path;
}
/**
* 获取文件夹详细信息,文件夹属性时调用,包含子文件夹数量,文件数量,总大小
*/
function path_info($path){
if (!file_exists($path)) return false;
$pathinfo = _path_info_more($path);//子目录文件大小统计信息
$folderinfo = folder_info($path);
return array_merge($pathinfo,$folderinfo);
}
/**
* 检查名称是否合法
*/
function path_check($path){
$check = array('/','\\',':','*','?','"','<','>','|');
$path = rtrim($path,'/');
$path = get_path_this($path);
foreach ($check as $v) {
if (strstr($path,$v)) {
return false;
}
}
return true;
}
/**
* 递归获取文件夹信息: 子文件夹数量,文件数量,总大小
*/
function _path_info_more($dir, &$fileCount = 0, &$pathCount = 0, &$size = 0){
if (!$dh = @opendir($dir)) return array('fileCount'=>0,'folderCount'=>0,'size'=>0);
while (($file = readdir($dh)) !== false) {
if ($file =='.' || $file =='..') continue;
$fullpath = $dir . "/" . $file;
if (!is_dir($fullpath)) {
$fileCount ++;
$size += get_filesize($fullpath);
} else {
_path_info_more($fullpath, $fileCount, $pathCount, $size);
$pathCount ++;
}
}
closedir($dh);
$pathinfo['fileCount'] = $fileCount;
$pathinfo['folderCount'] = $pathCount;
$pathinfo['size'] = $size;
return $pathinfo;
}
/**
* 获取多选文件信息,包含子文件夹数量,文件数量,总大小,父目录权限
*/
function path_info_muti($list,$timeType){
if (count($list) == 1) {
if ($list[0]['type']=="folder"){
return path_info($list[0]['path'],$timeType);
}else{
return file_info($list[0]['path'],$timeType);
}
}
$pathinfo = array(
'fileCount' => 0,
'folderCount' => 0,
'size' => 0,
'father_name' => '',
'mod' => ''
);
foreach ($list as $val){
if ($val['type'] == 'folder') {
$pathinfo['folderCount'] ++;
$temp = path_info($val['path']);
$pathinfo['folderCount'] += $temp['folderCount'];
$pathinfo['fileCount'] += $temp['fileCount'];
$pathinfo['size'] += $temp['size'];
}else{
$pathinfo['fileCount']++;
$pathinfo['size'] += get_filesize($val['path']);
}
}
$father_name = get_path_father($list[0]['path']);
$pathinfo['mode'] = get_mode($father_name);
return $pathinfo;
}
/**
* 获取文件夹下列表信息
* dir 包含结尾/ d:/wwwroot/test/
* 传入需要读取的文件夹路径,为程序编码
*/
function path_list($dir,$listFile=true,$checkChildren=false){
$dir = rtrim($dir,'/').'/';
if (!is_dir($dir) || !($dh = @opendir($dir))){
return array('folderList'=>array(),'fileList'=>array());
}
$folderList = array();$fileList = array();//文件夹与文件
while (($file = readdir($dh)) !== false) {
if ($file =='.' || $file =='..' || $file == ".svn") continue;
$fullpath = $dir . $file;
if (is_dir($fullpath)) {
$info = folder_info($fullpath);
if($checkChildren){
$info['isParent'] = path_haschildren($fullpath,$listFile);
}
$folderList[] = $info;
} else if($listFile) {//是否列出文件
$info = file_info($fullpath);
if($checkChildren) $info['isParent'] = false;
$fileList[] = $info;
}
}
closedir($dh);
return array('folderList' => $folderList,'fileList' => $fileList);
}
// 判断文件夹是否含有子内容【区分为文件或者只筛选文件夹才算】
function path_haschildren($dir,$checkFile=false){
$dir = rtrim($dir,'/').'/';
if (!$dh = @opendir($dir)) return false;
while (($file = readdir($dh)) !== false){
if ($file =='.' || $file =='..') continue;
$fullpath = $dir.$file;
if ($checkFile) {//有子目录或者文件都说明有子内容
if(@is_file($fullpath) || is_dir($fullpath.'/')){
closedir($dh);
return true;
}
}else{//只检查有没有文件
if(@is_dir($fullpath.'/')){//解决部分主机报错问题
closedir($dh);
return true;
}
}
}
closedir($dh);
return false;
}
/**
* 删除文件 传入参数编码为操作系统编码. win--gbk
*/
function del_file($fullpath){
if (!@unlink($fullpath)) { // 删除不了,尝试修改文件权限
@chmod($fullpath, 0777);
if (!@unlink($fullpath)) {
return false;
}
} else {
return true;
}
}
/**
* 删除文件夹 传入参数编码为操作系统编码. win--gbk
*/
function del_dir($dir){
if(!file_exists($dir) || !is_dir($dir)) return true;
if (!$dh = opendir($dir)) return false;
@set_time_limit(0);
while (($file = readdir($dh)) !== false) {
if ($file =='.' || $file =='..') continue;
$fullpath = $dir . '/' . $file;
if (!is_dir($fullpath)) {
if (!unlink($fullpath)) { // 删除不了,尝试修改文件权限
chmod($fullpath, 0777);
if (!unlink($fullpath)) {
return false;
}
}
} else {
if (!del_dir($fullpath)) {
chmod($fullpath, 0777);
if (!del_dir($fullpath)) return false;
}
}
}
closedir($dh);
if (rmdir($dir)) {
return true;
} else {
return false;
}
}
/**
* 复制文件夹
* eg:将D:/wwwroot/下面wordpress复制到
* D:/wwwroot/www/explorer/0000/del/1/
* 末尾都不需要加斜杠,复制到地址如果不加源文件夹名,
* 就会将wordpress下面文件复制到D:/wwwroot/www/explorer/0000/del/1/下面
* $from = 'D:/wwwroot/wordpress';
* $to = 'D:/wwwroot/www/explorer/0000/del/1/wordpress';
*/
function copy_dir($source, $dest){
if (!$dest) return false;
if (is_dir($source) && $source == substr($dest,0,strlen($source))) return false;//防止父文件夹拷贝到子文件夹,无限递归
@set_time_limit(0);
$result = true;
if (is_file($source)) {
if ($dest[strlen($dest)-1] == '/') {
$__dest = $dest . "/" . basename($source);
} else {
$__dest = $dest;
}
$result = @copy($source,$__dest);
@chmod($__dest, 0777);
}else if(is_dir($source)) {
if ($dest[strlen($dest)-1] == '/') {
$dest = $dest . basename($source);
}
if (!is_dir($dest)) {
@mkdir($dest,0777);
}
if (!$dh = opendir($source)) return false;
while (($file = readdir($dh)) !== false) {
if ($file =='.' || $file =='..') continue;
$result = copy_dir($source . "/" . $file, $dest . "/" . $file);
}
closedir($dh);
}
return $result;
}
/**
* 移动文件&文件夹;(同名文件夹则特殊处理)
* 问题win下挂载磁盘移动到系统盘时rmdir导致遍历不完全
*/
function move_path2($source,$dest,$repeat_add='',$repeat_type='replace'){
if (!$dest) return false;
if (is_dir($source) && $source == substr($dest,0,strlen($source))) return false;//防止父文件夹拷贝到子文件夹,无限递归
@set_time_limit(0);
if (is_file($source)) {
return move_file($source,$dest,$repeat_add,$repeat_type);
}else if(is_dir($source)) {
if ($dest[strlen($dest)-1] == '/') {
$dest = $dest . basename($source);
}
if (!file_exists($dest)) {
@mkdir($dest,0777);
}
if (!$dh = opendir($source)) return false;
while (($file = readdir($dh)) !== false) {
if ($file =='.' || $file =='..') continue;
move_path($source."/".$file, $dest."/".$file,$repeat_add,$repeat_type);
}
closedir($dh);
return @rmdir($source);
}
}
function move_file($source,$dest,$repeat_add,$repeat_type){
if ($dest[strlen($dest)-1] == '/') {
$dest = $dest . "/" . basename($source);
}
if(file_exists($dest)){
$dest = get_filename_auto($dest,$repeat_add,$repeat_type);//同名文件处理规则
}
$result = intval(@rename($source,$dest));
if (! $result) { // windows部分ing情况处理
$result = intval(@copy($source,$dest));
if ($result) {
@unlink($source);
}
}
return $result;
}
function move_path($source,$dest,$repeat_add='',$repeat_type='replace'){
if (!$dest || !file_exists($source)) return false;
if ( is_dir($source) ){
//防止父文件夹拷贝到子文件夹,无限递归
if($source == substr($dest,0,strlen($source))){
return false;
}
//地址相同
if(rtrim($source,'/') == rtrim($dest,'/')){
return false;
}
}
@set_time_limit(0);
if(is_file($source)){
return move_file($source,$dest,$repeat_add,$repeat_type);
}
recursion_dir($source,$dirs,$files,-1,0);
@mkdir($dest);
foreach($dirs as $f){
$path = $dest.'/'.substr($f,strlen($source));
if(!file_exists($path)){
mk_dir($path);
}
}
$file_success = 0;
foreach($files as $f){
$path = $dest.'/'.substr($f,strlen($source));
$file_success += move_file($f,$path,$repeat_add,$repeat_type);
}
foreach($dirs as $f){
@rmdir($f);
}
@rmdir($source);
if($file_success == count($files)){
del_dir($source);
return true;
}
return false;
}
/**
* 创建目录
*
* @param string $dir
* @param int $mode
* @return bool
*/
function mk_dir($dir, $mode = 0777){
if (!$dir) return false;
if (is_dir($dir) || @mkdir($dir, $mode)){
return true;
}
if (!mk_dir(dirname($dir), $mode)){
return false;
}
return @mkdir($dir, $mode);
}
/*
* 获取文件&文件夹列表(支持文件夹层级)
* path : 文件夹 $dir ——返回的文件夹array files ——返回的文件array
* $deepest 是否完整递归;$deep 递归层级
*/
function recursion_dir($path,&$dir,&$file,$deepest=-1,$deep=0){
$path = rtrim($path,'/').'/';
if (!is_array($file)) $file=array();
if (!is_array($dir)) $dir=array();
if (!$dh = opendir($path)) return false;
while(($val=readdir($dh)) !== false){
if ($val=='.' || $val=='..') continue;
$value = strval($path.$val);
if (is_file($value)){
$file[] = $value;
}else if(is_dir($value)){
$dir[]=$value;
if ($deepest==-1 || $deep<$deepest){
recursion_dir($value."/",$dir,$file,$deepest,$deep+1);
}
}
}
closedir($dh);
return true;
}
function dir_list($path){
recursion_dir($path,$dirs,$files);
return array_merge($dirs,$files);
}
// 安全读取文件,避免并发下读取数据为空
function file_read_safe($file,$timeout = 3){
if(!$file || !file_exists($file)) return false;
$fp = @fopen($file, 'r');
if(!$fp) return false;
$startTime = microtime(true);
do{
$locked = flock($fp, LOCK_SH);//LOCK_EX|LOCK_NB
if(!$locked){
usleep(mt_rand(1, 50) * 1000);//1~50ms;
}
} while((!$locked) && ((microtime(true) - $startTime) < $timeout ));//设置超时时间
if($locked && filesize($file) >=0 ){
$result = @fread($fp, filesize($file));
flock($fp,LOCK_UN);
fclose($fp);
if(filesize($file) == 0){
return '';
}
return $result;
}else{
flock($fp,LOCK_UN);fclose($fp);
return false;
}
}
// 安全读取文件,避免并发下读取数据为空
function file_wirte_safe($file,$buffer,$timeout=3){
clearstatcache();
if(strlen($file) == 0 || !$file || !file_exists($file)) return false;
$fp = fopen($file,'r+');
$startTime = microtime(true);
do{
$locked = flock($fp, LOCK_EX);//LOCK_EX
if(!$locked){
usleep(mt_rand(1, 50) * 1000);//1~50ms;
}
} while((!$locked) && ((microtime(true) - $startTime) < $timeout ) );//设置超时时间
if($locked){
$tempFile = $file.'.temp';
$result = file_put_contents($tempFile,$buffer,LOCK_EX);//验证是否还能写入;避免磁盘空间满的情况
if(!$result || !file_exists($tempFile) ){
flock($fp,LOCK_UN);fclose($fp);
return false;
}
@unlink($tempFile);
ftruncate($fp,0);
rewind($fp);
$result = fwrite($fp,$buffer);
flock($fp,LOCK_UN);fclose($fp);
clearstatcache();
return $result;
}else{
flock($fp,LOCK_UN);fclose($fp);
return false;
}
}
/*
* $search 为包含的字符串
* is_content 表示是否搜索文件内容;默认不搜索
* is_case 表示区分大小写,默认不区分
*/
function path_search($path,$search,$is_content=false,$file_ext='',$is_case=false){
$result = array();
$result['fileList'] = array();
$result['folderList'] = array();
if(!$path) return $result;
$ext_arr = explode("|",$file_ext);
recursion_dir($path,$dirs,$files,-1,0);
$strpos = 'stripos';//是否区分大小写
if ($is_case) $strpos = 'strpos';
$result_num = 0;
$result_num_max = 2000;//搜索文件内容,限制最多匹配条数
foreach($files as $f){
if($result_num >= $result_num_max){
$result['error_info'] = $result_num_max;
break;
}
//若指定了扩展名则只在匹配扩展名文件中搜索
$ext = get_path_ext($f);
if($file_ext != '' && !in_array($ext,$ext_arr)){
continue;
}
//搜索内容则不搜索文件名
if ($is_content) {
if(!is_text_file($ext)) continue; //在限定中或者不在bin中
$search_info = file_search($f,$search,$is_case);
if($search_info !== false){
$result_num += count($search_info['searchInfo']);
$result['fileList'][] = $search_info;
}
}else{
$path_this = get_path_this($f);
if ($strpos($path_this,iconv_system($search)) !== false){//搜索文件名;
$result['fileList'][] = file_info($f);
$result_num ++;
}
}
}
if (!$is_content && $file_ext == '' ) {//没有指定搜索文件内容,且没有限定扩展名,才搜索文件夹
foreach($dirs as $f){
$path_this = get_path_this($f);
if ($strpos($path_this,iconv_system($search)) !== false){
$result['folderList'][]= array(
'name' => iconv_app(get_path_this($f)),
'path' => iconv_app($f)
);
}
}
}
return $result;
}
// 文件搜索;返回行及关键词附近行
// 优化搜索算法 提高100被性能
function file_search($path,$search,$is_case){
$strpos = 'stripos';//是否区分大小写
if ($is_case) $strpos = 'strpos';
//文本文件 超过40M不再搜索
if(@filesize($path) >= 1024*1024*40){
return false;
}
$content = file_get_contents($path);
if( $strpos($content,"\0") > 0 ){// 不是文本文档
unset($content);
return false;
}
$charset = get_charset($content);
//搜索关键字为纯英文则直接搜索含有中文则转为utf8再搜索为兼容其他文件编码格式
$notAscii = preg_match("/[\x7f-\xff]/", $search);
if($notAscii && !in_array($charset,array('utf-8','ascii'))){
$content = iconv_to($content,$charset,'utf-8');
}
//文件没有搜索到目标直接返回
if ($strpos($content,$search) === false){
unset($content);
return false;
}
$pose = 0;
$file_size = strlen($content);
$arr_search = array(); // 匹配结果所在位置
while ( $pose !== false) {
$pose = $strpos($content,$search, $pose);
if($pose !== false){
$arr_search[] = $pose;
$pose ++;
}else{
break;
}
}
$arr_line = array();
$pose = 0;
while ( $pose !== false) {
$pose = strpos($content, "\n", $pose);
if($pose !== false){
$arr_line[] = $pose;
$pose ++;
}else{
break;
}
}
$arr_line[] = $file_size;//文件只有一行而且没有换行,则构造虚拟换行
$result = array();// [2,10,22,45,60] [20,30,40,50,55]
$len_search = count($arr_search);
$len_line = count($arr_line);
for ($i=0,$line=0; $i < $len_search && $line < $len_line; $line++) {
while ( $arr_search[$i] <= $arr_line[$line]) {
//行截取字符串
$cur_pose = $arr_search[$i];
$from = $line == 0 ? 0:$arr_line[$line-1];
$to = $arr_line[$line];
$len_max = 300;
if( $to - $from >= $len_max){ //长度过长处理
$from = $cur_pose - 20;
$from = $from <= 0 ? 0 : $from;
$to = $from + $len_max;
//中文避免截断;(向前 向后找到分隔符后终止)
$token = array("\r","\n"," ","\t",",","/","#","_","[","]","(",")","+","-","*","/","=","&");
while (!in_array($content[$from],$token) && $from >= 0) {
$from -- ;
}
while (!in_array($content[$to],$token) && $to <= $file_size) {
$to ++ ;
}
}
$line_str = substr($content,$from,$to - $from);
if($strpos($line_str,$search) === false){ //截取乱码避免
$line_str = $search;
}
$result[] = array('line'=>$line+1,'str'=>$line_str);
if(++$i >= $len_search ){
break;
}
}
}
$info = file_info($path);
$info['searchInfo'] = $result;
unset($content);
return $info;
}
/**
* 修改文件、文件夹权限
* @param $path 文件(夹)目录
* @return :string
*/
function chmod_path($path,$mod){
if (!isset($mod)) $mod = 0777;
if (!file_exists($path)) return false;
if (is_file($path)) return @chmod($path,$mod);
if (!$dh = @opendir($path)) return false;
while (($file = readdir($dh)) !== false){
if ($file =='.' || $file =='..') continue;
$fullpath = $path . '/' . $file;
chmod_path($fullpath,$mod);
@chmod($fullpath,$mod);
}
closedir($dh);
return @chmod($path,$mod);
}
/**
* 文件大小格式化
*
* @param $ :$bytes, int 文件大小
* @param $ :$precision int 保留小数点
* @return :string
*/
function size_format($bytes, $precision = 2){
if ($bytes == 0) return "0 B";
$unit = array(
'TB' => 1099511627776, // pow( 1024, 4)
'GB' => 1073741824, // pow( 1024, 3)
'MB' => 1048576, // pow( 1024, 2)
'kB' => 1024, // pow( 1024, 1)
'B ' => 1, // pow( 1024, 0)
);
foreach ($unit as $un => $mag) {
if (doubleval($bytes) >= $mag)
return round($bytes / $mag, $precision).' '.$un;
}
}
/**
* 判断路径是不是绝对路径
* 返回true('/foo/bar','c:\windows').
*
* @return 返回true则为绝对路径否则为相对路径
*/
function path_is_absolute($path){
if (realpath($path) == $path)// *nux 的绝对路径 /home/my
return true;
if (strlen($path) == 0 || $path[0] == '.')
return false;
if (preg_match('#^[a-zA-Z]:\\\\#', $path))// windows 的绝对路径 c:\aaa\
return true;
return (bool)preg_match('#^[/\\\\]#', $path); //绝对路径 运行 / 和 \绝对路径,其他的则为相对路径
}
function is_text_file($ext){
$ext_arr = array(
"txt","textile",'oexe','inc','csv','log','asc','tsv','lnk','url','webloc','meta',"localized",
"xib","xsd","storyboard","plist","csproj","pch","pbxproj","local","xcscheme","manifest","vbproj",
"strings",'jshintrc','sublime-project','readme','changes',"changelog",'version','license','changelog',
"abap","abc","as","asp",'aspx',"ada","adb","htaccess","htgroups","htgroups",
"htpasswd","asciidoc","adoc","asm","a","ahk","bat","cmd","cpp","c","cc","cxx","h","hh","hpp",
"ino","c9search_results","cirru","cr","clj","cljs","cbl","cob","coffee","cf","cson","cakefile",
"cfm","cs","css","curly","d","di","dart","diff","patch","dockerfile","dot","dummy","dummy","e",
"ge","ejs","ex","exs","elm","erl","hrl","frt","fs","ldr","ftl","gcode","feature",".gitignore",
"glsl","frag","vert","gbs","go","groovy","haml","hbs","handlebars","tpl","mustache","hs","hx",
"html","hta","htm","xhtml","eex","html.eex","erb","rhtml","html.erb","ini",'inf',"conf","cfg","prefs","io",
"jack","jade","java","ji","jl","jq","js","jsm","json","jsp","jsx","latex","ltx","bib",
"lean","hlean","less","liquid","lisp","ls","logic","lql","lsl","lua","lp","lucene","Makefile","makemakefile",
"gnumakefile","makefile","ocamlmakefile","make","md","markdown","mask","matlab","mz","mel",
"mc","mush","mysql","nix","nsi","nsh","m","mm","ml","mli","pas","p","pl","pm","pgsql","php",
"phtml","shtml","php3","php4","php5","phps","phpt","aw","ctp","module","ps1","praat",
"praatscript","psc","proc","plg","prolog","properties","proto","py","r","cshtml","rd",
"rhtml","rst","rb","ru","gemspec","rake","guardfile","rakefile","gemfile","rs","sass",
"scad","scala","scm","sm","rkt","oak","scheme","scss","sh","bash","bashrc","sjs","smarty",
"tpl","snippets","soy","space","sql","sqlserver","styl","stylus","svg","swift","tcl","tex",
"toml","twig","swig","ts","typescript","str","vala","vbs","vb","vm","v","vh",
"sv","svh","vhd","vhdl","wlk","wpgm","wtest","xml","rdf","rss","wsdl","xslt","atom","mathml",
"mml","xul","xbl","xaml","xq","yaml","yml",
"cer","reg","config"
);
if(in_array($ext,$ext_arr)){
return true;
}else{
return false;
}
}
/**
* 输出、文件下载,断点续传支持
* 默认以附件方式下载;$download为false时则为输出文件
* 视频播放拖拽:流媒体服务器
* 文件缓存http://blog.csdn.net/eroswang/article/details/8302191
*/
function file_put_out($file,$download=-1,$downFilename=false){
$error = false;
if (!file_exists($file)){
$error = 'file not exists';
}else if (!path_readable($file)){
$error = 'file not readable';
}else if (!$fp = @fopen($file, "rb")){
$error = 'file open error!';
}
if($error !== false){
if($downFilename === false){
return;
}else{
show_json($error,false);
}
}
$start= 0;
$file_size = get_filesize($file);
$end = $file_size - 1;
@ob_end_clean();
@set_time_limit(0);
$time = gmdate('D, d M Y H:i:s',filemtime($file));
$filename = get_path_this($file);
if($downFilename !== false){
$filename = $downFilename;
}
$mime = get_file_mime(get_path_ext($filename));
if ($download === -1 && !mime_support($mime)){
$download = true;
}
$headerName = rawurlencode(iconv_app($filename));
$headerName = '"'.$headerName."\"; filename*=utf-8''".$headerName;
if ($download) {
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment;filename='.$headerName);
}else{
header('Content-Type: '.$mime);
//header('Content-Disposition: inline;filename='.$headerName);
if(strstr($mime,'text/')){
//$charset = get_charset(file_get_contents($file));
header('Content-Type: '.$mime.'; charset=');//避免自动追加utf8导致gbk网页乱码
}
}
//缓存文件
header('Expires: '.gmdate('D, d M Y H:i:s',time()+3600*24*20).' GMT');
header('Cache-Pragma: public');
header('Pragma: public');
header('Cache-Control: cache, must-revalidate');
if (isset($_SERVER['If-Modified-Since']) &&
(strtotime($_SERVER['If-Modified-Since']) == filemtime($file))) {
header('304 Not Modified', true, 304);
exit;
}
$etag = '"'.md5($time.$file_size).'"';
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag){
header("Etag: ".$etag, true, 304);
exit;
}
header('Etag: '.$etag);
header('Last-Modified: '.$time.' GMT');
header("X-OutFileName: ".$filename);
header("X-Powered-By: kodExplorer.");
header("X-FileSize: ".$file_size);
// 过滤svg中非法script内容; 避免xxs;
if(!$download && get_path_ext($filename) == 'svg'){
if($file_size > 1024*1024*5) {exit;}
$content = file_get_contents($file);
$content = removeXXS($content);
echo $content;exit;
}
//远程路径不支持断点续传打开zip内部文件
if(!file_exists($file)){
header('HTTP/1.1 200 OK');
header('Content-Length: '.($end+1));
return;
}
//调用webserver下载
$server = strtolower($_SERVER['SERVER_SOFTWARE']);
if($server && $GLOBALS['config']['settings']['httpSendFile']){
if(strstr($server,'nginx')){//nginx
header("X-Accel-Redirect: ".$file);
}else if(strstr($server,'apache')){ //apache
header('X-Sendfile: '.$file);
}else if(strstr($server,'http')){//light http
header( "X-LIGHTTPD-send-file: " . $file);
}
return;
}
header("Accept-Ranges: bytes");
if (isset($_SERVER['HTTP_RANGE'])){
if (preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)){
$start = intval($matches[1]);
if (!empty($matches[2])){
$end = intval($matches[2]);
}
}
header('HTTP/1.1 206 Partial Content');
}else{
header('HTTP/1.1 200 OK');
}
if(isset($_GET['start'])){//flash video
$start = intval($_GET['start']);
}
header('Content-Length:' . (($end - $start) + 1));
if (isset($_SERVER['HTTP_RANGE']) || isset($_GET['start'])){
header("Content-Range: bytes $start-$end/".$file_size);
}
//输出文件
$cur = $start;
fseek($fp, $start,0);
while(!feof($fp) && $cur <= $end){ // && (connection_status() == 0)
print fread($fp, min(1024 * 200, ($end - $cur) + 1));
$cur += 1024 *200;
flush();
}
fclose($fp);
}
function removeXXS($val){
$val = preg_replace('/([\x00-\x08\x0b-\x0c\x0e-\x19])/', '', $val);
$search = 'abcdefghijklmnopqrstuvwxyz';
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$search .= '1234567890!@#$%^&*()';
$search .= '~`";:?+/={}[]-_|\'\\';
for ($i = 0; $i < strlen($search); $i++) {
// ;? matches the ;, which is optional
// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
// @ @ search for the hex values
$val = preg_replace('/(&#[xX]0{0,8}' . dechex(ord($search[$i])) . ';?)/i', $search[$i], $val); // with a ;
// @ @ 0{0,7} matches '0' zero to seven times
$val = preg_replace('/(&#0{0,8}' . ord($search[$i]) . ';?)/', $search[$i], $val); // with a ;
}
// now the only remaining whitespace attacks are \t, \n, and \r
$ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
$ra1 = array('javascript', 'vbscript', 'expression','script');// 过多,误判
$ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
$ra = array_merge($ra1, $ra2);
$found = true; // keep replacing as long as the previous round replaced something
while ($found == true) {
$val_before = $val;
for ($i = 0; $i < sizeof($ra); $i++) {
$pattern = '/';
for ($j = 0; $j < strlen($ra[$i]); $j++) {
if ($j > 0) {
$pattern .= '(';
$pattern .= '(&#[xX]0{0,8}([9ab]);)';
$pattern .= '|';
$pattern .= '|(&#0{0,8}([9|10|13]);)';
$pattern .= ')*';
}
$pattern .= $ra[$i][$j];
}
$pattern .= '/i';
$replacement = substr($ra[$i], 0, 2) . '_' . substr($ra[$i], 2); // add in <> to nerf the tag
$val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
if ($val_before == $val) {
// no replacements were made, so exit the loop
$found = false;
}
}
}
return $val;
}
/**
* 远程文件下载到服务器
* 支持fopen的打开都可以支持本地、url
*/
function file_download_this($from, $fileName,$headerSize=0){
@set_time_limit(0);
$fileTemp = $fileName.'.downloading';
if ($fp = @fopen ($from, "rb")){
if(!$downloadFp = @fopen($fileTemp, "wb")){
return false;
}
while(!feof($fp)){
if(!file_exists($fileTemp)){//删除目标文件;则终止下载
fclose($downloadFp);
return false;
}
//对于部分fp不结束的通过文件大小判断
clearstatcache();
if( $headerSize>0 &&
$headerSize==get_filesize(iconv_system($fileTemp))
){
break;
}
fwrite($downloadFp, fread($fp, 1024 * 200 ), 1024 * 200);
}
//下载完成,重命名临时文件到目标文件
fclose($downloadFp);
fclose($fp);
if(!@rename($fileTemp,$fileName)){
unlink($fileName);
return rename($fileTemp,$fileName);
}
return true;
}else{
return false;
}
}
/**
* 获取文件(夹)权限 rwx_rwx_rwx
*/
function get_mode($file){
$Mode = @fileperms($file);
$theMode = ' '.decoct($Mode);
$theMode = substr($theMode,-4);
$Owner = array();$Group=array();$World=array();
if ($Mode &0x1000) $Type = 'p'; // FIFO pipe
elseif ($Mode &0x2000) $Type = 'c'; // Character special
elseif ($Mode &0x4000) $Type = 'd'; // Directory
elseif ($Mode &0x6000) $Type = 'b'; // Block special
elseif ($Mode &0x8000) $Type = '-'; // Regular
elseif ($Mode &0xA000) $Type = 'l'; // Symbolic Link
elseif ($Mode &0xC000) $Type = 's'; // Socket
else $Type = 'u'; // UNKNOWN
// Determine les permissions par Groupe
$Owner['r'] = ($Mode &00400) ? 'r' : '-';
$Owner['w'] = ($Mode &00200) ? 'w' : '-';
$Owner['x'] = ($Mode &00100) ? 'x' : '-';
$Group['r'] = ($Mode &00040) ? 'r' : '-';
$Group['w'] = ($Mode &00020) ? 'w' : '-';
$Group['e'] = ($Mode &00010) ? 'x' : '-';
$World['r'] = ($Mode &00004) ? 'r' : '-';
$World['w'] = ($Mode &00002) ? 'w' : '-';
$World['e'] = ($Mode &00001) ? 'x' : '-';
// Adjuste pour SUID, SGID et sticky bit
if ($Mode &0x800) $Owner['e'] = ($Owner['e'] == 'x') ? 's' : 'S';
if ($Mode &0x400) $Group['e'] = ($Group['e'] == 'x') ? 's' : 'S';
if ($Mode &0x200) $World['e'] = ($World['e'] == 'x') ? 't' : 'T';
$Mode = $Type.$Owner['r'].$Owner['w'].$Owner['x'].' '.
$Group['r'].$Group['w'].$Group['e'].' '.
$World['r'].$World['w'].$World['e'];
return $Mode.'('.$theMode.')';
}
/**
* 获取可以上传的最大值
* return * byte
*/
function get_post_max(){
$upload = ini_get('upload_max_filesize');
$upload = $upload==''?ini_get('upload_max_size'):$upload;
$post = ini_get('post_max_size');
$upload = intval($upload)*1024*1024*0.8;
$post = intval($post)*1024*1024*0.8;
$the_max = $upload<$post?$upload:$post;
return $the_max==0?1024*1024*0.5:$the_max;//获取不到则500k
}
function path_clear($path){
$path = str_replace('\\','/',trim($path));
$path = preg_replace('/\/+/', '/', $path);
if (strstr($path,'../')) {
$path = preg_replace('/\/\.+\//', '/', $path);
}
return $path;
}
function path_clear_name($path){
$path = str_replace('\\','/',trim($path));
$path = str_replace('/','.',trim($path));
return $path;
}
// 兼容move_uploaded_file 和 流的方式上传
function kod_move_uploaded_file($fromPath,$savePath){
$tempPath = $savePath.'.parttmp';
if($fromPath == "base64"){
@file_put_contents($tempPath,base64_decode($_POST['file']));
}else if($fromPath == "php://input"){
$in = @fopen($fromPath, "rb");
$out = @fopen($tempPath, "wb");
if(!$in || !$out) return false;
while (!feof($in)) {
fwrite($out, fread($in, 1024*200));
}
fclose($in);
fclose($out);
}else{
if(!move_uploaded_file($fromPath,$tempPath)){
show_json('move uploaded file error!',false);
}
}
if(!$result = rename($tempPath,$savePath)){
del_file($savePath);
$result = rename($tempPath,$savePath);
}
chmod_path($savePath,DEFAULT_PERRMISSIONS);
return $result;
}
function check_upload($error){
$status = array(
'UPLOAD_ERR_OK', //0 没有错误发生,文件上传成功。
'UPLOAD_ERR_INI_SIZE', //1 上传的文件超过了php.ini 中 upload_max_filesize 选项限制的值。
'UPLOAD_ERR_FORM_SIZE', //2 上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
'UPLOAD_ERR_PARTIAL', //3 文件只有部分被上传。
'UPLOAD_ERR_NO_FILE', //4 没有文件被上传。
'UPLOAD_UNKNOW', //5 未定义
'UPLOAD_ERR_NO_TMP_DIR',//6 找不到临时文件夹。php 4.3.10 和 php 5.0.3 引进。
'UPLOAD_ERR_CANT_WRITE',//7 文件写入失败。php 5.1.0 引进。
);
return $error.':'.$status[$error];
}
//拍照上传
function updload_ios_check($fileName,$in){
if(!is_wap()) return $fileName;
$time = strtotime($in['lastModifiedDate']);
$time = $time ? $time : time();
$beforeName = strtolower($fileName);
if($beforeName == "image.jpg" || $beforeName == "image.jpeg"){
$fileName = date('Ymd',$time).'_'.$in['size'].'.jpg';
}else if($beforeName == "capturedvideo.mov"){
$fileName = date('Ymd',$time).'_'.$in['size'].'.mov';
}
return $fileName;
}
/**
* 文件上传处理。大文件支持分片上传
* upload('file','D:/www/');
*
* post上传base64Upload=1;file=base64str;name=filename
*/
function upload($path,$tempPath,$repeatAction='replace'){
ignore_timeout();
global $in;
$fileInput = 'file';
$fileName = "";
if (!empty($_FILES)) {
$fileName = iconv_system(path_clear_name($_FILES[$fileInput]["name"]));
$uploadFile = $_FILES[$fileInput]["tmp_name"];
if(!$uploadFile && $_FILES[$fileInput]['error']>0){
show_json(check_upload($_FILES[$fileInput]['error']),false);
}
$fileName = updload_ios_check($fileName,$in);//拍照上传
}else if (isset($in["name"])) {
$fileName = iconv_system(path_clear_name($in["name"]));
$uploadFile = "php://input";
if(isset($in['base64Upload'])){
$uploadFile = "base64";
}
$fileName = updload_ios_check($fileName,$in);//拍照上传
}else if( isset($in["check_md5"]) ) {//断点续传检测
$fileName = iconv_system(path_clear_name($in["name"]));
$savePath = get_filename_auto($path.$fileName,""); //自动重命名
return upload_chunk("--check_md5--",$tempPath,$savePath);
}else{
show_json('param error',false);
}
//正常上传
$savePath = get_filename_auto($path.$fileName,"",$repeatAction); //自动重命名
Hook::trigger('uploadFileBefore',$savePath);
if($savePath === false){
show_json('upload_exist_skip',false);
}
$chunks = isset($in["chunks"]) ? intval($in["chunks"]) : 1;
if ($chunks > 1) {//并发上传,不一定有前后顺序
return upload_chunk($uploadFile,$tempPath,$savePath);
}
if(kod_move_uploaded_file($uploadFile,$savePath)){
Hook::trigger('uploadFileAfter',$savePath);
show_json('upload_success',true,iconv_app(_DIR_OUT($savePath)));
}else {
show_json('move_error',false);
}
}
/**
* 简易文件hash获取;替代md5_file;
* md5(文件头6字节+中间6字节+结尾6字节)
*/
function file_hash_simple($file){
$fileSize = filesize($file);
$sliceLength = 6;
if($fileSize <= $sliceLength){
$sliceString = file_get_contents($file);
}else{
$fp = fopen($file,'r');
$sliceString = fread($fp,$sliceLength);
fseek($fp,($fileSize-$sliceLength)/2);
$sliceString .= fread($fp,$sliceLength);
fseek($fp,$fileSize-$sliceLength);
$sliceString .= fread($fp,$sliceLength);
fclose($fp);
}
$hash = $fileSize;
for ($i=0; $i < strlen($sliceString); $i++) {
$hash = $hash.",".ord($sliceString[$i]);
}
return md5($hash);
}
function upload_chunk($uploadFile,$tempPath,$savePath){
global $in;
$chunk = isset($in["chunk"]) ? intval($in["chunk"]) : 0;
$chunks = isset($in["chunks"]) ? intval($in["chunks"]) : 1;
$check_md5 = isset($in["check_md5"]) ? $in["check_md5"] : false;
//if(mt_rand(0, 100) > 10) die("server error".$chunk); //模拟失败
//文件分块检测是否已上传,已上传则忽略;断点续传
if($check_md5 !== false){
$chunk_file_pre = $tempPath.md5($savePath).'.part';
$chunk_file = $chunk_file_pre.$chunk;
if( file_exists($chunk_file) && file_hash_simple($chunk_file) == $check_md5){
$arr = array();
for($index = 0; $index<$chunks; $index++ ){
if(file_exists($chunk_file_pre.$index)){
$arr['part_'.$index] = file_hash_simple($chunk_file_pre.$index);
}
}
show_json('success',true,$arr);
}else{
show_json('not_exists',false);
}
}
$tempFilePre = $tempPath.md5($savePath).'.part';
if(kod_move_uploaded_file($uploadFile, $tempFilePre.$chunk)){
$done = true;
//优化分片存在判断;当分片太多时,每个分片都全量判断,会占用服务器资源及影响上传速度;
$fromIndex = 0;
$existMaxFile = $tempFilePre.'.max';//记录连续存在文件的最大序号
if(file_exists($existMaxFile)){
$fromIndex = intval(file_get_contents($fromIndex));
}else{
file_put_contents($existMaxFile,$fromIndex);
}
for($index = $fromIndex; $index<$chunks; $index++ ){
if (!file_exists($tempFilePre.$index)) {
if($index-1 > $fromIndex){
file_put_contents($existMaxFile,$index-1);
}
$done = false;
break;
}
}
if (!$done){
show_json('upload_success',true);
}else{
$savePathTemp = $tempFilePre.mtime();
if(!$out = fopen($savePathTemp, "wb")){
show_json('no_permission_write',false);
}
if (!flock($out, LOCK_EX)) {
show_json('lock dist move error',false);
}else{
for( $index = 0; $index < $chunks; $index++ ) {
$chunk_file = $tempFilePre.$index;
if (!$fp_in = @fopen($chunk_file,"rb")){//并发情况下另一个访问时文件已删除
flock($out, LOCK_UN);
fclose($out);
unlink($savePathTemp);
show_json('open chunk error! cur='.$chunk.';index='.$index,false);
}
while (!feof($fp_in)) {
fwrite($out, fread($fp_in,1024*200));
}
fclose($fp_in);
unlink($chunk_file);
}
flock($out, LOCK_UN);
fclose($out);
}
}
unlink($existMaxFile);
$res = rename($savePathTemp,$savePath);
if(!$res){
unlink($savePath);
$res = rename($savePathTemp,$savePath);
if(!$res){
show_json('move(rename) dist file error!',false);
}
}
Hook::trigger('uploadFileAfter',$savePath);
show_json('upload_success',true,iconv_app(_DIR_OUT($savePath)));
}else {
show_json('move_error',false);
}
}
/**
* 写日志
* @param string $log 日志信息
* @param string $type 日志类型 [system|app|...]
* @param string $level 日志级别
* @return boolean
*/
function write_log($log, $type = 'default', $level = 'log'){
if(!defined('LOG_PATH')){
return;
}
list($usec, $sec) = explode(' ', microtime());
$now_time = date('[H:i:s.').substr($usec,2,3).'] ';
$target = LOG_PATH . strtolower($type) . '/';
mk_dir($target);
if (!path_writeable($target)){
exit('path can not write!');
}
$ext = '.php';//.php .log;
$target .= date('Y_m_d').'__'.$level.$ext;
//检测日志文件大小, 超过配置大小则重命名
if (file_exists($target) && get_filesize($target) >= 1024*1024*10) {
$fileName = substr(basename($target),0,strrpos(basename($target),$ext)).date('H:i:s').$ext;
rename($target, dirname($target) .'/'. $fileName);
}
if(!file_exists($target)){
error_log("<?php exit;?>\n", 3,$target);
}
if(is_object($log) || is_array($log)){
$log = json_encode_force($log);
}
clearstatcache();
return error_log("$now_time $log\n", 3, $target);
}