You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDO::fetchAll方法重写失效及Firebird编码问题求助

Hey there, let's break down your problem into two parts: fixing the broken fetchAll() override first, then looking at ways to optimize your encoding handling.

Fixing the fetchAll() Override Issue

The main reason your rewritten fetchAll() returns NULL even without custom logic is a mismatched default parameter value with the parent PDOStatement class.

In your code, you set $fetch_style = null as the default, but the native PDOStatement::fetchAll() uses PDO::FETCH_DEFAULT as its default mode. When you call fetchAll() without arguments, your method passes null to the parent method instead of the correct default mode, which causes it to fail silently and return NULL.

Here's the corrected version of your fetchAll() method, plus a fix for another subtle issue:

public function fetchAll(int $fetch_style = PDO::FETCH_DEFAULT, $fetch_argument = null, array $ctor_args = array()) {
    if(DB_GLOBAL_UTFENCODING && $fetch_style == PDO::FETCH_ASSOC ) {
        $rows = parent::fetchAll($fetch_style, $fetch_argument, $ctor_args);
        
        // Use reference (&$row) to modify the actual elements in the $rows array
        foreach ($rows as &$row) {
            array_walk_recursive($row, function (&$value) {
                $value = utf8_encode($value);
            });
        }
        unset($row); // Unset the reference to avoid accidental modifications later
        
        return $rows;
    } else {
        return parent::fetchAll($fetch_style, $fetch_argument, $ctor_args);
    }
}

Notice the two key fixes:

  1. Changed the default value of $fetch_style to PDO::FETCH_DEFAULT to match the parent class.
  2. Switched to foreach ($rows as &$row) (using a reference) so your array_walk_recursive actually modifies the rows in the original array. Your original code was modifying a copy of each row, so the changes never made it into the returned $rows array.

Optimizing Your Encoding Handling

Now, a few tips to refine your encoding logic:

  • Question the mb_strtoupper call: In your bindValue() method, you’re converting strings to uppercase with mb_strtoupper after decoding. If this isn’t required by your business logic, remove it—you only need utf8_decode($value) to convert UTF-8 strings to the byte stream Firebird expects with a NONE character set.
  • Use mb_convert_encoding for flexibility: Instead of utf8_encode/utf8_decode, consider mb_convert_encoding which supports more encodings explicitly. For example:
    // When binding values: convert UTF-8 to ISO-8859-1 (matches utf8_decode)
    $value = mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8');
    // When fetching values: convert ISO-8859-1 back to UTF-8
    $value = mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1');
    
    This makes your encoding intent clearer and easier to adjust if your actual byte encoding ever changes.
  • Alternative approach: Wrap database operations: Instead of overriding PDOStatement methods, you could create a wrapper class that handles encoding before binding and after fetching. This can make your code more modular and easier to debug.

内容的提问来源于stack exchange,提问作者João Eduardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:16:22