程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> wordpress上傳圖片時重命名--修改插件時遇到的一些問題,wordpress上傳圖片

wordpress上傳圖片時重命名--修改插件時遇到的一些問題,wordpress上傳圖片

編輯:關於PHP編程

wordpress上傳圖片時重命名--修改插件時遇到的一些問題,wordpress上傳圖片


wordpress是用php語言開發的博客平台,它擴展性強,容易擴展,很適合拿來做二次開發。

1,問題由來

本周五,我在浏覽公司的網站(基於wordpress開發)時發現,網站首頁上有兩篇文章的縮略圖重復了,於是我進入網站後台檢查,想看下是不是某位員工在撰寫文章時不小心這兩篇文章選擇了相同的圖片作為封面圖片。

結果發現這兩篇文章選用的封面圖片的文件名還真是相同,但我轉念又想到,員工再糊塗也不至於犯這樣的錯誤。於是,我檢查了下這幾篇文章的封面圖片url地址,這些地址是相同的。

我想到,有可能是這兩張圖片的文件名相同(至於為什麼會出現這種情況,恐怕只有鬼知道),然後文件被上傳後,後上傳的圖片將前面上傳的圖片覆蓋,最後只有一張圖片留在了雲存儲的服務器上。

注:我寫了個插件,在上傳圖片時,可以將圖片上傳至百度雲的BOS上。

 

2,問題該如何解決

其實,一開始我是很糾結這個問題的:是讓編輯文章的員工下次注意,每次上傳圖片時都要按年月日時間、加序號和圖片其它信息將圖片重名後再上傳呢,還是自己默默的在自己寫的插件裡加上一些代碼把圖片重命名呢?

好吧,寫到這裡,你肯定能猜到我做了什麼樣的選擇?寫代碼吧。

 

3,曲折的過程

我的插件原來只負責把圖片上傳到百度雲的BOS上,然後把本地圖片刪除,主要用到了wordpress的wp_update_attachment_metadata鉤子。我在這個鉤子裡調用了一個自己定義的函數upload_attachement_to_bos,

這個函數就負責把圖片上傳到BOS並刪除本地圖片。一開始,我一直在想如何在這個函數裡做文章:把原圖重命名,把縮略圖重命名,額,試了半天都沒有效果。我檢查了下BOS上的圖片,上傳成功、文件名也是修改後的。

可是為什麼網站的圖片url地址還是沒變?

不能著急,先去媒體庫下面看下圖片,結果發現媒體庫的圖片文件名、標題、url中的名稱都還是原來的文件名。

我雖然把服務器上的文件名都改了,但數據庫中與圖片有關的字段的值都沒有改。於是,我嘗試更改wordpress的數據表,來看媒體庫和文章縮略圖中的圖片文件名是否有變化。

期間,我試著修改post表中的postname、post_title、guid字段,然而並沒有用。postname:文章的別名,顯示在url地址中,一般可用來美化url地址,post_title:與媒體庫中,附件詳情表單頁面中的圖片標題對應,就相當於文章標題,

guid:這個,說實話,我也不知道它有什麼用,好像是文章的唯一標識。

我最後定位到postmeta表中的meta_key: _wp_attached_file對應的meta_value。這個_wp_attached_file的值會影響文章附件的相關信息,如媒體庫中的附件詳情頁中的圖片url、文件名都是取的meta_value值

另外就是wordpress主題(據我測試的有限的幾個主題)下首頁文章縮略圖、文章單頁中的頭圖url中的文件名都是取的這個值。

好,總算找到病根了,剩下的問題就是如何把這個值給修改掉。

 

4,問題暫時解決,但還有一些遺留問題

前面說到了,我用到了wp_update_attachment_metadata鉤子,於是我在對應的鉤子函數裡做文件名修改、更新_wp_attached_file的工作。鉤子函數代碼大致如下:

1 // 鉤子函數: 重命名文件,更新文件meta信息,調用上傳函數,並將上傳的原圖在bucket下的路徑信息保存到數據庫 2 function update_attachment_metadata($data, $post_id) { 3 /* 重命名文件防止沖突 */ 4 date_default_timezone_set('PRC'); 5 $wp_upload_dir = wp_upload_dir(); 6 $old_path = $wp_upload_dir['basedir'] . '/' . $data['file']; 7 $ext = pathinfo($old_path, PATHINFO_EXTENSION); 8 $old_namestr = str_replace('.' . $ext, '', basename($data['file'])); 9 $new_namestr = date('YmdHis-') . dechex(mt_rand(100000, 999999)); 10 $new_path = $wp_upload_dir['path'] . '/' . $new_namestr. '.' . $ext; 11 12 rename($old_path, $new_path); 13 14 if (isset($data['sizes']) && count($data['sizes']) > 0) { 15 $thumb_data = &$data['sizes']; 16 foreach ($thumb_data as $key => $thumb) { 17 $old_thumbpath = $wp_upload_dir['basedir'] . '/' . substr($data['file'], 0, 8) 18 . $thumb['file']; 19 $new_thumbpath = str_replace($old_namestr, $new_namestr, $old_thumbpath); 20 if (file_exists($old_thumbpath)) { 21 rename($old_thumbpath, $new_thumbpath); 22 } 23 } 24 } 25 /* 更新data中的文件名 */ 26 $old_jsdata = json_encode($data, JSON_UNESCAPED_UNICODE); 27 $new_data = json_decode(str_replace($old_namestr, $new_namestr, $old_jsdata), true); 28 29 unset($data, $old_jsdata); 30 31 $ori_object_key = upload_attachement_to_bos($new_data, $post_id); 32 // 將原始圖片在BOS bucket下的路徑信息(object信息)添加到數據庫 33 add_post_meta($post_id, 'bos_info', $ori_object_key); 34 35 /* 更新數據庫中postmeta表中_wp_attached_fies的值 */ 36 $old_meta = get_post_meta($post_id, '_wp_attached_file', true); 37 update_post_meta($post_id, '_wp_attached_file', str_replace($old_namestr, $new_namestr, $old_meta)); 38 39 return $new_data; 40 } View Code

關鍵是36、37行修改postmeta表中的_wp_attached_file值,然後需要注意的是,我這裡對函數的返回值進行了處理,返回的$new_data數組是替換文件名後的數組,我暫時還不知道這麼做會不會產生什麼副作用。

然後,我把插件代碼更新了下。嗯,插件起作用了,重命名功能實現,原有功能沒被破壞。

 

5,其他啰哩啰嗦的問題

(1)代碼中的$data數組是一個多維數組,多維數組做字符串替換該怎麼做呢?str_replace()函數好像只能替換一維數組。我在代碼裡用的是將數組轉化為字符串再替換的方法,用到了json_encode()和json_decode(),不知道還有沒有其他更好的方法。

(2)文件重名的的方法rename(),在對文件重命名之前要先判斷文件是否存在和文件夾權限(或者權限不夠時,修改文件夾權限),我這裡沒有做。

 

ps:我寫的這個wp-bos插件(支持wordpress使用雲存儲作為圖片的存儲空間,目前支持BOS百度雲存儲)托管在gitoschina和github上,

不過托管的代碼暫時還沒有將重命名的功能加入,等到插件在網站上運行一段時間沒有問題後,我會及時將更改push上去,感興趣的朋友可以關注下。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved