以前,使用者在論壇中發一些圖片,會有一部分是從其它的站點直接複製內容過來,這樣複製過來的圖片只是一個附件地址,儲存在主題和帖子內容中,一旦其它站點開啟防盜鏈或改動圖片附件的資料夾位置,就會造成圖片不能正常顯示甚至死鏈。同時對站長自己附件的管理也帶來了麻煩,影響網站執行效果。
Discuz!X2.0 中在編輯器中新增加了一鍵下載遠端圖片到本地的功能,一般預設點選 「高階」,在 「word「下面會有一個按鈕,髮帶有圖片地址的主題或帖子時,按下這個按鈕,就會把圖片下載到本地伺服器。
下面介紹一下這個下載到本地伺服器的過程。找到 source/module/forum/forum_ajax.php,大約 320 行:
- elseif($_G['gp_action'] == 'downremoteimg') {
- $_G['gp_message'] = dstripslashes($_G['gp_message']);
- $_G['gp_message'] = str_replace(array("
", "
", "
"), '', $_G['gp_message']); -
preg_match_all("/[img]s*([^[<
]+?)s*[/img]|[img=d{1,4}[x|,]d{1,4}]s*([^[<
]+?)s*[/img]/is",
$_G['gp_message'], $image1, PREG_SET_ORDER); - preg_match_all("/<img.+src=('|"|)?(.*)(1)([s].*)?>/ismUe", $_G['gp_message'], $image2, PREG_SET_ORDER);
- $temp = $aids = $existentimg = array();
這段程式碼是對內容 $G_[『gp_message』] 刪除由 addslashes() 函式新增的反斜槓,str_replace 替換換行符等,即還原文字;preg_match_all 是對文字中圖片幾種地址進行全域性匹配,結果儲存在 $image1 、 $ image2 中。初始化變數。
- if(is_array($image1) && !empty($image1)) {
- foreach($image1 as $value) {
- $temp[] = array(
- '0' => $value[0],
- '1' => trim(!empty($value[1]) ? $value[1] : $value[2])
- );
- }
- }
- if(is_array($image2) && !empty($image2)) {
- foreach($image2 as $value) {
- $temp[] = array(
- '0' => $value[0],
- '1' => trim($value[2])
- );
- }
- }
- require_once libfile('class/image');
這段是對匹配後的結果進行遍歷賦值,幷包含圖片處理類。
- if(is_array($temp) && !empty($temp)) {
- require_once libfile('class/upload');
- $upload = new discuz_upload();
- $attachaids = array();
- foreach($temp as $value) {
- …………………中間略去…………………
- if(!@$fp = fopen($attach['target'], 'wb')) {
- continue;
- } else {
- flock($fp, 2);
- fwrite($fp, $content);
- fclose($fp);
- }
- if(!$upload->get_image_info($attach['target'])) {
- @unlink($attach['target']);
- continue;
- }
這一段的目的是對下載下來的附件進行地址、圖片資訊、縮圖等進行處理,並寫入檔案儲存,並且判斷是不是圖片,如果不是,則刪除----unlink($attach['target']); 。
- $attach['size'] = filesize($attach['target']);
- $upload->attach = $attach;
- $thumb = $width = 0;
- if($upload->attach['isimage']) {
- …………………中間內容省略………………………
- $aids[] = $aid = getattachnewaid();
- $setarr = array(//得到圖片附件相關資訊
- 'aid' => $aid,
- 'dateline' => $_G['timestamp'],
- 'filename' => daddslashes($upload->attach['name']),
- 'filesize' => $upload->attach['size'],
- 'attachment' => $upload->attach['attachment'],
- 'isimage' => $upload->attach['isimage'],
- 'uid' => $_G['uid'],
- 'thumb' => $thumb,
- 'remote' => '0',
- 'width' => $width
- );
- DB::insert("forum_attachment_unused", $setarr);//入庫
- $attachaids[$hash] = $imagereplace['newimageurl'][] = '[attachimg]'.$aid.'[/attachimg]';
- } else {
- $imagereplace['newimageurl'][] = $attachaids[$hash];
- }
這段是把圖片附件的資訊進行處理,透過 getattachnewaid 函式把主題或帖子相關圖片資訊插入附件表。
- if(!empty($aids)) {
- require_once libfile('function/post');
- ftpupload($aids);
- }
- $_G['gp_message'] = str_replace($imagereplace['oldimageurl'], $imagereplace['newimageurl'], $_G['gp_message']);
- $_G['gp_message'] = addcslashes($_G['gp_message'], '/"');
- }
最後這段就是真正把圖片附件上傳到自己本地伺服器,並將文字再 addcslashes 處理。