以附加檔案原來的檔名做備份

與 phpBB 3.0.x 相關主題。
回覆文章
頭像
心靈捕手
默默耕耘的老師
默默耕耘的老師
文章: 8510
註冊時間: 2004-04-30 01:54
來自: Taiwan

以附加檔案原來的檔名做備份

文章 心靈捕手 »

想法

phpBB 的附加檔案和其原來的檔案名稱都被儲存在「attachments」資料表,所以要恢復原來的檔案名稱,您可以使用該資料表中的資料。

在此,有一個 script,複製所有附加檔案(縮圖除外)上傳到不同的資料夾中的,並重新命名為原來的檔名,由 attachment_id 作為的前綴,以防止重複的檔名。
phpBB 的原始資料保持不變。

步驟

第 1 步

首先,在論壇的根目錄建立一個命名為「filebackup」的資料夾,並將它的 CHMOD 權限設定為 777。

第 2 步

貼上下列的 script 代碼到純文字編輯器中,將它儲存為「rename.php」,並放在論壇的根目錄底下(與 config.php 同一層)。

代碼: 選擇全部

<?php
/**
* This script will copy all attachments from the attachment folder (default
* "files") to a separate directory, replacing the cryptic phpBB filename with the
* original filename, prepended by numeric attach_id to prevent duplicate filenames.
*/

/**
* @ignore
*/
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);

// Name of script - change if you use a different name for the script
$scriptname = 'rename.php';
// Specify the number of attachments to copy in one run - reduce if you receive a timeout from server
$interval = 100;
// Specify the path for the copies - must have write access (CHMOD 777)
$copypath = 'filebackup';

// read id of last attachement copied
if (isset($config['last_attach_id']))
{
   $last_attach_id = $config['last_attach_id'];
}
else
{
   $last_attach_id = 0;
   set_config('last_attach_id', 0);
}

// count number of attachments to process
$sql = 'SELECT COUNT(attach_id) AS num_attach
    FROM ' . ATTACHMENTS_TABLE . '
WHERE attach_id > ' . (int) $last_attach_id . '
ORDER BY attach_id ASC';
$result = $db->sql_query($sql);
$attachs_count = (int) $db->sql_fetchfield('num_attach');

// Output Information
echo dheader();

// read required information from attachment table
$sql = 'SELECT attach_id, physical_filename, real_filename
    FROM ' . ATTACHMENTS_TABLE . '
WHERE attach_id > ' . (int) $last_attach_id . '
ORDER BY attach_id ASC';
$result = $db->sql_query_limit($sql, $interval);

// how many attachment do we copy in this run?
$actual_num = $db->sql_affectedrows($result);
if ($actual_num == 0)
{
    // nothing to do
    $complete = true;
}
else
{
    $complete = false;
    if ($attachs_count <= $interval)
    {
        // this is the last run
        $complete = true;
    }
    while ($row = $db->sql_fetchrow($result))
    {
        // for each attachment
        //remember id
        $last_attach_id = $row['attach_id'];
        // build source filename including path (we fetch the path from config
        $source = $phpbb_root_path . $config['upload_path'] . '/' . $row['physical_filename'];
        // build destination filename including path
        $destination = $phpbb_root_path . $copypath . '/' . $last_attach_id . "_" . $row['real_filename'];
        // copy the file
        if (copy ($source, $destination))
        {
            // write info to user
            echo sprintf("<tr><td class='succ'>copy succesful:</td><td>%s</td><td>%s</td><td>%s</td></tr>", $last_attach_id, $source, $destination);
        }
        else
        {
            echo sprintf("<tr><td class='error'>copy failed:</span></td><td>%s</td><td>%s</td><td>%s</td></tr>", $last_attach_id, $source, $destination);
        }
    }
    // write last attachment id in config
    set_config('last_attach_id', $last_attach_id);
}
// finished
echo dfooter();

function dheader()
{
    global $attachs_count, $interval;
    if ($interval > $attachs_count)
    {
        $interval = $attachs_count;
    }
    $remain = $attachs_count - $interval;

    return '<html>
    <head>
        <title>copy ' . $interval . ' attachments in this run, ' . $remain . ' remain to copy</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf8">
        <style>
            a:visited {COLOR: #3A4273; TEXT-DECORATION: none}
            a:link {COLOR: #3A4273; TEXT-DECORATION: none}
            a:hover {COLOR: #3A4273; TEXT-DECORATION: underline}
            .error {COLOR: red; ; FONT-WEIGHT: bold}
            .succ {COLOR: green; ; FONT-WEIGHT: bold}
            body, table, td {COLOR: #3A4273; FONT-FAMILY: Tahoma, Verdana, Arial; FONT-SIZE: 12px; LINE-HEIGHT: 20px; scrollbar-base-color: #E3E3EA; scrollbar-arrow-color: #5C5C8D}
            input {COLOR: #085878; FONT-FAMILY: Tahoma, Verdana, Arial; FONT-SIZE: 12px; background-color: #3A4273; color: #FFFFFF; scrollbar-base-color: #E3E3EA; scrollbar-arrow-color: #5C5C8D}
            .install {FONT-FAMILY: Arial, Verdana; FONT-SIZE: 20px; FONT-WEIGHT: bold; COLOR: #000000}
        </style>
    </head>
    <body bgcolor="#3A4273\" text="#000000">
        <table width="95%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
            <tr>
                <td>
                    <table width="98%" border="0" cellspacing="0" cellpadding="0" align="center">
                        <tr><th colspan="4">copy ' . $interval . ' attachments in this run, ' . $remain . ' remain to copy</th></tr>
                        <tr>
                            <th>Status</th><th>Attach_ID</th><th>phpBB internal file name</th><th>Copy with original file name</th>
                        </tr>';
}

function dfooter()
{
    global $scriptname, $complete;
    if (!$complete)
    {
        $next_step_link = '<a href="' . $scriptname . '">Click to continue with next step</a>';
    }
    else
    {
        $next_step_link = "<b>Completed</b>";
    }

    return '<tr><td colspan="4" align="center">' . $next_step_link . '</td></tr>
                    </table>
                </td>
            </tr>
        </table><br>
    </body>
</html>';
}

?>
在瀏覽器的網址列執行這個 script,例如:「http://www.example.com/[board_root_fold ... rename.php」。

這個 script 將複製以及重新命名所有的附加檔案(縮圖除外)到新的「filebackup」資料夾中。
為了防止重複的檔名(例如:也許有兩個會員都使用了 abc.jpg),將由 attachment_id 作為檔名的前綴。

這個 script 提供所有複製的檔案之詳細輸出,而且它可以多次地使用。
只需按 [F5] 重新啟動,或按照第一次運行後,在頁面底部的連結進行。

第 3 步

運行完成後,您可以從「filebackup」資料夾,下載所有使用「真實的名稱」之附加檔案。

注意

如果您在運行 script 時得到一個錯誤,那麼您可以減少複製(只是減少在 script 的 $interval 值)。
如果您有一個大數目的附加檔案,那麼您可以增加 $interval - 只測試適合您需求的值。
請記住,當您有大量的附加檔案,那麼您可能會碰上 php-超時。如上所述,盡量減少 $interval 值。
當它運行時, script 在資料庫中設定一個值,所以如果再次運行該 script,只有上回最後一次運行複製後,新增的附加檔案被增加到論壇。
如果您需要重新複製所有的附加檔案,那麼您可以運行下列 SQL 查詢,以重新設定資料庫中的值:

代碼: 選擇全部

UPDATE phpbb_config SET config_value = 0 WHERE config_name = 'last_attach_id'; 
那裡的 phpbb_ 是您的資料庫的資料表之前綴。參見 Executing SQL Queries in phpMyAdmin

也感謝 t_backoff、Noxwizard、stevemaury 以及 marc1706 對於這篇文章的貢獻。

--
資料來源:
http://www.phpbb.com/kb/article/backing ... filenames/

--
p.s.
根據實際測驗,運行此 script 時,如果您上傳的附加檔案使用中文檔名,那麼會出現錯誤。
施比受有福,祝福您好運! ^_^
歡迎光臨★★心靈捕手★★ :: 討論區
https://wang5555.dnsfor.me/phpBB3/
頭像
rex
版面管理員
版面管理員
文章: 501
註冊時間: 2001-11-01 15:28
來自: 竹貓星球
聯繫:

Re: 以附加檔案原來的檔名做備份

文章 rex »

感謝捕手老師撥空將該篇文章中文化 :-D
p.s.
根據實際測驗,運行此 script 時,如果您上傳的附加檔案使用中文檔名,那麼會出現錯誤。
應該是主機環境的關係?
我這邊實際測試使用正常,無出現相關錯誤訊息,檔案也可使用。
螢幕快照 2013-01-10 下午3.43.45.png
全面支援 phpBB3.3.x 版本虛擬空間

台灣[不限流量]虛擬主機
*可自由調整php 版本。
*免費 SSL 簽章。
https://kukan.tw/
回覆文章

回到「3.0」