Wordpress

外掛顯示不相容 WooCommerce HPOS?停用前先查警告是真是假

多數人看到 WooCommerce 後台跳出「這支外掛不相容 High-Performance Order Storage,請停用」的紅字,直覺反應是照辦,把整批被點名的外掛一次停用,只要下單流程還能跑就算過關。這是 WooCommerce HPOS 上線後最常見的處理方式,問題是,清單裡有些外掛其實運作正常,一停用反而讓結帳流程少了一塊功能,甚至讓已經上線的訂閱或促銷邏輯整個斷掉。

WooCommerce HPOS(High-Performance Order Storage,前身叫 Custom Order Tables)把訂單資料從 WordPress 共用的wp_postswp_postmeta,搬進四張 WooCommerce 專屬的資料表,這個底層搬家動作本身沒有問題。真正該弄清楚的是「不相容」這三個字背後的判斷邏輯,其實只在檢查外掛有沒有主動申報,不是 WooCommerce 真的把每支外掛裝上去實測過一輪。搞懂這層機制,才知道哪些警告該認真處理,哪些只是外掛作者還沒補一行程式碼。

WooCommerce HPOS 是什麼?訂單資料搬出 wp_posts 之後的架構改變

在 WooCommerce 的外掛清單頁,一次看到十幾支外掛被標成「不相容」並不少見,原因通常出在一個更底層的架構改動,也就是高效能訂單儲存(High-Performance Order Storage,以下稱 HPOS)。這套機制的前身叫 Custom Order Tables,核心做法是把訂單資料從 WordPress 所有文章類型共用的wp_postswp_postmeta,搬進四張 WooCommerce 專屬的資料表:wc_orders存放訂單本身的主資料,包括狀態、金額、下單時間這類核心欄位;wc_order_addresses存放帳單與收件地址;wc_order_operational_data存放內部運作狀態,例如是否已同步到舊表這類旗標;wc_orders_meta則扮演擴充角色,功能類似舊架構裡的postmeta,讓外掛可以掛自己的欄位上去。

HPOS 把訂單資料從 wp_posts、wp_postmeta 搬進 wc_orders 等四張 WooCommerce 專用資料表,各自存放訂單主資料、地址、運作狀態與擴充欄位
HPOS 啟用後,訂單改存進 wc_orders 這四張專用表,外掛若還讀 wp_posts、wp_postmeta 舊表就會對不上資料。

WooCommerce 自 8.2 版起(2023 年 10 月發布)把 HPOS 列為穩定功能,新安裝的站台會直接以這套架構為預設值。原訂在 8.0 版(同年 8 月)就要全面預設啟用,官方在高流量的實測站台上先發現問題,決定延後兩個版本再上線,這代表 HPOS 從一開始就不是切一次就結束的動作,而是持續在調整的機制。目前它仍是可選架構,新舊兩套資料表可以並存,WooCommerce 沒有訂出強制淘汰舊表的時間表;近期一個例子是訂單資料快取(Order DataStore Caching),這項最佳化功能在 2025 年 1 月以功能開關的形式先進入實驗階段,直到同年底的 10.4 版才轉為正式選項,連核心團隊自己都還在持續微調這套架構底層的運作方式。

外掛之所以會被標成不相容,根源就在這次搬家動作。只要外掛的寫法是繞過 WooCommerce 提供的 CRUD 介面,直接呼叫 WordPress 原生的get_post()get_post_meta()或用WP_Query去查訂單,資料就會對不上,它讀寫的目標仍是舊表,可是系統的權威資料已經搬到新表去了。

不相容警告未必代表外掛真的無法運作

後台跳出的紅字,看起來像是 WooCommerce 親自把每支外掛都裝上去測過一輪,結果才判定不相容。實際的判斷邏輯簡單得多,幾乎全部建立在外掛有沒有主動申報這件事上,跟這支外掛的程式碼寫得好不好、會不會真的壞掉,是兩回事。

官方文件把這套宣告機制說明得很具體。外掛要在主檔案裡,透過before_woocommerce_init這個掛鉤呼叫FeaturesUtil::declare_compatibility(),把要宣告的項目(HPOS 對應的代號是custom_order_tables)、外掛自己的檔案路徑,以及一個布林值傳進去,布林值填true代表宣告相容,填false就是明講不相容。這行程式碼,是唯一決定後台會不會跳警告的關鍵。

官方文件裡還有一句更關鍵的但書。因為很多 WordPress 外掛根本跟 WooCommerce 無關,WooCommerce 只會對在外掛主檔案的檔頭寫了「WC tested up to」這個欄位的外掛顯示相容性資訊。換句話說,一支外掛之所以沒被標不相容,可能不是因為它真的相容,只是它連被檢查的資格都沒有,作者根本沒在檔頭寫上那個欄位,系統也就不會去問它支不支援 HPOS 這個問題。反過來,一支外掛被標成不相容,代表的也只有兩種情況其中之一:作者明確申報了false,或者作者有申報資格卻什麼都沒申報,系統把沒申報當成不相容處理。

不只如此,連 WooCommerce 自己的 GitHub 問題追蹤器裡都留著已知的誤判案例。有開發者回報,自己的外掛已經在主檔案清楚呼叫declare_compatibility()並把第三個參數設成true,後台卻仍持續跳出這支外掛不相容高效能訂單儲存功能、應予停用的警告,而且不能關掉。他在乾淨環境重現這個問題,只裝 WooCommerce 加上一支只有宣告程式碼的最小外掛,警告照樣出現,研判是掃描機制被外掛的檔名或檔頭裡「Manager」「Order」這類關鍵字誤判,而不是真的去解析程式碼判斷相容性。這代表被標不相容的清單裡,連系統自己都可能誤判,看到警告就直接停用或移除外掛,反而可能是白忙一場。

在外掛列表裡揪出被標記不相容的擴充套件

光懂這套判斷邏輯還不夠,你得知道自己網站上哪一批外掛真的被標了不相容,而不是每次都等到真的想切換 HPOS,才臨時去外掛清單裡逐支翻找。

WooCommerce 的後台其實準備了兩條路徑,不必用猜的。第一條路徑是透過設定頁面,只要系統偵測到目前啟用中的外掛裡有任何一支不相容 HPOS,WooCommerce → Settings → Advanced → Features這個頁面裡的 HPOS 選項就會被灰掉、無法勾選,旁邊會多出一個「檢視與管理」的連結,點下去就是完整的不相容清單。第二條路徑更直接,把自己網站的網域代進這串網址參數:plugins.php?plugin_status=incompatible_with_feature&feature_id=custom_order_tables,貼在後台網址列直接開,不用先繞去設定頁,一樣能看到同一份清單。

除了這兩條主動查詢的路徑,外掛清單頁本身平常就會顯示提示文字,不用特地去找,只要那支外掛真的被判定不相容,清單裡它自己的欄位下方就會多一行說明。也就是說,只要定期看一眼外掛清單頁,尤其是每次更新完 WordPress 核心或大量外掛之後,這個訊號本來就攤在眼前,不必等到動念切換 HPOS 才第一次注意到它。

WooCommerce 外掛清單用「與高效能訂單儲存不相容」篩選,列出被標記的外掛與「不相容、不應啟用」的警告
把 plugin_status=incompatible_with_feature 這串參數貼進後台網址,就能一次看到所有被標記不相容 HPOS 的外掛。

若手上這批外掛剛好牽涉到訂閱或預約功能,看到清單先別急著照單全停,這類外掛牽涉到另一個跟相不相容完全無關的問題,停用的時間點錯了,一樣會讓資料對不起來。清單只是起點,接下來要做的是逐一確認警告是不是真的準。

隔離外掛,逐一排除問題根源

有了清單,下一步是把「介面顯示不相容」這句話,轉換成這個警告準不準的具體判斷。這個過程分三個步驟依序做完,再決定要不要真的停用或退回舊表,直接看到警告就動手,反而可能砍掉一支其實運作正常的外掛,或錯過真正該處理的那支。

WooCommerce 官方給開發者的稽核建議,是拿一長串正規表示式(比對wpdbget_postget_post_metawp_insert_postupdate_post_meta這類字樣)去外掛的原始碼裡搜尋,只要出現這些字眼,就代表這支外掛直接碰觸了訂單資料,沒有走 WooCommerce 提供的 CRUD 介面。一般站主不見得看得懂程式碼,但接下來這三個步驟,可以在不讀程式碼的前提下,達到類似的判斷效果。

不讀程式碼排查 HPOS 不相容警告的三步驟:先做最小環境測下單、再比對版本紀錄的相容宣告、最後翻檔頭找 declare_compatibility
警告不一定是真的:照這三步從最小環境查到外掛檔頭,再決定要不要停用那支外掛。

步驟一,停用其餘外掛只留下嫌疑對象

先把後台裡除了 WooCommerce 本身和被標記的那支外掛以外,其餘外掛全部停用,做一次最小環境。接著重新走一次完整的下單流程,把商品加進購物車、結帳、確認訂單真的成立,也去後台看一下這筆訂單的狀態與明細有沒有正常寫入。如果問題在這個縮到最小的環境裡依然重現,大致就能排除是別的外掛互相打架造成的假警報。

如果縮到最小之後問題反而消失,就代表原本的狀況其實是兩支外掛搭配出問題,不是單一那支外掛本身有缺陷。這時候可以把停用的外掛一支一支加回來,每加一支就重新測一次下單流程,找出真正互相衝突的那一組,這比直接把清單上所有被標記的外掛全部移除,更能精準定位問題。

步驟二,比對版本紀錄裡出現過的相容宣告

打開外掛的更新紀錄,多數外掛在後台或官網都找得到 changelog,往回找有沒有出現「HPOS」「High-Performance Order Storage」或「custom order tables」這類字樣的版本說明。這類字眼通常代表開發者是在那個版本才補上相容性宣告,如果目前用的版本比那個時間點還舊,問題往往不是外掛不支援,是自己還沒更新到有處理過這件事的版本。

WooCommerce 在 2023 年延遲全面上線 HPOS 的公告裡,直接呼籲外掛開發者確保自己的外掛已經宣告 HPOS 相容,還在社群 Slack 開了一個專門頻道協助外掛作者處理這件事。這代表從 2023 年下半年起,多數仍在維護中的外掛陸續補上了宣告,版本紀錄裡查得到這個時間點。反過來說,如果一支外掛的更新紀錄從那之後就再也沒有新版本,警告多半是真的,不是誤判,是這支外掛已經停止維護,不會再有人幫它補上宣告。

步驟三,翻開外掛檔頭找相容宣告的程式碼

前兩步都做完,如果還是拿不準,剛好自己或身邊有人看得懂程式碼,就可以直接打開外掛主檔案,找before_woocommerce_init這個掛鉤底下有沒有呼叫FeaturesUtil::declare_compatibility(),官方給的標準寫法大致是這樣:

add_action( 'before_woocommerce_init', function() {
    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
            'custom_order_tables', __FILE__, true
        );
    }
} );Code language: PHP (php)

看的重點是最後一個布林參數,true是相容、false是不相容。這比只看外部清單準,因為前面已經講清楚,沒被系統標記的外掛,可能只是連被檢查的資格都沒有。翻遍整支外掛主檔案找不到這段程式碼,代表作者根本沒處理過 HPOS 相容性,不管介面上有沒有跳警告,都該當成高風險項目看待,優先安排更新或找替代方案。

同步模式讓外掛在新舊資料表之間有緩衝期可用

就算排查出某支外掛真的還沒支援 HPOS,也不代表只能二選一,馬上換掉這支外掛,或是放棄升級效能。WooCommerce 準備了一個緩衝機制,勾選Enable compatibility mode(同步模式)之後,訂單資料會同時寫進舊的wp_postswp_postmeta與新的 HPOS 專屬資料表,雙邊都留一份,讓還在用舊寫法讀資料的外掛暫時不會斷資料。

在 WooCommerce 進階功能頁勾選「啟用相容模式」,讓訂單同時寫進 WordPress 文章舊表與 HPOS 專用表
勾選「啟用相容模式」後,訂單會雙寫到新舊兩組資料表,讓還沒支援 HPOS 的外掛有緩衝期。

要注意的是,這是雙寫不是切換。啟用同步模式的當下,系統會先把既有訂單資料回填到另一組資料表,英文叫 backfill。這個回填動作由背景排程負責,wc_schedule_pending_batch_process會先檢查有沒有還沒回填的訂單,有的話就排入wc_run_batch_process這個動作,每次處理 25 筆,處理完會自動接著排下一批,直到全部同步完成。不想乾等背景排程慢慢跑,也可以在WooCommerce → Status → Scheduled Actions頁面找到這個排程,手動點選執行加速。

WooCommerce 把這兩組資料表定義成權威表與備份表的角色關係。啟用 HPOS 時,新的專屬資料表是權威表,負責實際的讀寫;舊的wp_postswp_postmeta退居備份表的角色,只被動接收同步進來的副本。關掉 HPOS 時,兩者的角色會互換過來。這裡有一條硬性限制,只要還有訂單處於待同步的狀態,系統就不會讓你切換權威表的角色,這是為了避免半套資料造成的不一致,也是為什麼一定要等回填跑完才能真正做切換這個動作。

對訂單量特別大的站台,光靠背景排程可能跑不完。WooCommerce 提供命令列指令wp wc hpos sync手動觸發同步、wp wc hpos verify_data驗證兩邊資料是否一致,官方自己拿一個 900 萬筆訂單的測試站示範,光是跑完同步就花了大約 1 週,這個時間量級,可以讓你在真正動手之前,先對自己的站台需要多久有個底。

訂閱與預約類外掛,停用時機比相容性更關鍵

排查相容性清單時,有一種外掛的問題跟前面幾節講的邏輯完全不一樣,很容易被忽略,那就是用自訂文章類型(custom post type)儲存資料的外掛,常見的例子是訂閱制或預約類功能。這類外掛的資料原本就存在 WordPress 共用的文章資料表裡,如果剛好在啟用 HPOS 的過程中被停用,之後才重新啟用,資料就會對不起來。這跟外掛支不支援 HPOS 完全無關,純粹是停用與啟用的時間點沒抓對。

WooCommerce 的官方文件白紙黑字提醒,在啟用 HPOS 之前,務必確認站上任何用到自訂文章類型的擴充套件都保持啟用狀態。原因不難理解,HPOS 啟用之後訂單資料搬到新的專屬資料表,但這類擴充套件建立的自訂資料,例如一筆訂閱紀錄或一筆預約紀錄,仍然留在原本的文章資料表裡,系統的判斷邏輯卻已經改成優先看 HPOS 那一組表。若這類擴充套件在遷移過程中被停用,重新啟用的時間點跟訂單資料遷移的時間點對不上,資料就會出現落差。

如果已經不小心先停用了這類擴充套件才啟用 HPOS,官方也給了補救流程。回到WooCommerce → Settings → Advanced → Features,把訂單資料儲存方式切回 WordPress posts storage(舊版),讓同步先跑完,等資料補齊之後,再重新切回 HPOS。整個補救等於是把時間順序重新走一遍,用先讓自訂文章類型的資料穩定下來、再談訂單搬家的順序,避免同一個落差再發生一次。

確認外掛真的不相容後,退回舊表儲存的做法

走完前面的排查,如果確認某支外掛真的還沒支援 HPOS,短期內也沒有替代方案可換,這裡要處理的是怎麼安全退回舊的wp_posts儲存方式,而不是直接把同步模式關掉,才發現訂單資料對不上。

官方給的退回步驟有先後順序。第一步先到WooCommerce → Settings → Advanced → Features確認同步模式是開著的,如果本來沒開,就要先開啟並等訂單資料在兩邊資料庫同步完成。第二步,同步完成之後,把訂單資料儲存方式切回 WordPress posts storage(舊版),這時候也可以順便決定要不要一併關掉同步模式。日後如果想重新啟用 HPOS,就照最開始的流程再走一次。有一個容易漏掉的小步驟,每次改完設定都要記得按儲存,不然前面確認的動作等於白做。

退回舊表只是暫時性的應對,不是問題就此解決。同一份文件也再次呼籲,強烈建議聯絡不相容擴充套件的開發團隊,請他們著手修正。這句話的意思是,退回舊表跟聯絡外掛開發者是同時要做的兩件事,不是先退回舊表把眼前的警告壓下去,就代表這件事已經處理完畢。

所有外掛過關才是切換正式版本的正確時機

排查、隔離、退回或等待更新,這幾步都做完之後,剩下的問題是,什麼狀態才算真的可以安心把 HPOS 設成正式的權威資料來源。答案不是同步跑完就可以,連 WooCommerce 自己實際操作切換時,也是分好幾個階段慢慢退場,不是一次到位。

官方指南建議,正式切換到 HPOS 為權威來源之後,先不要急著關掉同步模式,而是先透過一個 filter 關掉讀取時的同步:add_filter( 'woocommerce_hpos_enable_sync_on_read', '__return_false' )。這一步之所以要先做,是因為讀取時同步是整套機制裡最耗資源的部分。官方自己在高流量商店的實測案例裡,設定 HPOS 為權威來源之後僅僅 6 小時,就先關掉了這道讀取同步,確認運作正常、觀察大約 1 週之後,才透過設定頁面完全關閉同步,也就是取消勾選Enable compatibility mode。即使完全關閉同步,也還是能隨時透過wp wc hpos sync指令手動補回資料,不是走到這一步就沒有回頭路。

留意還沒宣告支援 HPOS 的外掛、主動聯繫開發者請他們補上宣告,這件事也不是切換完就結束的一次性動作。WooCommerce 自己都曾經因為在高流量站台實測發現問題,把原訂的全面上線時程往後延了兩個版本,連官方主推的核心功能都不會用介面沒跳警告這種粗略的判準來決定正式切換的時機,一般站主更沒有理由用同一套心態,看到清單空了就直接關掉同步、宣告大功告成。

從後台第一次跳出紅字警告,到真正把 HPOS 切成正式的權威資料來源,中間這幾層判斷,其實都在確認同一件事。警告只是一個提示,不是最終答案,真正該看的是外掛作者有沒有申報、申報的內容是什麼,以及自己的站台有沒有真的驗證過資料一致。把這幾層一步一步走完,效能升級跟外掛穩定,不必變成一個換一個的取捨。

常見問答

本區問答由 AI 依文章內容自動整理,僅供快速參考,正式內容仍以全文為準。

WooCommerce HPOS 把訂單資料搬到哪裡去?

HPOS 把訂單資料從 WordPress 共用的 wp_posts 與 wp_postmeta,搬進四張 WooCommerce 專屬資料表,分別存放訂單主資料、地址、運作狀態與擴充欄位,不再跟其他文章類型共用資料表。

外掛顯示不相容 HPOS,是不是代表一定會壞掉?

不一定。這個警告幾乎全部建立在外掛作者有沒有主動申報相容性,跟外掛程式碼寫得好不好、會不會真的故障是兩回事。沒被標記也可能只是外掛連被檢查的資格都沒有,不代表它真的相容。

怎麼查自己網站有哪些外掛被標不相容 HPOS?

有兩條路徑:一是到 WooCommerce 進階功能設定頁,若有外掛不相容,HPOS 選項會被灰掉並出現「檢視與管理」連結;二是外掛清單頁本身,只要那支外掛被判定不相容,欄位下方就會直接多一行說明文字。

同步模式(相容模式)在 HPOS 裡是做什麼用的?

勾選啟用相容模式之後,訂單資料會同時寫進舊的 wp_posts/wp_postmeta 與新的 HPOS 專屬資料表,雙邊都留一份,讓還在用舊寫法讀資料的外掛暫時不會斷資料。啟用當下系統也會先把既有訂單回填到另一組資料表,直到全部同步完成。

訂閱或預約類外掛在啟用 HPOS 時要注意什麼?

這類外掛用自訂文章類型儲存資料,跟支不支援 HPOS 無關,重點是停用的時間點。若在啟用 HPOS 過程中被停用、之後才重新啟用,資料就會對不起來,因為訂單已改看 HPOS 那組表,但訂閱或預約紀錄仍留在原本的文章資料表裡。

資料來源
  1. High-Performance Order Storage — WooCommerce
  2. HPOS Full Rollout Delayed — WooCommerce
  3. Order DataStore Caching — A new approach to optimize WooCommerce performance — WooCommerce
  4. WooCommerce 10.4: Pre-release updates — WooCommerce
  5. High-Performance Order Storage Recipe Book — WooCommerce
  6. HPOS Incompatibility warning persists despite explicit FeaturesUtil::declare_compatibility declaration — WooCommerce
  7. High-Performance Order Storage — WooCommerce
  8. High-Performance Order Storage: A Guide for Large Stores — WooCommerce
  9. HPOS CLI Tools — WooCommerce