最近嘗試把 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 中,正確的做法應該是:

  1. 先取出 event 名稱,用來決定要呼叫哪個函數。
  2. 刪除 $args 裡的 event 鍵,避免干擾參數匹配。
  3. 轉換 為純數值陣列,確保 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 不會對你的程式碼負責任的.