📄 dbbackup.php
字号:
<?phpdefined('WikyBlog') or die("Not an entry point...");global $lang;$lang['database_backup'] = 'Database Backup';$lang['backup'] = 'Backup';$lang['backup_now'] = 'Backup Now';$lang['recover'] = 'Recover';$lang['table'] = 'Table';$lang['tables'] = 'Tables';$lang['create'] = 'Create';$lang['download'] = 'Download';$lang['start_recovery'] = 'Start Recovery';$lang['continue_recovery'] = 'Continue Recovery';$lang['info'] = 'Info';$lang['DOWNLOAD_MESSAGE'] = 'Your download should begin shortly. You may click here to <a %s>initiate the download</a> if you are having problems.';if( $_SESSION['userlevel'] !== 4){ global $page; $page->contentA['Admin Only'] = 'You must be an administrator to access this page.'; return;}class dbBackup{ var $tables = array(); var $useTable = false; var $maxTime = 8; var $startNum = 100; var $safeMode = false; var $compress = false; var $downloadable = false; var $backupCounts = array(); var $handle = false; var $lineCount = 0; var $recCounts = array(); function dbBackup(){ global $page,$pageOwner,$dbObject,$lang,$rootDir,$wbWritable,$wbUniq; if( isset($wbWritable) && ($wbWritable === false) ){ message('The backup script requires the ability to write files to your server. If php is running in safe mode, WikyBlog must be installed with ftp values.'); return; } if( ini_get('safe_mode') ){ $this->safeMode = true; } // // setup // $dbObject->links[$lang['database_backup']] = $page->formAction = '/Admin/'.$pageOwner['username'].'/Backup'; $this->setTables(); $this->backupFile = $rootDir.'/userfiles/backup.'.$wbUniq.'.tmp'; $this->recoverFile = $rootDir.'/userfiles/recover.txt'; if( file_exists($this->backupFile) && (filesize($this->backupFile) > 1)){ $this->downloadable = true; } if(function_exists('gzopen') && function_exists('ob_get_level') ){ $this->compress = true; } // // GRANTS // includeFile('admin/CheckPrivs.php'); if( !checkPrivs::isGrantedCheck(array('ALTER')) ){ message('<strong>Warning:</strong> The MySQL user you supplied at installation needs the <a href="http://dev.mysql.com/doc/refman/4.1/en/privileges-provided.html" target="_new">FILE and ALTER privilege</a> to be able to perform backups and recoveries. You can find the username being used by looking in your /wiki.php file.'); } // // Download // if( $page->userCmd == 'download'){ $this->downloadNow(); } ob_start(); $this->options(); $page->contentA[$lang['database_backup']] = wb::get_clean(); } function options(){ global $page,$lang,$wbAdminUser,$wbTablePrefix; $downloadMessage = false; switch($page->userCmd){ case 'recover': $this->startRecovery(); return; case wbStrtolower($lang['start_recovery']): $this->recover(true); $this->recoverInstruct(); return; case wbStrtolower($lang['continue_recovery']): $this->recover(); $this->recoverInstruct(); return; case wbStrtolower($lang['backup_now']): $this->backupInit(); $this->backup(); if( !$this->useTable ){ $this->downloadNow(); } return; case wbStrtolower($lang['continue']): $this->backup(); if( $this->useTable ){ return; }else{ $url = wbLinks::getUrl('Backup?cmd=download'); echo '<iframe style="border: 0px none ; width: 0px; height: 0px;" src="'.$url.'"></iframe>'; $downloadMessage = true; $url = 'href="'.$url.'"'; //$link = 'You can now <a href="'.wbLinks::getUrl('Backup?cmd=download').'">'.$lang['download'].'</a> your backup file.'; message('DOWNLOAD_MESSAGE',$url); } break; } if( !$downloadMessage && $this->downloadable){ message('<strong>Warning:</strong> There\'s a backup file on your server that should be <a href="'.wbLinks::getUrl('Backup?cmd=download').'">downloaded and erased</a> as soon as possible.'); } echo '<p>'; echo 'This utility will allow you to download an entire copy of your site\'s database and, in the event of data loss, recover your database from these files.'; echo '</p>'; $this->backupForm(); $this->recoverInstruct(); echo '<h3>Remember</h3>'; echo '<ul>'; echo '<li>Sensitive data is stored in the backup files and should not be stored on a public server.</li>'; echo '<li>If you have to re-install WikyBlog, you\'ll need to re-install the same version with the same admin username and mysql table prefix. These values are currently "<tt>'.$wbAdminUser.'</tt>" and "<tt>'.$wbTablePrefix.'</tt>" respectively.</li>'; echo '<li>Recovery will overwrite any data left in your database.</li>'; echo '</ul>'; } function setTables(){ global $wbTablePrefix; includeFile('installDB.php'); $this->database = getDatabaseArray($wbTablePrefix); } ////////////////////////////////////////////////////////////////////////////////////////// // // Recovery // function startRecovery(){ global $lang; $this->recoveryVars(); $this->recoverForm(); echo '<br/>'; echo '<input type="submit" name="cmd" value="'.$lang['start_recovery'].'" />'; $this->recoverInstruct(); } function recoveryVars(){ global $page,$lang,$wbAdminUser,$wbTablePrefix,$dbname,$packageVersion; $page->displayTitle = $lang['recover']; if( !file_exists($this->recoverFile) ){ message('The recover file doesn\'t exist.'); return false; } $this->handleRec = fopen($this->recoverFile,'r'); $i = 0; $code = ''; while($ln = fgets($this->handleRec) ){ $i++; $test = trim($ln); if( empty($test) ){ break; } $code .= $ln; if( $i > 10 ){ break; } } //get the last line of the recover file.. $seek = min(filesize($this->recoverFile),20000); fseek($this->handleRec,-($seek),SEEK_END); $prevPos = $nextPos = ftell($this->handleRec); while($ln = fgets($this->handleRec) ){ $lastLine = $ln; $prevPos = $nextPos; $nextPos = ftell($this->handleRec); } $this->recLength = $prevPos; rewind($this->handleRec); $data = unserialize($lastLine); $this->recTables =& $data['tables']; $this->recCounts =& $data['counts']; $done = true; if( $data['adminUser'] != $wbAdminUser){ $done = false; message('The admininstrator\'s username must be the same for the backup.txt file and the current installation. The backup.txt file\'s admin user is <tt>'.$data['adminUser'].'</tt>'); } if( $data['tablePrefix'] != $wbTablePrefix){ message('The MySQL table prefix must be the same for the backup.txt file and the current installation. The backup.txt file\'s table prefix is <tt>'.$data['tablePrefix'].'</tt>'); $done = false; } if( $data['version'] != $packageVersion){ message('<strong>Warning:</strong> The version of this installation (<tt>V'.$packageVersion.'</tt>) does not match the version of the backup file (<tt>V'.$data['version'].'</tt>). If the database structure of these two versions does not match, your data will not be recovered correctly. We recommend installing version <tt>'.$data['version'].'</tt> before continuing.'); } return $done; } function initRecover(){ global $wbTablePrefix; require_once('installDB.php'); $alterDb = new dbAlter(); if( $alterDb->go($wbTablePrefix,$this->recTables) ){ return true; } return false; } function recoverForm(){ global $pageOwner,$lang; if( empty($this->recCounts) ){ $this->recoveryVars(); } $i = 0; $classes[] = ' class="tableRowOdd" '; $classes[] = ' class="tableRowEven" '; echo '<table class="tableRows">'; echo '<tr><th>'; echo $lang['table']; echo '</th>'; echo '<th>'; echo $lang['info']; echo '</th>'; echo '</tr>'; $exists = true; foreach($this->recCounts as $table => $len){ echo '<tr'.$classes[($i%2)].'>'; echo '<td>'; echo $table; echo '</td>'; echo '<td style="text-align:right !important;">'; if( $len <= 0 ){ echo '-nothing to recover-'; }elseif( $exists ){ echo number_format($len).' rows'; } echo '</td>'; echo '</tr>'; $i++; } echo '<tr><td>'; echo $lang['total']; echo '</td>'; echo '<td style="text-align:right !important">'; echo number_format(array_sum($this->recCounts)).' rows'; echo '</td></tr></table>'; } function recover($init=false){ global $pageOwner,$lang,$wbTablePrefix; if( !$this->recoveryVars() ){ return false; } if( $init && !$this->initRecover()){ return false; } if( isset($_POST['position']) && is_numeric($_POST['position']) ){ fseek($this->handleRec,$_POST['position'],SEEK_SET); } if( isset($_POST['count']) && is_numeric($_POST['count']) ){ $this->lineCount = $_POST['count']; } foreach($this->recTables as $table => $null){ $query = 'ALTER TABLE `'.$wbTablePrefix.$table.'` DISABLE KEYS '; wbDB::runQuery($query); } if( $this->safeMode ){ $this->recoverPortion(); }else{ do{ $this->recoverPortion(); set_time_limit(15); }while( !$this->recFinished() ); } foreach($this->recTables as $table => $null){ $query = 'ALTER TABLE `'.$wbTablePrefix.$table.'` ENABLE KEYS '; wbDB::runQuery($query); } $this->recoverForm(); if( !$this->recFinished() ){ echo '<br>'; message(number_format($this->lineCount).' rows have been recovered out of a total of of '.number_format(array_sum($this->recCounts)).'.'); echo '<input type="hidden" name="count" value="'.$this->lineCount.'" />'; echo '<input type="hidden" name="position" value="'.ftell($this->handleRec).'" />'; echo '<input type="submit" name="cmd" value="'.$lang['continue_recovery'].'" />'; }else{ message('All '.number_format($this->lineCount).' rows have been recovered.'); } return true; } function recFinished(){ if( ftell($this->handleRec) >= $this->recLength){ return true; } return false; } function recoverPortion(){ $duration = 0; $startTime = microtime(); while(($duration < $this->maxTime) && ($ln = fgets($this->handleRec)) && !$this->recFinished() ){ $ln = trim($ln); if( empty($ln) ){ continue; } if( strpos($ln,'INSERT') !== 0){ //message('hmm: '.htmlspecialchars($ln)); continue; } $ln = 'REPLACE '.substr($ln,6); wbDB::runQuery($ln); $this->lineCount++; $duration = microtime_diff($startTime, microtime()); } // // So the user isn't logged out //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -