如何使用PHP备份数据库并定时发送到指定邮箱

背景:对于个人站长而言,在玩票或者初期建站阶段我们通常会使用免费的或者成本较低的虚拟空间,那么对于这些比较入门级的服务商而言异地备份往往做的不好,如果发生数据丢失就是灾难性的,博主从2011年接触建站就有过多次切肤之痛。那么这时候我们就需要考虑如何自己来备份数据,由于个人建站对于web程序基本是没有改动的(往往使用知名的开源程序),其实对于我们而言最为重要的就是数据库的备份了。这里以PHP为例。

准备:所谓做事做全套,这里博主给大家提供全部需要的组件或者资源列表

1.一个虚拟空间,如果已有请看下一条,因为练习需要推荐大家使用卓越主机idc.ac 订购一个免费空间(博主最近发现的一家免空服务商,友情提醒仅推荐测试用途,切勿建立重要站点)

2.一个126或者163账号(主流我们使用的就是QQ和163系的邮箱,但是博主多次测试发现QQ的验证更加恶心现在对于SMTP还增加了额外的授权码机制,对于我们即将使用的PHPMailer组件尤其不友好)

3.PHPMailer组件 https://github.com/PHPMailer/PHPMailer

开始:组件准备好就是编码了。

<?php 
/*@备份数据库*/
$host = "localhost"; //数据库地址
$dbname = "chenji110"; //数据库名称
$user = "chenji110"; //数据库账号
$password = "pvPR38bzBQ"; //数据库密码
$sendmail = "chenjiesuper123@126.com"; //发件邮箱
$mailpassword = "fdafsaf"; //发件邮箱密码
$sendmailname = "backup-it-database"; //发件人昵称
$inbox ="chenjiesuper123@163.com"; //收件邮箱
// 到这里为止,请不要随意修改下面的代码
if (!mysql_connect($host, $user, $password)) // 连接mysql数据库
    {
        echo '数据库连接失败,请核对后再试';
    exit;
} 
if (!mysql_select_db($dbname)) // 是否存在该数据库
    {
        echo '不存在数据库:' . $dbname . ',请核对后再试';
    exit;
} 
mysql_query("set names 'utf8'");
//$mysql = "set charset utf8;\r\n"; 在WordPress中,加入改行会乱码
$q1 = mysql_query("show tables");
while ($t = mysql_fetch_array($q1))
{
    $table = $t[0];
    $q2 = mysql_query("show create table `$table`");
    $sql = mysql_fetch_array($q2);
    $mysql .= $sql['Create Table'] . ";\r\n";
    $q3 = mysql_query("select * from `$table`");
    while ($data = mysql_fetch_assoc($q3))
    {
        $keys = array_keys($data);
        $keys = array_map('addslashes', $keys);
        $keys = join('`,`', $keys);
        $keys = "`" . $keys . "`";
        $vals = array_values($data);
        $vals = array_map('addslashes', $vals);
        $vals = join("','", $vals);
        $vals = "'" . $vals . "'";
        $mysql .= "insert into `$table`($keys) values($vals);\r\n";
    } 
} 
$filename = $dbname . @date('Ymjgi') . ".sql"; //存放路径,默认存放到项目最外层
$fp = fopen($filename, 'w');
fputs($fp, $mysql);
fclose($fp);
/*@创建一个zip文件*/
function create_zip($files = array(),$destination = ”,$overwrite = false) {
if(file_exists($destination) && !$overwrite){ //检测zip文件是否存在
return false;
}
if(is_array($files)) { //检测文件是否存在
foreach($files as $file) { //循环通过每个文件
if(file_exists($file)) { //确定这个文件存在
$valid_files[] = $file;
}
}
}
if(count($valid_files)) {
$zip = new ZipArchive(); //创建zip文件
if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true){
return false;
}
foreach($valid_files as $file) { //添加文件
$zip->addFile($file,$file);
}
$zip->close();
return file_exists($destination);
} else {
return false;
}
}
$zipfilename=$dbname . @date('Ymjgi') . ".zip";
create_zip(array($filename),$zipfilename,true);//执行压缩文件
/*@发送邮件*/
require("PHPMailer-master/PHPMailerAutoload.php"); //下载的文件必须放在该文件所在目录
$mail = new PHPMailer(); //建立邮件发送类
$mail->IsSMTP(); // 使用SMTP方式发送
$mail->CharSet = "utf-8"; //设置采用utf-8中文编码(内容不会乱码)
$mail->Host = "smtp.126.com"; // 您的企业邮局域名
$mail->Username = $sendmail; // 邮局用户名(请填写完整的email地址)
$mail->Password = $mailpassword; // 邮局密码
$mail->SMTPDebug = 0;
$mail->Port=25;
$mail->SMTPKeepAlive = true;
$mail->SMTPAuth = true; // 启用SMTP验证功能
$mail->From = $sendmail; //邮件发送者email地址
$mail->FromName = $sendmailname;
$mail->AddAddress($inbox, "a");//收件人地址,可以替换成任何想要接收邮件的email信箱,格式是AddAddress("收件人email","收件人姓名")
//$mail->AddReplyTo("", "");
$mail->AddAttachment("$zipfilename"); // 添加附件
//$mail->IsHTML(true); // set email format to HTML //是否使用HTML格式
$mail->Subject = "数据库备份"; //邮件标题
$mail->Body = "数据库备份邮件"; //邮件内容
//$mail->AltBody = "This is the body in plain text for non-HTML mail clients"; //附加信息,可以省略
if(!$mail->Send())
{
echo "邮件发送失败. <p>";
echo "错误原因: " . $mail->ErrorInfo;
exit;
}
echo "邮件发送成功";
/*@删除本地数据库文件sql和zip*/
unlink($filename);
unlink($zipfilename);
?>

这里除了最开始几行大家需要改成自己的数据库,邮箱信息外,还有2行需要特别给大家说下

$mail->SMTPDebug = 0;//这是开启PHPMailer的debug,如果邮件问题可以开启这项,改成1就行了,往往可能是网络问题,大家在遇到问题时打开这个然后去按照报错信息去检索吧。
$mail->Host = "smtp.126.com"; // 您的企业邮局域名,如果是126就是这个,如果是163就把126改成163即可。

部署:编码结束后我们需要把代码保存为PHP文件(例mail.php)然后上传到虚拟空间上。假设我们的域名是mail.com, 那么这时候我们浏览器访问http://mail.com/mail.php即可完成一次数据库的备份发送到邮箱的操作。

定时:上面基本就比较完整了,但是我们发现美中不足,人都是懒的,我们希望能不能定时的触发呢。答案是肯定的。这里推荐几种方案,具体实现就不赘述了。

1.如果你使用Windows 可以设置一个bat文件定时触发访问http://mail.com/mail.php

2.设置你的工作机或者常用计算机主页为http://mail.com/mail.php,但是这种方案需要改造一下代码增加一个每天只发一次的判断标记,不难你邮箱估计很快就被封了。

3.如果你使用的是Linux或者Mac 设置一个crontab 访问http://mail.com/mail.php

4.据我所知阿里云的ace ,新浪的sae都提供了基于自己主机的定时任务机制,配置也很简单。可以搜索参考。

疑问:因为写这篇文章是针对基本没有编码基础的个人站长,如果有一定基础的同学可能会困惑上面的定时是不是考虑使用纯PHP来实现,那么博主经过测试发现在除非是纯CLI状态(基于本文讨论的是虚拟空间,所以我们是没有CLI执行权限的),只要结合了WEB服务器(Nginx ,Apache等)基本是不可行的,即使你使用以下代码其实也是不能真正的忽略PHP的异常和超时。

ignore_user_abort(); // 关掉浏览器,PHP脚本也可以继续执行
set_time_limit(0); // 设置程序的执行时间为无限长

再引用一段官方的解释,相信大家是明白了。

Your web server can have other timeout configurations that may also interrupt PHP execution. Apache has a Timeout directive and IIS has a CGI timeout function. Both default to 300 seconds. See your web server documentation for specific details.

翻译:

你的 web 服务器也可以有其他超时设置,也有可能中断 PHP 的执行。 Apache 有一个 Timeout 指令,IIS 有一个 CGI 超时功能。 他们默认都是 300 秒。更多具体信息参见你的 web 服务器的文档。

最后:对于网站而言数据就是生命,不管怎么样做好数据备份机制还是非常重要的。重要数据务必勤备份。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据