最近嘗試把 joomla3 從PHP7升級到PHP8
結果AI 有些輸入參數上
叫我用 array_values 來過濾資料確保資料正確
結果就遇到有些用 event 參數的呼叫整個無效
然後我還卡這個BUG卡了將近一天
變成拿石頭砸自己的意思...
就是說
實際上
通常不需要再 array 傳入之前加上 array_values
尤其是一些名稱有衝突的情況
#########################################################################
array_values 會把 event 給刪除???
#########################################################################
![]()
這是一個很好的邏輯問題。答案是:它不會「刪除」內容,但它會「毀滅」鍵名(Key),這在 PHP 8 中會改變函數接收參數的方式。
讓我們拆解 array_values 到底對你的 $args 做了什麼:
1. array_values 的運作原理
假設你的 $args 原本長這樣(帶有字串鍵名):
$args = [
'name' => 'editor1',
'content' => '
Hello
',
'event' => 'onDisplay'
];
執行 $safeArgs = array_values($args); 後,內容變成:
PHP
$safeArgs = [
0 => 'editor1',
1 => '
Hello
',
2 => 'onDisplay'
];
內容(Value)都在,但「名字」(Key)不見了。
2. 為什麼這會影響 onDisplay 函數?
這就是 PHP 8 最核心的變更:參數匹配機制。
情況 A:直接傳遞 $args (PHP 8 的地雷)
當你執行 $this->onDisplay(...$args) 時,PHP 8 看到有 name 這個 Key,它會自動找 onDisplay 函數中名字叫 $name 的變數。
- 如果名字對得上:沒事。
- 如果 $args 裡多了一個 event 鍵:PHP 8 會去 onDisplay 找有沒有 $event 這個參數。
- 結果:因為你的 onDisplay 定義裡沒有 $event,PHP 8 就會大喊:「Unknown named parameter $event」,然後直接程式崩潰。
情況 B:使用 array_values($args) (傳統安全模式)
當你傳遞純數字陣列時,PHP 8 會放棄「按名找人」,回歸「按順序入座」:
- 第 0 個值給第 1 個參數 $name。
- 第 1 個值給第 2 個參數 $content。
- 第 2 個值給第 3 個參數 $width。
- 結果:你的 onDisplay 函數會把原本的 'onDisplay' 字串 當成 $width 填進去!
3. 這就是為什麼我建議「不要把 event 塞進 args」
如果你執行了 $args['event'] = $event;,這個 event 就變成了陣列的一部分。
- 如果你用 array_values:你的參數順序會全部大風吹(原本該是寬度的位置變成了事件名稱)。
- 如果你不消掉 Key:PHP 8 會因為找不到 $event 參數而崩潰。
4. 正確的處理 SOP
在 libraries/joomla/event/event.php 或 dispatcher.php 中,正確的做法應該是:
- 先取出 event 名稱,用來決定要呼叫哪個函數。
- 刪除 $args 裡的 event 鍵,避免干擾參數匹配。
- 轉換 為純數值陣列,確保 PHP 8 乖乖按順序傳參。
建議修改代碼:
public function update(&$args)
{
// 1. 備份並取得事件名稱
$method = $args['event'] ?? '';
// 2. 為了安全,把 'event' 從參數包裡拿掉,以免它佔位子或導致命名衝突
$tempArgs = $args;
if (isset($tempArgs['event'])) {
unset($tempArgs['event']);
}
// 3. 轉成純數字順序,傳給 onDisplay
$params = array_values($tempArgs);
if ($method && method_exists($this, $method)) {
return call_user_func_array(array($this, $method), $params);
}
}
總結
array_values 不會刪除數據,但它會讓 event 這個數據變成一個「無名路人」。如果它被排在陣列的最後面,而你的函數參數剛好夠多,它就會被填進錯誤的變數裡(例如寬度或高度)。
這解釋了為什麼你之前可能看到編輯器寬度變得很奇怪,或是方法找不到!
#########################################################################
![]()
如果問AI
把 joomla3 硬是升級到 PHP8版本
都會建議不要這樣做
如果遇到BUG還會一直勸我放棄
就是因為已經有套件依賴
不能隨便升級joomla版本阿...

然後升級PHP的建議有時候真的會有幻覺
他認為這樣對
實際上不是這個問題
AI都會想辦法從你的問題中找答案
但是有時候答案跟你的問題真的沒有相關阿...
所以有時候AI的回答要當作 “查詢”
不是真的答案
然後程式碼要看過再執行
而且git commit 時候還要再檢查
AI 不會對你的程式碼負責任的.

留言板
歡迎留下建議與分享!希望一起交流!感恩!