PHP 做的文件备份
请看代码:
<?php
/**
* 经过前两次的硬盘突然损坏, 我受到了极大的打击.
* 每次坏了之后, 不单是要买块硬盘, 还要承受数据丢失的痛苦, 前面辛辛苦苦写的代码, 收集的材料, 以及我的各种环境配置, 密码文件都丢了, 很是痛苦.
* 当然了, 还有我的片也没了, 不过这不是重点.
*
* 上面的那些理由让我决定写这么一个小文件来定期做备份, 把日常写的代码, password文件, 通信的密钥, 电子书等都定期备份下,
* 目前只有小文件的备份, 不过平时也都是小文件, 电影神马的丢就丢吧, 也无所谓
* 这样以后即使硬盘坏了也就不会在如这般痛苦了.
*
* 上面都是废话, 本文件仅支持windows平台, 需要和windows的计划任务一起执行.当然稍微修改下在linux应该也没问题.
* 使用之前请先做好相关配置.
*
* # 2012/04/24 发现一个问题, 拷贝到U盘的时候很慢, U盘的IO不行啊, 准备改成先拷贝到本地磁盘, 然后压缩成ZIP然后在拷贝到U盘, 准备实施下看看效果
* 不过需要使用pclzip这个开源的类
* # 算了, 打包还不如直接考过去快呢
*/
define('DS', DIRECTORY_SEPARATOR);
error_reporting(E_ERROR);
set_time_limit(0);
$time = time();
$num = 0;
list($year, $month, $day, $hour, $minute, $seconde) =
explode('-', gmdate("Y-m-d-H-i-s", time()));
$files = array(
'E:/veryImportant/',
'D:/Program Files/Vim/_vimrc',
'D:/cron/',
'E:\AppServ\www\test\\',
'E:\AppServ\www\stat\\',
);
$backupdir = 'I:/backup/';
if(!is_dir($backupdir.$year.$month.$day)) {
mkdir($backupdir.$year.$month.$day);
}
$backupdir = $backupdir.$year.$month.$day.DS;
$backupdir = dir_format($backupdir);
$files = dir_format($files);
foreach($files as $need_to_back_dir) {
if(is_dir($need_to_back_dir)) {
$directory = array_filter(explode(DS, $need_to_back_dir));
$size = count($directory);
$todir = $directory[$size-1];
copy_from_array(filewalk($need_to_back_dir), $need_to_back_dir, $backupdir.$todir.DS);
} else {
copy_from_array(array(str_replace(dirname($need_to_back_dir).DS, '', $need_to_back_dir)), dirname($need_to_back_dir).DS, $backupdir);
}
}
echo "####################\r\ncopy file finished\r\n";
echo time() - $time." second(s).";
echo "\r\n{$num} file(s) copied.";
echo "\r\n####################";
/**
* 替换目录地址中的斜杠, 反斜杠为系统的目录分隔符
* #需要静态变量 DS
* #2012-04-24 10:35 刚刚YY的QQ上线了, 心里好乱啊, 只能眼睁睁的看着, 什么也做不了
* #我连发个消息给她的勇气都没有.
*/
function dir_format($dir) {
if(is_array($dir)) {
foreach($dir as $key => $value) {
$dir[$key] = dir_format($value);
}
} else {
$dir = str_replace('/', DS, $dir);
$dir = str_replace('\\', DS, $dir);
}
return $dir;
}
/**
* 按照数组复制文件
* #如果目标文件存在, 会被覆盖
* #需要静态变脸 DS directory_separator
* @param files 从下面的filewalk的返回值得到的
* @param basedir 复制文件的起始目录
* @param todir 复制到的辣个文件目录
* @return 如果basedir不存或者文件不是数组则返回false
* 如果执行成功然后true
*/
function copy_from_array($files, $basedir, $todir) {
global $num;
if(!is_array($files) || !is_dir($basedir)) {
return false;
}
if(!is_dir($todir)) {
mkdir($todir) || exit('make directory error.');
}
foreach($files as $key => $value) {
if(is_array($value)) {
if(!is_dir($todir.$key)) {
mkdir($todir.$key);
}
if(!copy_from_array($value, $basedir.$key.DS, $todir.$key.DS)) return false;
} else {
copy($basedir.$value, $todir.$value);
$num++;
echo "copy {$basedir}{$value} -> {$todir}{$value}\r\n";
}
}
return true;
}
/**
* 函数:遍历文件夹
* # 静态变量DS为文件目录分隔符
* # 递归函数,请自重
* @dir 要遍历的文件目录
* @return 返回值
* false - 目录读取错误
* array - 文件列表(如果value为数组, 则key为目录名, value为目录下文件;否则value为文件名)
*/
function filewalk($dir) {
if(is_dir($dir)) {
if($handle = opendir($dir)) {
while(false !== ($file = readdir($handle))) {
if($file == '.' || $file == '..') continue;
if(is_dir($dir.DS.$file)) {
$filelist[$file] = filewalk($dir.DS.$file);
} else {
$filelist[] = $file;
}
}
return $filelist;
} else {
return false;
}
} elseif(file_exists($dir)) {
return array($dir);
} else {
return false;
}
}
?>
然后是对应的bat, 做好之后把BAT加到系统的计划任务里就可以了.BAT里就一个命令
php php E:\www\test\cron.php
很easy吧
