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:
- Changed the default value of
$fetch_styletoPDO::FETCH_DEFAULTto match the parent class. - Switched to
foreach ($rows as &$row)(using a reference) so yourarray_walk_recursiveactually 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$rowsarray.
Optimizing Your Encoding Handling
Now, a few tips to refine your encoding logic:
- Question the
mb_strtouppercall: In yourbindValue()method, you’re converting strings to uppercase withmb_strtoupperafter decoding. If this isn’t required by your business logic, remove it—you only needutf8_decode($value)to convert UTF-8 strings to the byte stream Firebird expects with a NONE character set. - Use
mb_convert_encodingfor flexibility: Instead ofutf8_encode/utf8_decode, considermb_convert_encodingwhich supports more encodings explicitly. For example:
This makes your encoding intent clearer and easier to adjust if your actual byte encoding ever changes.// 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'); - 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

