?? tools.php
字號:
<?php
/*
[Discuz!] Tools (C)2001-2008 Comsenz Inc.
This is NOT a freeware, use is subject to license terms
$Id: tools.php 1761 2008-12-10 07:55:12 by xiaobozi $
*/
/**
* ********************** 配置區 *******************************
*/
$tool_password = 'sunrisedhy'; // ☆★☆★☆★ 請您設置一個工具包的高強度密碼,不能為空!☆★☆★☆★
error_reporting(E_ERROR | E_WARNING | E_PARSE); //E_ERROR | E_WARNING | E_PARSE
@set_time_limit(0);
define('TOOLS_ROOT', dirname(__FILE__)."/");
define('VERSION', '2009賀歲版');
$functionall = array(
array('all', 'all_repair', '檢查或修復數據庫', '對所有數據表進行檢查修復工作(支持所有Comsenz產品)。'),
array('all', 'all_runquery', '數據庫升級', '可以運行任意SQL語句,請慎用(支持所有Comsenz產品)。'),
array('all', 'all_checkcharset', '編碼檢測修復', '對所有數據表進行編碼檢查和修復(支持所有Comsenz產品)。'),
array('dz_uc_ss_uch', 'all_restore', '導入數據庫備份', '一次性導入論壇數據備份(可以恢復Discuz!、UCenter、SupeSite、UCenter Home程序備份的數據)。'),
array('uc_dz', 'uc_dz_deletepms', '清理短消息', '放在UCenter下可以'),
array('dz_uc_uch_ec_ss', 'all_setadmin', '找回管理員', '將把您指定的會員設置為管理員,如果忘記管理員帳號密碼,這是個不錯的工具(支持Discuz!、SupeSite、UCenter、UCenter Home、ECshop)。'),
array('dz', 'dz_doctor', '論壇醫生', '自動檢查您的論壇配置文件情況,系統環境信息以及錯誤報告(Discuz!論壇下使用)。'),
array('dz', 'dz_filecheck', '搜索未知文件', '檢查論壇程序目錄下的非Discuz!官方文件(Discuz!論壇下使用)。'),
array('dz', 'dz_rplastpost', '修復最后回復', '修復版塊最后回復(Discuz!論壇下使用。)'),
array('dz', 'dz_rpthreads', '批量修復主題', '某些帖子頁面會出現未定義操作,可以用批量修復主題的功能修復下(Discuz!論壇下使用。'),
array('dz', 'dz_mysqlclear', '數據庫冗余數據清理', '對您的數據進行有效性檢查,刪除冗余數據信息(Discuz!論壇下使用)。'),
array('dz', 'dz_moveattach', '附件保存方式', '將您現在的附件存儲方式按照指定方式進行目錄結構調整并重新存儲(Discuz!論壇下使用)。'),
array('dz', 'dz_replace', '帖子內容批量替換', '按照論壇后臺中設置的詞語過濾列表,可選擇性的對所有帖子進行處理,帖子將按照過濾規則進行處理(Discuz!論壇下使用)。'),
array('dz', 'dz_repair_auto', '字段自增長修復', '自動檢索論壇所有的數據表,可修復自增字段丟失的問題(Discuz!論壇下使用)。'),
array('dz', 'dz_updatecache', '更新緩存', '清除緩存(Discuz!論壇下使用)。'),
array('all', 'all_toolsback', '<font color="red">反饋建議</font>', '您對Tools工具箱的建議和意見,以及使用過程中遇到的問題,可以及時的反饋給我們。')
);
//初始化
$lockfile = ''; //tools鎖存放位置
$action = '';
$target_fsockopen = '0'; //使用何種方式進行連接服務器 0=域名, 1=IP (使用IP方式需要保證IP地址可以正常訪問到您的站點)
$alertmsg = ' onclick="alert(\'點擊確定開始運行,可能需要一段時間,請稍候\');"';
foreach(array('_COOKIE', '_POST', '_GET') as $_request) { //釋放變量到全局
foreach($$_request as $_key => $_value) {
($_key{0} != '_' && $_key != 'tool_password' && $_key != 'lockfile') && $$_key = taddslashes($_value);
}
}
$whereis = getplace(); //判斷文件位置
if($whereis == 'is_dz' && !defined('DISCUZ_ROOT')) {
define('DISCUZ_ROOT', TOOLS_ROOT);
}
if(!$whereis && !in_array($whereis, array('is_dz', 'is_uc', 'is_uch', 'is_ss', 'is_ec', 'is_ecm'))) {
$alertmsg = '';
errorpage('<ul><li>工具箱必須放在Discuz!、UCenter、UCente Home、SupeSite、ECShop或者ECmall的根目錄下才能正常使用。</li><li>如果你確實放在了上述程序目錄下,請檢查上述程序運行所需要設定的目錄可讀寫權限是否正確</li>');
}
if(@file_exists($lockfile)) { //工具箱是否鎖定
$alertmsg = '';
errorpage("<h6>工具箱已關閉,如需開啟只要通過 FTP 刪除 $lockfile 文件即可! </h6>");
} elseif ($tool_password == ''){
$alertmsg = '';
errorpage('<h6>工具箱密碼默認為空,第一次使用前請您修改本文件中$tool_password設置密碼!</h6>');
}
if($action == 'login') {//登陸
setcookie('toolpassword',md5($toolpassword), 0);
echo '<meta http-equiv="refresh" content="2 url=?">';
errorpage("<h6>請稍等,程序登錄中!</h6>");
}
if(isset($toolpassword)) {
if($toolpassword != md5($tool_password)) {
$alertmsg = ''; //bug 有點多余?
errorpage("login");
}
} else {
$alertmsg = '';
errorpage("login");
}
// 判斷是否含有升級或者安裝文件,提示刪除
if(file_exists(TOOLS_ROOT.'./install/index.php') && $whereis=='is_dz'){
$installfile = './install/index.php';
}
for($ti=1;$ti<11;$ti++){
if(file_exists(TOOLS_ROOT.'./upgrade'.$ti.'.php') && $whereis=='is_dz'){
$upgradefile = './upgrade'.$ti.'.php';
}
}
getdbcfg();//獲得數據庫配置信息 連接數據庫
mysql_connect($dbhost, $dbuser, $dbpw);
mysql_select_db($dbname);
$my_version = mysql_get_server_info();
if($my_version > '4.1'){
$serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary' : '';
$serverset .=$my_version > '5.0.1' ? ((empty($serverset))? '' : ',').'sql_mode=\'\'' : '';
$serverset && mysql_query("SET $serverset");
}
//流程開始
if($action == 'all_repair') {//修復數據庫開始
$counttables = $oktables = $errortables = $rapirtables = 0;
if($check) {
$tables = mysql_query("SHOW TABLES");
if(!$nohtml) {
echo "<html><head></head><body>";
}
if($iterations) {
$iterations --;
}
while($table = mysql_fetch_row($tables)) {
$counttables += 1;
$answer = checktable($table[0],$iterations);
if(!$nohtml) {
echo "<tr><td colspan=4> </td></tr>";
} elseif (!$simple) {
flush();
}
}
if(!$nohtml) {
echo "</body></html>";
}
if($simple) {
htmlheader();
echo '<h4>檢查修復數據庫</h4>
<h5>檢查結果:</h5>
<table>
<tr><th>檢查表(張)</th><th>正常表(張)</th><th>修復的表(張)</th><th>錯誤的表(個)</th></tr>
<tr><td>'.$counttables.'</td><td>'.$oktables.'</td><td>'.$rapirtables.'</td><td>'.$errortables.'</td></tr>
</table>
<p>檢查結果沒有錯誤后請返回工具箱首頁反之則繼續修復</p>
<p><b><a href="tools.php?action=all_repair">繼續修復</a> <a href="tools.php">返回首頁</a></b></p>
</td></tr></table>';
specialdiv();
}
} else {
htmlheader();
echo "<h4>檢查修復數據庫</h4>
<div class='specialdiv'>
操作提示:
<ul>
<li>您可以通過下面的方式修復已經損壞的數據庫。點擊后請耐心等待修復結果!</li>
<li>本程序可以修復常見的數據庫錯誤,但無法保證可以修復所有的數據庫錯誤。(需要 MySQL 3.23+)</li>
</ul>
</div>
<h5>操作:</h5>
<ul>
<li><a href=\"?action=all_repair&check=1&nohtml=1&simple=1\">檢查并嘗試修復數據庫1次</a>
<li><a href=\"?action=all_repair&check=1&iterations=5&nohtml=1&simple=1\">檢查并嘗試修復數據庫5次</a> (因為數據庫讀寫關系可能有時需要多修復幾次才能完全修復成功)
</ul>";
specialdiv();
}
htmlfooter();
}elseif($action == 'all_restore') {//導入數據庫備份
ob_implicit_flush();
$backdirarray = array( //不同的程序存放備份文件的目錄是不同的
'is_dz'=>'forumdata',
'is_uc'=>'data/backup',
'is_uch'=>'data',
'is_ss'=>'data'
);
if(!get_cfg_var('register_globals')) {
@extract($HTTP_GET_VARS);
}
$sqldump = '';
htmlheader();
?><h4>數據庫恢復實用工具 </h4><?php
echo "<div class=\"specialdiv\">操作提示:<ul>
<li>只能恢復存放在服務器(遠程或本地)上的數據文件,如果您的數據不在服務器上,請用 FTP 上傳</li>
<li>數據文件必須為 Discuz! 導出格式,并設置相應屬性使 PHP 能夠讀取</li>
<li>請盡量選擇服務器空閑時段操作,以避免超時.如程序長久(超過 10 分鐘)不反應,請刷新</li></ul></div>";
if($file) {
if(strtolower(substr($file, 0, 7)) == "http://") {
echo "從遠程數據庫恢復數據 - 讀取遠程數據:<br><br>";
echo "從遠程服務器讀取文件 ... ";
$sqldump = @fread($fp, 99999999);
@fclose($fp);
if($sqldump) {
echo "成功<br><br>";
} elseif (!$multivol) {
cexit("失敗<br><br><b>無法恢復數據</b>");
}
} else {
echo "<div class=\"specialtext\">從本地恢復數據 - 檢查數據文件:<br><br>";
if(file_exists($file)) {
echo "數據文件 $file 存在檢查 ... 成功<br><br>";
} elseif (!$multivol) {
cexit("數據文件 $file 存在檢查 ... 失敗<br><br><br><b>無法恢復數據</b></div>");
}
if(is_readable($file)) {
echo "數據文件 $file 可讀檢查 ... 成功<br><br>";
@$fp = fopen($file, "r");
@flock($fp, 3);
$sqldump = @fread($fp, filesize($file));
@fclose($fp);
echo "從本地讀取數據 ... 成功<br><br>";
} elseif (!$multivol) {
cexit("數據文件 $file 可讀檢查 ... 失敗<br><br><br><b>無法恢復數據</b></div>");
}
}
if($multivol && !$sqldump) {
cexit("分卷備份范圍檢查 ... 成功<br><br><b>恭喜您,數據已經全部成功恢復!安全起見,請務必刪除本程序.</b></div>");
}
echo "數據文件 $file 格式檢查 ... ";
if($whereis == 'is_uc') {
$identify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", substr($sqldump, 0, 256))));
$method = 'multivol';
$volume = $identify[4];
}else{
@list(,,,$method, $volume) = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", preg_replace("/^(.+)/", "\\1", substr($sqldump, 0, 256)))));
}
if($method == 'multivol' && is_numeric($volume)) {
echo "成功<br><br>";
} else {
cexit("失敗<br><br><b>數據非 Discuz! 分卷備份格式,無法恢復</b></div>");
}
if($onlysave == "yes") {
echo "將數據文件保存到本地服務器 ... ";
$filename = TOOLS_ROOT.'./'.$backdirarray[$whereis].strrchr($file, "/");
@$filehandle = fopen($filename, "w");
@flock($filehandle, 3);
if(@fwrite($filehandle, $sqldump)) {
@fclose($filehandle);
echo "成功<br><br>";
} else {
@fclose($filehandle);
die("失敗<br><br><b>無法保存數據</b>");
}
echo "成功<br><br><b>恭喜您,數據已經成功保存到本地服務器 <a href=\"".strstr($filename, "/")."\">$filename</a>.安全起見,請務必刪除本程序.</b></div>";
} else {
$sqlquery = splitsql($sqldump);
echo "拆分操作語句 ... 成功<br><br>";
unset($sqldump);
echo "正在恢復數據,請等待 ... </div>";
foreach($sqlquery as $sql) {
$dbversion = mysql_get_server_info();
$sql = syntablestruct(trim($sql), $dbversion > '4.1', $dbcharset);
if(trim($sql)) {
@mysql_query($sql);
}
}
if($auto == 'off'){
$nextfile = str_replace("-$volume.sql", '-'.($volume + 1).'.sql', $file);
cexit("<ul><li>數據文件 <b>$volume#</b> 恢復成功,如果有需要請繼續恢復其他卷數據文件</li><li>請點擊<b><a href=\"?action=all_restore&file=$nextfile&multivol=yes\">全部恢復</a></b> 或許單獨恢復下一個數據文件<b><a href=\"?action=all_restore&file=$nextfile&multivol=yes&auto=off\">單獨恢復下一數據文件</a></b></li></ul>");
} else {
$nextfile = str_replace("-$volume.sql", '-'.($volume + 1).'.sql', $file);
echo "<ul><li>數據文件 <b>$volume#</b> 恢復成功,現在將自動導入其他分卷備份數據.</li><li><b>請勿關閉瀏覽器或中斷本程序運行</b></li></ul>";
redirect("?action=all_restore&file=$nextfile&multivol=yes");
}
}
} else {
$exportlog = array();
if(is_dir(TOOLS_ROOT.'./'.$backdirarray[$whereis])) {
$dir = dir(TOOLS_ROOT.'./'.$backdirarray[$whereis]);
while($entry = $dir->read()) {
$entry = "./".$backdirarray[$whereis]."/$entry";
if(is_file($entry) && preg_match("/\.sql/i", $entry)) {
$filesize = filesize($entry);
$fp = @fopen($entry, 'rb');
@$identify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", fgets($fp, 256))));
@fclose ($fp);
if(preg_match("/\-1.sql/i", $entry) || $identify[3] == 'shell'){
$exportlog[$identify[0]] = array( 'version' => $identify[1],
'type' => $identify[2],
'method' => $identify[3],
'volume' => $identify[4],
'filename' => $entry,
'size' => $filesize);
}
} elseif (is_dir($entry) && preg_match("/backup\_/i", $entry)) {
$bakdir = dir($entry);
while($bakentry = $bakdir->read()) {
$bakentry = "$entry/$bakentry";
if(is_file($bakentry)){
@$fp = fopen($bakentry, 'rb');
@$bakidentify = explode(',', base64_decode(preg_replace("/^# Identify:\s*(\w+).*/s", "\\1", fgets($fp, 256))));
@fclose ($fp);
if(preg_match("/\-1\.sql/i", $bakentry) || $bakidentify[3] == 'shell') {
$identify['bakentry'] = $bakentry;
}
}
}
if(preg_match("/backup\_/i", $entry)){
$exportlog[filemtime($entry)] = array( 'version' => $bakidentify[1],
'type' => $bakidentify[2],
'method' => $bakidentify[3],
'volume' => $bakidentify[4],
'bakentry' => $identify['bakentry'],
'filename' => $entry);
}
}
}
$dir->close();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -