这几天在写一个定时备份网站数据的脚本,在写到导出MySQL功能时,想找一个现成的比较好的脚本使用,百度了一下相关的脚本,不是过于复杂,就是有各种错误,而且好多文章都是抄袭。
下面这个我写的脚本,简单实现了MySQL的导出,不适合大型数据库。然而,如果网站数据真大到无法使用这个脚本导出的时候,估计早就用上了独立服务器,也就不缺乏数据备份方案了。
function bzg_backup_tables( $host, $user, $pass, $name, $tables = '*') { if( ! $link = mysql_connect( $host, $user, $pass ) ) return; if( ! mysql_select_db( $name, $link ) ) return; mysql_query("set names 'utf8'"); if( $tables == '*' ) { $tables = array(); $result = mysql_query( 'SHOW TABLES' ); while( $row = mysql_fetch_row( $result ) ) $tables[] = $row[0]; } else { $tables = is_array( $tables ) ? $tables : explode( ',', $tables ); } $date = date('Y 年 m 月 d 日 H:i:s', time() ); $mysqlinfo = mysql_query( 'SELECT VERSION()'); $mysqlinfo = mysql_fetch_row( $mysqlinfo ); $mysqlinfo = $mysqlinfo[0]; $phpinfo = PHP_VERSION; $return = "--\n"; $return .= "-- 背字根数据库备份脚本\n"; $return .= "-- 主机:$host\n"; $return .= "-- 生成日期:$date\n"; $return .= "-- 数据库版本:$mysqlinfo\n"; $return .= "-- PHP版本:$phpinfo\n"; $return .= "--\n"; $return .= "-- 数据库: `$name`\n"; $return .= "--\n\n"; $return .= "-- --------------------------------------------------------\n\n"; foreach( $tables as $table ) { $result = mysql_query( 'SELECT * FROM ' . $table ); $num_fields = mysql_num_fields( $result ); $return .= "--\n"; $return .= "-- 表的结构 `$table`\n"; $return .= "--"; $row2 = mysql_fetch_row( mysql_query( 'SHOW CREATE TABLE ' . $table ) ); $return .= "\n\n" . $row2[1] . ";\n\n"; $return .= "--\n"; $return .= "-- 转存表中的数据 `$table`\n"; $return .= "--\n\n"; while( $row = mysql_fetch_row( $result ) ) { $return .= "INSERT INTO `$table` VALUES ("; for( $i=0; $i<$num_fields; $i++ ) { $row[$i] = mysql_real_escape_string( $row[$i] ); if ( isset( $row[$i] ) ) { if( is_numeric($row[$i]) ) { $return .= $row[$i]; } else { $return .= "'$row[$i]'"; } } else { $return .= '""'; } if ( $i < ($num_fields-1) ) { $return .= ', '; } } $return .= ");\n"; } $return .= "\n\n"; } mysql_close($link); return $return; }
网上的脚本大多数没有对内容进行转义,一些脚本使用addslashes函数来转义,这样内容中的换行会使导出的内容看起来很乱,这里我使用mysql_real_escape_string函数来转义,导出的内容和使用phpMyAdmin导出的一致。
将导出的数据写入文件并打包:
$host = 'xxx.xxx.xxx.com:3306'; $user = 'beizigen'; $pass = '123456'; $name = 'beizigendb'; $filename = __DIR__ . '/' . $name . '_' . time() . '.sql'; $mysql = bzg_backup_tables( $host, $user, $pass, $name ); if( $mysql ) { $fp = fopen( $filename, 'w' ); fputs( $fp, $mysql ); fclose( $fp ); } if( file_exists( $filename ) ) { $zip = new ZipArchive; if ( $zip->open( $filename . '.zip', ZIPARCHIVE::CREATE ) === TRUE ) { $zip->addFile( $filename, basename( $filename ) ); $zip->close(); unlink( $filename ); $filename = $filename . '.zip'; } }