profile

WordPress 開發日常

除錯的意義

Published 6 months ago • 1 min read

上週五工作到一半,家裡的門鈴響起,開門後是衛生局的人員通報說社區附近出現登革熱案例,需要整棟樓進行消毒,正當我想著那我就不要出門就好,結果想不到對方說連屋內都要消毒時,我一整個傻眼,家裡這麼多吃的穿的睡的,全部都要暴露在殺蟲劑下,一想到頭就暈。

第一時間先上網查一下這是不是新型態的詐騙手法,才知道原來對臺南人來說這已是司空見慣的作業流程,還查到「養生膠帶」這個神器,它可以把大型傢俱鋪上一層塑膠袋作為防護,於是當晚趕快去水電行買了兩捲,想說隔天早上再蓋就好。

到了隔天一早九點,大樓就傳來噴藥機的巨大聲響,衛生局人員敲每戶的門,說要開始進行消毒了,那時候我們才剛吃完早餐,一整個被殺個措手不及,只好趕快把養生膠帶鋪上,但因為太趕,很多傢俱都沒有鋪到,就這樣半推半就的被請出家裡。

坐進電梯前看到消毒人員拿著在戶外消毒水溝的大型噴藥機直接在家裡面狂噴,不知為何有種荒謬感,好像我家是喪屍病毒外洩的實驗室必須徹底消毒一番,然後跟著鄰居們一起被迫撤離家園,似乎也拉近了鄰居之間的距離(?)

就這樣在外面待了半小時後回到家中準備進行清掃,一進門就被殺蟲劑的味道嗆到一直咳,只能把所有門窗打開用電風扇狂吹,然後依序拆下養生膠帶並把每個傢俱都用酒精擦擦過一遍,地板因為還有殘留所以很濕滑,必須要先用靜電拖拖過一輪。

第一輪收拾殘局就花了一個多小時,接下來開始每週的例行打掃,掃完後開始洗衣服跟床單,前前後後花了三個小時才恢復世界和平,打掃過程中就只有撿到一隻小小強,好像在跟我證明說消毒是有用的。

在實體世界消完了毒,數位世界的蟲依舊每天出現,真希望也有台噴藥機可以一次幫我搞定 Debug 啊~

除錯的意義

在忙完了 WordCamp 之後,我調整了自己的工作節奏,從原先做二休一,改成做五休二,把之前累積的工作放在早上集中力最高的三小時來處理,然後上午做完後就下班了,下午看是要繼續弄產品,還是去跑個步動一下。

這樣的節奏在第一週運作的很順利,看到專案每天都有進展對客戶也有所交代,但到了第二週開始有些狀況,下午的時間常收到客戶的緊急回報,因為這些問題會影響到客戶當晚的作業流程,因此我會放棄下午的行程優排除客戶的問題。

檢查後才發現是第一週開發的功能所影響的,這些新功能開發完成時雖然我都有進行測試,並且確認可以正常運作後才交付,但這週遇到的問題是我完全沒想到的情境,我沒有預料到做了 A 功能竟然會造成 B 功能的錯誤,於是只能當客戶在實際使用時才發現問題。

這樣的狀況持續了幾天,結果變成一整天都在處理專案,上午開發下午除錯,就讓我反省為什麼會有這些臭蟲的發生?難道這些蟲是無法避免的嗎?就算無法避免有沒有更好的通知機制能讓我第一時間就知道?

因此我想藉由這篇文章來分析一下這週遇到的問題,並且提出可能的解決之道。情境是這樣:

因為 wp_postmeta 資料表已經儲存百萬筆的資料,在載入文章編輯頁的時候速度變得很慢,原先的欄位是用 ACF Repeater 開的,這些資料每天都會有數百筆的增長,因此我跟客戶提議把這些資料拉出來,新開一個自訂資料表來存放以及查詢,並且用 WP_List_Table 來彙整所有資料,不用點進各別文章查看。

我將本週遇到的問題類型分為以下三種:

ㄧ、原本應該發生的行為沒有觸發

重構前有一個功能是可以在前台寫入這個資料,然後在寫入後會觸發第三方的 API 做事情,結果重構後觸發 API 的行為沒有發生。觀察我自己的重構方式是在加入新的寫入方式後,把原先舊有的程式碼全部註解掉,結果我以為註解掉的部分就只有寫入資料的功能,想不到觸發 API 的程式碼也被我一併刪了。

舊版寫入資料的方法有將近四十行程式碼,觸發第三方 API 僅有六行,因此一整遍看過去會以為這四十六行就是只有處理寫入資料,而忽略了觸發 API 也在裡面。想到幾個可以改善的地方是:

  1. 把寫入資料的程式碼包裝成方法或函式,這樣在視覺上就會是一個獨立的事件而非一連串的行為
  2. 增加明顯的程式碼註解,帶有開頭跟結尾,並且把空行的間距加大,讓自己可以很明顯的看出處理同一功能的區塊開頭與結尾
  3. 增加返回的型別提示,確實定義每個任務執行完後要回傳的是什麼資料型態,以這個例子來說,寫完資料觸發 API,要回傳的應該是 WP_HTTP_Response 物件,如果我有指定的話,在測試重構後的方法我就可以即時知道回傳東西有誤,進而發現到我漏了觸發 API 的行為

事實上我有時候都會懶得把一連串的程式封裝成方法或函式,因為每多一個函式就要多寫程式碼,像是函式的命名、帶入參數的定義、返回資料類型、註解說明,尤其是要找問題的時候必須在多個函式之間切換很麻煩,但為了程式碼的維護性,還是要逼自己養成這個習慣才行。

還好在我改用 PhpStorm 之後裡面有一個很貼心的重構功能,可以把選取的程式碼直接變成函式:

點下之後就會在同一個檔案的最下方加入新的方法,他還會自動所需要的參數帶入,並且寫好參數的註解,算是省下不少手動輸入的時間,另外在查看函式的部分,只要把游標停留在函式上,按住 cmd + 滑鼠點擊,就會自動跳到定義該函式的區塊或檔案以方便查看。

有了這兩個實用的功能應該不能再用麻煩當藉口了,乖乖的把程式碼封裝起來吧!

二、重構不完整

新功能有一個方法是檢查特定的 user id 是否有在新建立的資料表中,藉此取代原本判斷 user id 是否存在於 Post Repeater 欄位中的邏輯,這部分我已經有獨立一個方法來做判斷,因此我是直接替換這個方法裡面的判斷邏輯。

結果想不到除了這個方法以外,還有一支散落於某處的函式也是在處理一樣的功能,結果我只改了方法沒改到函式因此發生問題,這讓我學到在重構方法前,記得先用全站搜尋功能來尋找原始的 user id 判斷邏輯有寫在哪寫地方,然後列出所有的方法與函式。

更好的做法是要將這些重複的地方整合為一個方法,就能避免改了 A 忘了 B,趁著這次除錯就可以順手把這件事做起來,如果時間趕可以先寫個註記,萬一之後又要調整就不會漏了它。

三、預期外的 save_post 勾點

新增資料的部分我是用 ACF 設定頁來處理,這樣就可以省下開一堆欄位的時間,然後當儲存後抓欄位值寫入資料,一般儲存文章的勾點是 save_post,而 ACF 的是 acf/save_post,問題出在我為了要判斷當下儲存的頁面是 ACF 設定頁,因此用了 get_current_screen() 來取得目前所在頁面,當頁面 ID 等於我的設定頁 ID 時才會執行資料寫入。

因為這個勾點的名稱我預期是只有在儲存 ACF 設定頁面才會觸發,為了精簡程式碼我把 get_current_srceen() 的判斷拔掉了,想說應該不需要這層判斷,但沒想到一般文章在儲存時也會觸發到,這導致寫入資料表時少了必要欄位而噴錯,造成客戶沒有辦法在後台更新文章。

於是還是乖乖的把判斷加回去,但第二個問題來了,因為我有用另外一個 ACF 設定頁以表單的方式放在前台供客戶使用,在前台因為沒有 get_current_srceen() 這個方法,因此設定頁 ID 的判斷會出錯,要先用 function_exists() 來判斷函式是否存在,才能繼續做設定頁 ID 的判斷。

第一個問題我想到的解決辦法就是用任何勾點前先去爬一下原始碼,看他們會在哪裡被觸發,使用 PhpStorm 並且有設定 WordPress 為專案環境的話,在每個勾點前面都可以看到一個小 h 的圖示,點擊後就會直接前往勾點定義的來源:

第二個問題的解法是在使用 WordPress 內建的函式時,要先意識到該函式是否有前後台的區別,如果懶得想最快的解法就是用之前一律做 function_exists 判斷就不會錯了,然後當回傳 false 時直接返回終止程式執行。

-

回想我的除錯過程都是客戶貼重大錯誤的截圖給我,然後我再進主機或是網站後台去查看錯誤日誌,然後從裡面尋找程式出錯的地方,我就在想不知道有沒有更快速的方法可以得知問題在哪,爬了一下找到這個解:https://www.businessbloomer.com/woocommerce-email-fatal-error/

研究後才知道原來 PHP 有 register_shutdown_function 函式,而 WooCommerce 就是利用這個函式來來做錯誤日誌的紀錄,並且在裡面放 woocommerce_shutdown_error 的勾點,就能實現當 500 Error 時收到通知,而不用從伺服器底層處理。

我期許自己在除錯的時候不是只要把眼前的問題解決就好,而是有餘裕去反思為何這個問題會發生,並且在除完錯的當下重構程式碼來避免再次出現,甚至可以改進工作流程來減少緊急狀況的發生,為了努力實現只上半天班,一定要將重大錯誤發生的頻率降低才行啊~

WordPress 開發日常

Read more from WordPress 開發日常

每次遇到想要跟我學習 WordPress 外掛開發的朋友來信,總是只能丟些教學文件給他們,畢竟我也不知道他們想做什麼東西,只能提供官方文件給他們參考,雖然這幾年來也寫了不少,但好像都缺少比較完整的開發教學。 想到之前為了教老婆開發而整理出的一套課程大綱,似乎有這個契機可以把它發展下去,但如果只是講理論而沒應用好像無法立即派上用場,於是想到可以整合之前寫過的小工具作為內容,就可以設計出真的能做出東西的教材。 剛好上週為了除錯的事情順手寫了一支日誌外掛,整合理論與實務的教學計畫如下: -- 前言 日誌紀錄是開發者與網站維護人員最重要的好夥伴,除了可以在開發當下輸出執行結果來確認程式的邏輯外,當網站發生錯誤時也能從紀錄中去檢查問題所在原因。查看 WooCommerce 的日誌紀錄步驟為:進入後台側選單 > 點選 WooCommerce > 狀態 > 日誌紀錄 > 選擇日誌檔 > 查看,就會顯示相關的資訊。 一、WooCommerce 內建日誌紀錄的問題 WooComerce 內建的日誌有以下幾個痛點: 選單的目錄層級過多,日誌檔太多時東西不好找...

6 months ago • 1 min read

這兩週在忙著準備 WordCamp 簡報以及擺攤相關事宜,雖然既累人又噴錢,但過程還是充滿了樂趣,我弄了宣傳 DM、易拉展、桌上立牌,以及手工裁切貼紙,好久沒做平面設計了,光設計一份 DM 就搞了五小時。 我是用 Figma 做的,由於它是專門用來做介面設計的,因此色彩模式並沒有 CMYK,所以只能用 RGB 輸出,為了要精準還原電腦上的顏色,前前後後不曉得打樣了多少次,最後還是睜一隻眼閉一隻眼讓它過了,不然可能花上七天七夜還搞不定… 明天就是期待已久的 WordCamp Taiwan,我覺得身為聽眾真的超幸福,只要人到屁股坐下,就能獲得這些講者們累積好多年的經驗與知識,會後還能去扒著他們不放問問題,光這樣想就覺得值回票價,我想分享一下身為開發者的我會去聽哪幾場,以及我是如何認識這些大大的: 上午 9:30 - WordPress 社群中的成長旅程 by Eric 在 WordCamp Keynote 由台灣人主講印象中這還是頭一次,我覺得這超棒的,以往的 Keynote 都是由 WordPress 官方代表來負責,通常會宣傳新的功能或是官方想要傳達的主題,這次是由 Eric...

7 months ago • 1 min read

如果你有在用這幾年出的 Mac 軟體,應該對於啟動器 ( Launcher ) 不陌生,只要輸入快速鍵 Command + K,就會出現一個很像 Google 首頁的搜尋框,或是 MacOS 內建的 Spotlight。 這個搜尋框可以輸入關鍵字進行相關資訊的搜尋,並且將結果顯示在啟動器的下方,就能用鍵盤上下鍵去切換要進一步查看的內容,選定後才會開啟瀏覽器前往頁面或執行特定動作,這對於很懶得用滑鼠的我來說超方便。 而這功能在今年也流行到 WordPress 生態圈,在更新 6.3 版本後多了「命令選擇區」,它也是類似的功能,可以在搜尋框輸入相對應的關鍵字,像是新增頁面或新增文章,點擊後就會自動進入該頁面,就不用操作滑鼠點選新增文章的按鈕。 關於命令選擇區在 2023 WordCamp Taiwan 將有一個專門的議程來介紹,主講者是非常資深的 WordPress 工程師昱程大大,想要了解這個功能可以對於網站管理員帶來什麼改變的話,鎖定 10/14 下午三點二十分的議程「如何使用命令選擇區 (Command Palette)來提升網站使用者體驗?」就沒錯了!...

7 months ago • 1 min read
Share this post