php版照片按拍照日期归类整理源码
php版照片按拍照日期归类整理源码 以年-月为目录进行归类跳过重复文件视频文件、非图片文件单独归类读不到日期的照片单独归类
array( //图片的扩展名 'pic' => array('jpg','png','gif','bmp'), //视频的扩展名 'movies' => array('mov','3gp','mp4') ), 'path' => array( //所有新目录产生的根目录,* 注意修改成自己的路径 'root' => $curr_dir_path.'/pic_new_month' ));$config['path']['pic'] = $config['path']['root'].'/pic'; //照片移到哪个目录$config['path']['movies'] = $config['path']['root'].'/movies'; //视频移到哪个目录$config['path']['unkown'] = $config['path']['root'].'/unkown'; //非照片文件移到哪个目录//初始化log相关$log_path = $config['path']['root'].'/log/';if(!is_dir($log_path)) mkdir($log_path, 0755, true); $log_file = $log_path.'/'.date('y-m-d').'.log';$log_category = 'photomove';$log =null;$log_config = array('locking' => 1,'buffering' => true, 'lineformat' =>'%1$s %2$s [%3$s] %8$s->%7$s %6$s %4$s');if(!defined('pear_log_debug')){ define('pear_log_emerg', 0); /* system is unusable */ define('pear_log_alert', 1); /* immediate action required */ define('pear_log_crit', 2); /* critical conditions */ define('pear_log_err', 3); /* error conditions */ define('pear_log_warning', 4); /* warning conditions */ define('pear_log_notice', 5); /* normal but significant */ define('pear_log_info', 6); /* informational */ define('pear_log_debug', 7); /* debug-level messages */ $log = defaultlog::singleton(file , $log_file,$log_category , $log_config ,pear_log_debug);}else{ $log = log::singleton(file , $log_file,$log_category , $log_config ,pear_log_debug);}$photomove_obj= new photomove($config,$log);$photomove_obj->run($photo_source_path);echo done;class photomove { private $mrootpath= './tmp'; private $logger= null; private $mconfig= array(); public function __construct($config,$logger) { $this->mconfig = $config; $this->mrootpath = $config['path']['root']; foreach($config['path'] as $tmp_path) { if(!is_dir($tmp_path)) mkdir($tmp_path, 0755, true); } $this->logger = $logger; } /** * 运行脚本入口 * @param string $srcpath 照片来源目录 * */ public function run($srcpath) { $it = new recursivedirectoryiterator($srcpath); foreach (new recursiveiteratoriterator($it, 2) as $file_path) { if ($file_path->isdir()) continue; $file_path_name = $file_path->__tostring(); $this->logger->info('file_path_name: '.$file_path_name); $file_info = pathinfo($file_path_name); if('thumbs.db' == strtolower($file_info['basename'])) continue; if(!isset($file_info['extension'])) { $this->logger->notice('no extension : '.$file_path_name); $file_info['extension'] = ''; } $file_info['extension'] = strtolower($file_info['extension']); //找到图片 if(in_array($file_info['extension'],$this->mconfig['fileextension']['pic'])) { $tmp_timestamp = $this->getdatetimeoriginal($file_path_name); //移到新目录 $new_dir = $this->mconfig['path']['pic'].'/'.date('y-m',$tmp_timestamp); if(!is_dir($new_dir)) mkdir($new_dir, 0755, true); $tmp_new_file_path = $new_dir.'/'.$file_info['basename']; $this->move($file_path_name,$tmp_new_file_path); } else if(in_array($file_info['extension'],$this->mconfig['fileextension']['movies'])) { $tmp_new_file_path = $this->mconfig['path']['movies'].'/'.$file_info['basename']; $this->move($file_path_name,$tmp_new_file_path); } else { //非图片文件处理 $this->logger->notice('not image file : '.$file_path_name); $tmp_new_file_path = $this->mconfig['path']['unkown'].'/'.$file_info['basename']; $this->move($file_path_name, $tmp_new_file_path); } } } /** * 取拍照日期 * @param string $filepathname 照片完整路径 * @param string $defaultdatetime 取不到拍照时间时的默认时间 * @return int 返回时间戳 * */ public function getdatetimeoriginal($filepathname,$defaultdatetime='1970:01:01 01:01:01') { $exif = exif_read_data($filepathname, 0, true); $date_time_original = $defaultdatetime; if(empty($exif['exif']) || empty($exif['exif']['datetimeoriginal'])) { $this->logger->warning(empty datetimeoriginal); } else $date_time_original = $exif['exif']['datetimeoriginal']; //string(19) 2011:03:13 10:23:09 $this->logger->info('datetimeoriginal: '.$date_time_original); $tmp_timestamp = strtotime($date_time_original); return $tmp_timestamp; } /** * 移动文件 * @param string $oldfilepath 原文件完整路径 * @param string $newfilepath 目标文件完整路径 * @return bool * */ public function move($oldfilepath,$newfilepath) { //针对已存在的文件 if(file_exists($newfilepath)) { $this->logger->notice(file_exists .$newfilepath); return false; } $result = false;// if($result == copy($oldfilepath, $newfilepath)) if($result == rename($oldfilepath, $newfilepath)) $this->logger->err(rename false, to .$newfilepath ); else $this->logger->info('[ok] move '.$oldfilepath.' to '.$newfilepath); return $result; }}class defaultlog { var $_formatmap = array('%{timestamp}' => '%1$s', '%{ident}' => '%2$s', '%{priority}' => '%3$s', '%{message}' => '%4$s', '%{file}' => '%5$s', '%{line}' => '%6$s', '%{function}' => '%7$s', '%{class}' => '%8$s', '%\{' => '%%{'); var $_lineformat = '%1$s %2$s [%3$s] %4$s'; var $_timeformat = '%b %d %h:%m:%s'; var $_eol = \n; var $_dirmode = 0755; private $_filename= './tmp'; var $_backtrace_depth = 0; public function __construct($name, $ident, $conf, $level='') { $this->_filename = $name; $this->_ident = $ident; if (!empty($conf['lineformat'])) { $this->_lineformat = str_replace(array_keys($this->_formatmap), array_values($this->_formatmap), $conf['lineformat']); } if (!is_dir(dirname($this->_filename))) { mkdir(dirname($this->_filename, $this->_dirmode,true)); } } public static function singleton($handler, $name = '', $ident = '', $conf = array(), $level = pear_log_debug) { static $instances; if (!isset($instances)) $instances = array(); $signature = serialize(array($handler, $name, $ident, $conf, $level)); if (!isset($instances[$signature])) { $instances[$signature] = new self($name, $ident, $conf, $level); } return $instances[$signature]; } function log($message, $priority = null) { /* extract the string representation of the message. */ $message = $this->_extractmessage($message); /* build the string containing the complete log line. */ $line = $this->_format($this->_lineformat, strftime($this->_timeformat), $priority, $message) . $this->_eol; error_log($line, 3,$this->_filename);echo $line; } function emerg($message) { return $this->log($message, pear_log_emerg); } function alert($message) { return $this->log($message, pear_log_alert); } function crit($message) { return $this->log($message, pear_log_crit); } function err($message) { return $this->log($message, pear_log_err); } function warning($message) { return $this->log($message, pear_log_warning); } function notice($message) { return $this->log($message, pear_log_notice); } function info($message) { return $this->log($message, pear_log_info); } function debug($message) { return $this->log($message, pear_log_debug); } function _extractmessage($message) { /* * if we've been given an object, attempt to extract the message using * a known method. if we can't find such a method, default to the * human-readable version of the object. * * we also use the human-readable format for arrays. */ if (is_object($message)) { if (method_exists($message, 'getmessage')) { $message = $message->getmessage(); } else if (method_exists($message, 'tostring')) { $message = $message->tostring(); } else if (method_exists($message, '__tostring')) { $message = (string)$message; } else { $message = var_export($message, true); } } else if (is_array($message)) { if (isset($message['message'])) { if (is_scalar($message['message'])) { $message = $message['message']; } else { $message = var_export($message['message'], true); } } else { $message = var_export($message, true); } } else if (is_bool($message) || $message === null) { $message = var_export($message, true); } /* otherwise, we assume the message is a string. */ return $message; } function _format($format, $timestamp, $priority, $message) { /* * if the format string references any of the backtrace-driven * variables (%5 %6,%7,%8), generate the backtrace and fetch them. */ if (preg_match('/%[5678]/', $format)) { /* plus 2 to account for our internal function calls. */ $d = $this->_backtrace_depth + 2; list($file, $line, $func, $class) = $this->_getbacktracevars($d); } /* * build the formatted string. we use the sprintf() function's * argument swapping capability to dynamically select and position * the variables which will ultimately appear in the log string. */ return sprintf($format, $timestamp, $this->_ident, $this->prioritytostring($priority), $message, isset($file) ? $file : '', isset($line) ? $line : '', isset($func) ? $func : '', isset($class) ? $class : ''); } function prioritytostring($priority) { $levels = array( pear_log_emerg => 'emergency', pear_log_alert => 'alert', pear_log_crit => 'critical', pear_log_err => 'error', pear_log_warning => 'warning', pear_log_notice => 'notice', pear_log_info => 'info', pear_log_debug => 'debug' ); return $levels[$priority]; } function _getbacktracevars($depth) { /* start by generating a backtrace from the current call (here). */ $bt = debug_backtrace(); /* store some handy shortcuts to our previous frames. */ $bt0 = isset($bt[$depth]) ? $bt[$depth] : null; $bt1 = isset($bt[$depth + 1]) ? $bt[$depth + 1] : null; /* * if we were ultimately invoked by the composite handler, we need to * increase our depth one additional level to compensate. */ $class = isset($bt1['class']) ? $bt1['class'] : null; if ($class !== null && strcasecmp($class, 'log_composite') == 0) { $depth++; $bt0 = isset($bt[$depth]) ? $bt[$depth] : null; $bt1 = isset($bt[$depth + 1]) ? $bt[$depth + 1] : null; $class = isset($bt1['class']) ? $bt1['class'] : null; } /* * we're interested in the frame which invoked the log() function, so * we need to walk back some number of frames into the backtrace. the * $depth parameter tells us where to start looking. we go one step * further back to find the name of the encapsulating function from * which log() was called. */ $file = isset($bt0) ? $bt0['file'] : null; $line = isset($bt0) ? $bt0['line'] : 0; $func = isset($bt1) ? $bt1['function'] : null; /* * however, if log() was called from one of our shortcut functions, * we're going to need to go back an additional step. */ if (in_array($func, array('emerg', 'alert', 'crit', 'err', 'warning', 'notice', 'info', 'debug'))) { $bt2 = isset($bt[$depth + 2]) ? $bt[$depth + 2] : null; $file = is_array($bt1) ? $bt1['file'] : null; $line = is_array($bt1) ? $bt1['line'] : 0; $func = is_array($bt2) ? $bt2['function'] : null; $class = isset($bt2['class']) ? $bt2['class'] : null; } /* * if we couldn't extract a function name (perhaps because we were * executed from the main context), provide a default value. */ if ($func === null) { $func = '(none)'; } /* return a 4-tuple containing (file, line, function, class). */ return array($file, $line, $func, $class); } }