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

来源:http://www.cnblogs.com/yangtoude/archive/2016/11/12/6057545.html
-Advertisement-
Play Games

wordpress是用php語言開發的博客平臺,它擴展性強,容易擴展,很適合拿來做二次開發。 1,問題由來 本周五,我在瀏覽公司的網站(基於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百度雲存儲)托管在gitoschinagithub上,

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、簡介 EventBus是一個Android端優化的publish/subscribe消息匯流排,簡化了應用程式內各組件間、組件與後臺線程間的通信。比如請求網路,等網路返回時通過Handler或Broadcast通知UI,兩個Fragment之間需要通過Listener通信,這些需求都可以通過Eve ...
  • 1、簡介 ButterKnife是註解中相對簡單易懂的很不錯的開源框架 1.強大的View綁定和Click事件處理功能,簡化代碼,提升開發效率 2.方便的處理Adapter里的ViewHolder綁定問題 3.運行時不會影響APP效率,使用配置方便 4.代碼清晰,可讀性強 2、下載地址 https: ...
  • 有不足之處,請大家指出 一、 基礎知識 1、SDK的最新下載 搜索oracle,進入網站,à Downloads –> JavaSEI à 選第一個下載(其實java 8u111和8u112的區別就是在8u111的基礎上優化了一下,升了下級,實際使用沒什麼區別的) 其次註意一下選32位還是64位,是 ...
  • 無限級分類是一種設計技巧,在開發中經常使用,例如:網站目錄、部門結構、文章分類。筆者覺得它在對於設計表的層級結構上面發揮很大的作用,比如大家在一些平臺上面, 填寫邀請人,它就是一種上下級的關係,上級會有多個下級,下級又會有自己的分支,大多數都是利用遞歸的思想去實現。話不多說,首先來溫故一下遞歸的實現 ...
  • 如果你還沒有搭建gtest框架,可以參考我之前的博客:http://www.cnblogs.com/jycboy/p/6001153.html。。 1.The first sample: sample1 你把github上的項目導來之後,github地址:https://github.com/goo ...
  • RPC即遠程過程調用,它的實現方式有很多,比如webservice等。框架調多了,煩了,沒激情了,我們就該問自己,這些框架的作用到底是什麼,來找回當初的激情。 一般來說,我們寫的系統就是一個單機系統,一個web伺服器一個資料庫服務,但是當這單台伺服器的處理能力受硬體成本的限制,是不能無限的提升處理性 ...
  • 一、設置一個新的測試項目 在用google test寫測試項目之前,需要先編譯gtest到library庫並將測試與其鏈接。我們為一些流行的構建系統提供了構建文件: msvc/ for Visual Studio, xcode/ for Mac Xcode, make/ for GNU make,  ...
  • 背景說明 最近在工作項目中有下麵一個場景: 使用Node.js的express框架實現了一個文件系統伺服器端,其中有個API用於客戶端上傳文件。客戶端使用Node.js的HttpClient來調用伺服器端的API上傳文件。 客戶端在上傳小文件時沒有任何問題,在上傳大文件時httpClient請求報錯 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...