本文實例講述了ThinkPHP框架實現的MySQL數據庫備份功能。分享給大家供大家參考,具體如下:
1、緣由
自從2010年開始試用ThinkPHP以來,的確帶來了許多方便。的確給我帶來了許多方便。此次應為數據頻繁備份需要,而每次遠程連接到服務器頗為不便。變萌生了寫個ThinkPHP數據庫備份SQL生成類的念頭。
2、介紹
由于在數據庫中有使用觸發器。因此也需要一并備份。并且為了插入數據的時候不會受到觸發器影響而破壞先前插入的數據,在插入數據之前生成了刪除觸發器的代碼。 本類并不能生成數據表的創建和刪除代碼,因此在使用中請注意保證兩端表結構的一致。
做WEB開發,一直以來,都采用 Navicat For Mysql 將本地數據庫同步到服務器上。前些天,突然心血來潮,將本地數據庫升級到了 Mysql 5.5版本,再次將數據同步的時候卻發生了錯誤。想起之前寫過的 ThinkPHP 實現Mysql數據庫備份 只有備份數據的功能,而沒有導出表結構的功能。于是想到了升級一下。讓其更完整。
本次升級 增加了 備份表結構、視圖功能。導出數據增加了類型判斷,insert 語句當字段為空的時候會輸出 NULL,當為數字 的時候則不會帶上 單引號。
<?php /** * 描述:基于ThinkPHP框架的Mysql數據庫導出類 * 日期:2012-07-15 * 作者:龔辟愚 */ class DBExport { /** * @description 獲取當前數據庫的所有表名。 * @static * @return array */ static protected function getTables() { $dbName=C('DB_NAME'); $result=M()->query("SHOW FULL TABLES FROM `{$dbName}` WHERE Table_Type = 'BASE TABLE'"); foreach ($result as $v){ $tbArray[]=$v['Tables_in_'.C('DB_NAME')]; } return $tbArray; } static protected function getViews() { $dbName=C('DB_NAME'); $result=M()->query("SHOW FULL TABLES FROM `{$dbName}` WHERE Table_Type = 'VIEW'"); foreach ($result as $v){ $tbArray[]=$v['Tables_in_'.C('DB_NAME')]; } return $tbArray; } /** * @description 導出SQL數據,但不包含表創建代碼。 * @static * @return string */ static public function ExportAllData() { $tables = self::getTables(); $arrAll = array( "SET FOREIGN_KEY_CHECKS=0;", self::BuildAllTriggerDropSql(), self::BuildTableSql(), self::BuildViewSql() ); $tbl = new Model(); foreach($tables as $table) { $arrAll[]="\r\nDELETE FROM {$table};"; /* $rs = $tbl->query("SHOW COLUMNS FROM {$table}"); $arrFields = array(); foreach ($rs as $k=>&$v){ $arrFields[] = "`{$v['Field']}`"; } $sqlFields = implode($arrFields,","); */ $rs=$tbl->query("select * from `{$table}`"); foreach ($rs as $k=>&$v){ $arrValues = array(); foreach($v as $key=>$val) { if(is_numeric($val)){ $arrValues[]=$val; }else if(is_null($val)){ $arrValues[]='NULL'; }else{ $arrValues[]="'".addslashes($val)."'"; } } $arrAll[] = "INSERT INTO `{$table}` VALUES (".implode(',',$arrValues).");"; } } $arrAll[]=self::BuildTriggerCreateSql(); return implode("\r\n",$arrAll); } static protected function BuildTableSql() { $tables = self::getTables(); $arrAll = array(); foreach($tables as &$val){ $rs = M()->query("SHOW CREATE TABLE `{$val}`"); $tbSql = preg_replace("#CREATE(.*)\\s+TABLE#","CREATE TABLE",$rs[0]['Create Table']); $arrAll[] = "DROP TABLE IF EXISTS `{$rs[0]['Table']}`;\r\n{$tbSql};\r\n"; } return implode("\r\n",$arrAll); } static protected function BuildViewSql() { $views = self::getViews(); $arrAll = array(); foreach($views as &$val){ $rs = M()->query("SHOW CREATE VIEW `{$val}`"); $tbSql = preg_replace("#CREATE(.*)\\s+VIEW#","CREATE VIEW",$rs[0]['Create View']); $arrAll[] = "DROP VIEW IF EXISTS `{$rs[0]['View']}`;\r\n{$tbSql};\r\n"; } return implode("\r\n",$arrAll); } /** * @description 如果存在觸發器,生成刪除代碼。原因是:插入數據的時候可能會受到觸發器影響。 * @static * @return string */ static public function BuildAllTriggerDropSql() { $rs = M()->query("show triggers"); $arrAll = array(); foreach ($rs as $k=>&$v) { $arrSql = array( 'DROP TRIGGER IF EXISTS `',$v['Trigger'],'`;' ); $arrAll[] = implode('',$arrSql); } return implode("\r\n",$arrAll); } /** * @description 生成所有觸發器的創建代碼。 * @static * @return string */ static protected function BuildTriggerCreateSql() { $rs = M()->query("show triggers"); $arrAll = array(); foreach ($rs as $k=>&$v) { $arrSql = array( 'CREATE TRIGGER `',$v['Trigger'],'` ',$v['Timing'],' ',$v['Event'],' ON `', $v['Table'],'` FOR EACH ROW ',$v['Statement'],';' ); $arrAll[] = implode('',$arrSql); } return implode("\r\n",$arrAll); } }
調用示例:
vendor('DBExport',COMMON_PATH); header('Content-type: text/plain; charset=UTF-8'); $dbName = C('DB_NAME'); header("Content-Disposition: attachment; filename=\"{$dbName}.sql\""); echo DBExport::ExportAllData()
希望本文所述對大家基于ThinkPHP框架的PHP程序設計有所幫助。