├── Module.php ├── controllers ├── DefaultController.php └── BackupController.php ├── views └── default │ └── index.php ├── composer.json ├── README.md └── helpers └── MysqlBackup.php /Module.php: -------------------------------------------------------------------------------- 1 | 4 | * createTime : 2015/6/29 19:43 5 | * description: 6 | */ 7 | namespace yiier\backup\controllers; 8 | 9 | use yii\web\Controller; 10 | 11 | class DefaultController extends Controller 12 | { 13 | public function actionIndex() 14 | { 15 | return $this->render('index'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /views/default/index.php: -------------------------------------------------------------------------------- 1 |
2 |

context->action->uniqueId ?>

3 |

4 | This is the view content for action "context->action->id ?>". 5 | The action belongs to the controller "context) ?>" 6 | in the "context->module->id ?>" module. 7 |

8 |

9 | You may customize this page by editing the following file:
10 | 11 |

12 |
13 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiier/yii2-backup", 3 | "description": "Database Backup and Restore functionality", 4 | "type": "yii2-extension", 5 | "keywords": ["yii2","extension","yii2-backup","backup"], 6 | "license": "Apache-2.0", 7 | "authors": [ 8 | { 9 | "name": "forecho", 10 | "email": "caizhenghai@gmail.com" 11 | } 12 | ], 13 | "require": { 14 | "yiisoft/yii2": "*" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "yiier\\backup\\": "" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /controllers/BackupController.php: -------------------------------------------------------------------------------- 1 | 4 | * createTime : 2015/6/29 19:43 5 | * description: 6 | */ 7 | namespace yiier\backup\controllers; 8 | 9 | use yii\console\Controller; 10 | use yiier\backup\helpers\MysqlBackup; 11 | use Yii; 12 | 13 | class BackupController extends Controller 14 | { 15 | public $formUser; 16 | public $siteName; 17 | 18 | public function init() 19 | { 20 | parent::init(); 21 | $this->formUser = Yii::$app->params['supportEmail']; 22 | $this->siteName = Yii::$app->name; 23 | if (Yii::$app->has('setting')) { 24 | $this->formUser = Yii::$app->setting->get('smtpUser'); 25 | $this->siteName = Yii::$app->setting->get('siteName'); 26 | Yii::$app->set('mailer', [ 27 | 'class' => 'yii\swiftmailer\Mailer', 28 | 'viewPath' => '@common/mail', 29 | 'transport' => [ 30 | 'class' => 'Swift_SmtpTransport', 31 | 'host' => Yii::$app->setting->get('smtpHost'), 32 | 'username' => Yii::$app->setting->get('smtpUser'), 33 | 'password' => Yii::$app->setting->get('smtpPassword'), 34 | 'port' => Yii::$app->setting->get('smtpPort'), 35 | // 'mail' => Yii::$app->setting->get('smtpMail'), // 显示地址 36 | 'encryption' => 'tls', 37 | ], 38 | ]); 39 | } 40 | } 41 | 42 | public function sendEmail($sqlFile) 43 | { 44 | return Yii::$app->mailer->compose('backup') 45 | ->setFrom([$this->formUser => $this->siteName . '- 机器人']) 46 | ->setTo(Yii::$app->params['backupEmail']) 47 | ->setSubject('数据库定时备份系统-' . $this->siteName) 48 | ->attach($sqlFile) 49 | ->send(); 50 | } 51 | 52 | public function actionIndex() 53 | { 54 | $sql = new MysqlBackup(); 55 | $tables = $sql->getTables(); 56 | Yii::info('数据库备份失败', 'backups'); 57 | if (!$sql->StartBackup()) { 58 | //render error 59 | Yii::info('数据库备份失败', 'backup'); 60 | die; 61 | } 62 | 63 | foreach ($tables as $tableName) { 64 | $sql->getColumns($tableName); 65 | } 66 | 67 | foreach ($tables as $tableName) { 68 | $sql->getData($tableName); 69 | } 70 | $sqlFile = $sql->EndBackup(); 71 | 72 | $this->sendEmail($sqlFile); 73 | Yii::info('数据库备份成功', 'backup'); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | yii2-backup 2 | =========== 3 | 4 | [![Latest Stable Version](https://poser.pugx.org/yiier/yii2-backup/v/stable)](https://packagist.org/packages/yiier/yii2-backup) 5 | [![Total Downloads](https://poser.pugx.org/yiier/yii2-backup/downloads)](https://packagist.org/packages/yiier/yii2-backup) 6 | [![Latest Unstable Version](https://poser.pugx.org/yiier/yii2-backup/v/unstable)](https://packagist.org/packages/yiier/yii2-backup) 7 | [![License](https://poser.pugx.org/yiier/yii2-backup/license)](https://packagist.org/packages/yiier/yii2-backup) 8 | 9 | Database Backup and Restore functionality 10 | 11 | Installation 12 | ------------ 13 | 14 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 15 | 16 | Either run 17 | 18 | ``` 19 | 20 | php composer.phar require --prefer-dist yiier/yii2-backup "*" 21 | php composer.phar require funson86/yii2-setting "*" 22 | 23 | // or 24 | 25 | php composer.phar require --prefer-dist yiier/yii2-backup "*" 26 | ``` 27 | 28 | or add 29 | 30 | ``` 31 | "yiier/yii2-backup": "*", 32 | "funson86/yii2-setting": "*" 33 | 34 | // or 35 | 36 | "yiier/yii2-backup": "*", 37 | ``` 38 | 39 | to the require section of your `composer.json` file. 40 | 41 | 42 | Usage 43 | ----- 44 | 45 | Once the extension is installed, simply use it in your code by : 46 | 47 | main.php 48 | 49 | ``` 50 | 'modules' => [ 51 | 'setting' => [ 52 | 'class' => 'funson86\setting\Module', 53 | 'controllerNamespace' => 'funson86\setting\controllers', 54 | ], 55 | 'backup' => [ 56 | 'class' => 'yiier\backup\Module', 57 | ], 58 | ], 59 | 60 | // or 61 | 62 | 'modules' => [ 63 | 'backup' => [ 64 | 'class' => 'yiier\backup\Module', 65 | ], 66 | ], 67 | 'components' => [ 68 | // ... 69 | 'mailer' => [ 70 | 'class' => 'yii\swiftmailer\Mailer', 71 | 'viewPath' => '@common/mail', 72 | 'transport' => [ 73 | 'class' => 'Swift_SmtpTransport', 74 | 'host' => 'smtp.xx.xx', 75 | 'username' => 'xxxxx', 76 | 'password' => 'xxxx', 77 | 'port' => 25, 78 | 'encryption' => 'tls', 79 | ], 80 | ], 81 | // ... 82 | ], 83 | 84 | 85 | ``` 86 | 87 | params.php 88 | ``` 89 | 'backupEmail' => 'xxx@xx', 90 | 'supportEmail' => 'yyy@yy', // from address must be same as supportEmail 91 | ``` 92 | 93 | 94 | add mail/backup.php 95 | ``` 96 | backup successful !!!! 97 | ``` 98 | 99 | console\config\main.php 100 | ``` 101 | 'params' => $params, 102 | ... 103 | 'controllerMap' => [ 104 | 'backup' => [ 105 | 'class' => 'yiier\backup\controllers\BackupController', 106 | ] 107 | ] 108 | ``` 109 | 110 | console 111 | ``` 112 | php yii backup 113 | ``` 114 | 115 | Look 116 | ---------- 117 | https://github.com/iiYii/getyii/commit/b8315d083d5d07969ac163205bf1452216246666 118 | -------------------------------------------------------------------------------- /helpers/MysqlBackup.php: -------------------------------------------------------------------------------- 1 | 4 | * createTime : 2015/6/29 19:43 5 | * description: 6 | */ 7 | 8 | namespace yiier\backup\helpers; 9 | 10 | 11 | use yii\base\Object; 12 | use Yii; 13 | use yii\db\Exception; 14 | 15 | class MysqlBackup extends Object 16 | { 17 | public $menu = []; 18 | public $tables = []; 19 | public $fp; 20 | public $file_name; 21 | public $_path = '@runtime'; 22 | public $back_temp_file = 'db_backup_'; 23 | 24 | protected function getPath() 25 | { 26 | // if (isset ($this->module->path)) { 27 | // $this->_path = $this->module->path; 28 | // } else { 29 | // $this->_path = Yii::$app->basePath . '/_backup/'; 30 | // } 31 | $this->_path = Yii::getAlias('@backend/runtime') . '/_backup/'; 32 | 33 | if (!file_exists($this->_path)) { 34 | mkdir($this->_path); 35 | chmod($this->_path, '777'); 36 | } 37 | return $this->_path; 38 | } 39 | 40 | public function execSqlFile($sqlFile) 41 | { 42 | $message = "ok"; 43 | 44 | if (file_exists($sqlFile)) { 45 | $sqlArray = file_get_contents($sqlFile); 46 | 47 | $cmd = Yii::$app->db->createCommand($sqlArray); 48 | try { 49 | $cmd->execute(); 50 | } catch (Exception $e) { 51 | $message = $e->getMessage(); 52 | } 53 | 54 | } 55 | return $message; 56 | } 57 | 58 | public function getColumns($tableName) 59 | { 60 | $sql = 'SHOW CREATE TABLE ' . $tableName; 61 | $cmd = Yii::$app->db->createCommand($sql); 62 | $table = $cmd->queryOne(); 63 | 64 | $create_query = $table['Create Table'] . ';'; 65 | 66 | $create_query = preg_replace('/^CREATE TABLE/', 'CREATE TABLE IF NOT EXISTS', $create_query); 67 | $create_query = preg_replace('/AUTO_INCREMENT\s*=\s*([0-9])+/', '', $create_query); 68 | if ($this->fp) { 69 | $this->writeComment('TABLE `' . addslashes($tableName) . '`'); 70 | $final = 'DROP TABLE IF EXISTS `' . addslashes($tableName) . '`;' . PHP_EOL . $create_query . PHP_EOL . PHP_EOL; 71 | fwrite($this->fp, $final); 72 | } else { 73 | $this->tables[$tableName]['create'] = $create_query; 74 | return $create_query; 75 | } 76 | } 77 | 78 | public function getData($tableName) 79 | { 80 | $sql = 'SELECT * FROM ' . $tableName; 81 | $cmd = Yii::$app->db->createCommand($sql); 82 | $dataReader = $cmd->query(); 83 | 84 | $data_string = ''; 85 | 86 | foreach ($dataReader as $data) { 87 | $itemNames = array_keys($data); 88 | $itemNames = array_map("addslashes", $itemNames); 89 | $items = join('`,`', $itemNames); 90 | $itemValues = array_values($data); 91 | $itemValues = array_map("addslashes", $itemValues); 92 | $valueString = join("','", $itemValues); 93 | $valueString = "('" . $valueString . "'),"; 94 | $values = "\n" . $valueString; 95 | if ($values != "") { 96 | $data_string .= "INSERT INTO `$tableName` (`$items`) VALUES" . rtrim($values, ",") . ";" . PHP_EOL; 97 | } 98 | } 99 | 100 | if ($data_string == '') 101 | return null; 102 | 103 | if ($this->fp) { 104 | $this->writeComment('TABLE DATA ' . $tableName); 105 | $final = $data_string . PHP_EOL . PHP_EOL . PHP_EOL; 106 | fwrite($this->fp, $final); 107 | } else { 108 | $this->tables[$tableName]['data'] = $data_string; 109 | return $data_string; 110 | } 111 | } 112 | 113 | public function getTables($dbName = null) 114 | { 115 | $sql = 'SHOW TABLES'; 116 | $cmd = Yii::$app->db->createCommand($sql); 117 | $tables = $cmd->queryColumn(); 118 | return $tables; 119 | } 120 | 121 | public function StartBackup($addcheck = true) 122 | { 123 | $this->file_name = $this->path . $this->back_temp_file . date('Y.m.d_H.i.s') . '.sql'; 124 | 125 | $this->fp = fopen($this->file_name, 'w+'); 126 | 127 | if ($this->fp == null) 128 | return false; 129 | fwrite($this->fp, '-- -------------------------------------------' . PHP_EOL); 130 | if ($addcheck) { 131 | fwrite($this->fp, 'SET AUTOCOMMIT=0;' . PHP_EOL); 132 | fwrite($this->fp, 'START TRANSACTION;' . PHP_EOL); 133 | fwrite($this->fp, 'SET SQL_QUOTE_SHOW_CREATE = 1;' . PHP_EOL); 134 | } 135 | fwrite($this->fp, 'SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;' . PHP_EOL); 136 | fwrite($this->fp, 'SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;' . PHP_EOL); 137 | fwrite($this->fp, '-- -------------------------------------------' . PHP_EOL); 138 | $this->writeComment('START BACKUP'); 139 | return true; 140 | } 141 | 142 | public function EndBackup($addcheck = true) 143 | { 144 | fwrite($this->fp, '-- -------------------------------------------' . PHP_EOL); 145 | fwrite($this->fp, 'SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;' . PHP_EOL); 146 | fwrite($this->fp, 'SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;' . PHP_EOL); 147 | 148 | if ($addcheck) { 149 | fwrite($this->fp, 'COMMIT;' . PHP_EOL); 150 | } 151 | fwrite($this->fp, '-- -------------------------------------------' . PHP_EOL); 152 | $this->writeComment('END BACKUP'); 153 | fclose($this->fp); 154 | $this->fp = null; 155 | return $this->file_name; 156 | } 157 | 158 | public function writeComment($string) 159 | { 160 | fwrite($this->fp, '-- -------------------------------------------' . PHP_EOL); 161 | fwrite($this->fp, '-- ' . $string . PHP_EOL); 162 | fwrite($this->fp, '-- -------------------------------------------' . PHP_EOL); 163 | } 164 | 165 | } 166 | --------------------------------------------------------------------------------