php版照片按拍照日期归类整理源码
- php版照片按拍照日期归类整理源码
- 以年-月为目录进行归类
- 跳过重复文件
- 视频文件、非图片文件单独归类
- 读不到日期的照片单独归类
<?php /* 2014/4/1 17:27 klggg 照片按拍照日期整理 依赖 php_exif 扩展 win下打开扩展 extension=php_exif.dll ; 注,这段必须放在 extension=php_mbstring.dll 下面*/date_default_timezone_set('PRC');//require dirname(__FILE__).'/vendor/autoload.php';$curr_dir_path = dirname(__FILE__); //要处理的照片来源路径 * 需要针对自己的情况做下修改$photo_source_path = 'K:/家庭照片';$config = array( 'fileExtension' => 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); } }

Ce qui est encore populaire, c'est la facilité d'utilisation, la flexibilité et un écosystème fort. 1) La facilité d'utilisation et la syntaxe simple en font le premier choix pour les débutants. 2) étroitement intégré au développement Web, excellente interaction avec les demandes HTTP et la base de données. 3) L'énorme écosystème fournit une multitude d'outils et de bibliothèques. 4) La nature active et la nature open source les adaptent à de nouveaux besoins et tendances technologiques.

PHP et Python sont tous deux des langages de programmation de haut niveau qui sont largement utilisés dans le développement Web, le traitement des données et les tâches d'automatisation. 1.Php est souvent utilisé pour créer des sites Web dynamiques et des systèmes de gestion de contenu, tandis que Python est souvent utilisé pour créer des cadres Web et une science des données. 2.PHP utilise Echo pour sortir du contenu, Python utilise l'impression. 3. Les deux prennent en charge la programmation orientée objet, mais la syntaxe et les mots clés sont différents. 4. PHP prend en charge la conversion de type faible, tandis que Python est plus strict. 5. L'optimisation des performances PHP comprend l'utilisation de la programmation OPCACH et asynchrone, tandis que Python utilise la programmation CPROFILE et asynchrone.

PHP est principalement la programmation procédurale, mais prend également en charge la programmation orientée objet (POO); Python prend en charge une variété de paradigmes, y compris la POO, la programmation fonctionnelle et procédurale. PHP convient au développement Web, et Python convient à une variété d'applications telles que l'analyse des données et l'apprentissage automatique.

PHP est originaire en 1994 et a été développé par Rasmuslerdorf. Il a été utilisé à l'origine pour suivre les visiteurs du site Web et a progressivement évolué en un langage de script côté serveur et a été largement utilisé dans le développement Web. Python a été développé par Guidovan Rossum à la fin des années 1980 et a été publié pour la première fois en 1991. Il met l'accent sur la lisibilité et la simplicité du code, et convient à l'informatique scientifique, à l'analyse des données et à d'autres domaines.

PHP convient au développement Web et au prototypage rapide, et Python convient à la science des données et à l'apprentissage automatique. 1.Php est utilisé pour le développement Web dynamique, avec une syntaxe simple et adapté pour un développement rapide. 2. Python a une syntaxe concise, convient à plusieurs champs et a un écosystème de bibliothèque solide.

PHP reste important dans le processus de modernisation car il prend en charge un grand nombre de sites Web et d'applications et d'adapter les besoins de développement via des cadres. 1.Php7 améliore les performances et introduit de nouvelles fonctionnalités. 2. Des cadres modernes tels que Laravel, Symfony et Codeigniter simplifient le développement et améliorent la qualité du code. 3. L'optimisation des performances et les meilleures pratiques améliorent encore l'efficacité de l'application.

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

Le type PHP invite à améliorer la qualité et la lisibilité du code. 1) Conseils de type scalaire: Depuis PHP7.0, les types de données de base sont autorisés à être spécifiés dans les paramètres de fonction, tels que INT, Float, etc. 2) Invite de type de retour: Assurez la cohérence du type de valeur de retour de fonction. 3) Invite de type d'union: Depuis PHP8.0, plusieurs types peuvent être spécifiés dans les paramètres de fonction ou les valeurs de retour. 4) Invite de type nullable: permet d'inclure des valeurs nulles et de gérer les fonctions qui peuvent renvoyer les valeurs nulles.


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

MantisBT
Mantis est un outil Web de suivi des défauts facile à déployer, conçu pour faciliter le suivi des défauts des produits. Cela nécessite PHP, MySQL et un serveur Web. Découvrez nos services de démonstration et d'hébergement.

PhpStorm version Mac
Le dernier (2018.2.1) outil de développement intégré PHP professionnel

Dreamweaver CS6
Outils de développement Web visuel

Listes Sec
SecLists est le compagnon ultime du testeur de sécurité. Il s'agit d'une collection de différents types de listes fréquemment utilisées lors des évaluations de sécurité, le tout en un seul endroit. SecLists contribue à rendre les tests de sécurité plus efficaces et productifs en fournissant facilement toutes les listes dont un testeur de sécurité pourrait avoir besoin. Les types de listes incluent les noms d'utilisateur, les mots de passe, les URL, les charges utiles floues, les modèles de données sensibles, les shells Web, etc. Le testeur peut simplement extraire ce référentiel sur une nouvelle machine de test et il aura accès à tous les types de listes dont il a besoin.

SublimeText3 version chinoise
Version chinoise, très simple à utiliser