|
8 | 8 | * @author Tran Ngoc Duc <ductn@diepxuan.com> |
9 | 9 | * @author Tran Ngoc Duc <caothu91@gmail.com> |
10 | 10 | * |
11 | | - * @lastupdate 2026-04-07 12:39:39 |
| 11 | + * @lastupdate 2026-04-07 13:04:50 |
12 | 12 | */ |
13 | 13 |
|
14 | 14 | namespace Diepxuan\Simba\StoredProcedures; |
@@ -87,7 +87,7 @@ public static function call(string $name, array $params = [], ?string $connectio |
87 | 87 | if (empty($bindings)) { |
88 | 88 | $rows = $conn->select($sql); |
89 | 89 | } else { |
90 | | - // Replace ? với Unicode literal |
| 90 | + // Replace :placeholder với Unicode literal (fix UTF-8 cho SQL Server) |
91 | 91 | $processedQuery = self::replacePlaceholders($sql, $bindings); |
92 | 92 | $rows = $conn->select($processedQuery); |
93 | 93 | } |
@@ -146,41 +146,20 @@ public static function toUnicodeLiteral(mixed $value): string |
146 | 146 | } |
147 | 147 |
|
148 | 148 | /** |
149 | | - * Replace ? placeholders với Unicode literals. |
| 149 | + * Replace :placeholder với Unicode literals (N'...') |
| 150 | + * Fix UTF-8 cho SQL Server parameter binding trên Linux. |
| 151 | + * |
| 152 | + * @param string $query SQL query với :named placeholders |
| 153 | + * @param array $bindings Associative array [paramName => value] |
150 | 154 | */ |
151 | 155 | private static function replacePlaceholders(string $query, array $bindings): string |
152 | 156 | { |
153 | | - $count = 0; |
154 | | - |
155 | | - return preg_replace_callback('/\?/', static function () use ($bindings, &$count) { |
156 | | - $value = $bindings[$count] ?? null; |
157 | | - ++$count; |
158 | | - |
159 | | - return self::toUnicodeLiteral($value); |
160 | | - }, $query); |
161 | | - } |
162 | | - |
163 | | - /** |
164 | | - * Kiểm tra xem value có phải là date/datetime format không. |
165 | | - */ |
166 | | - private static function isDateOrDatetime(string $value): bool |
167 | | - { |
168 | | - // Check các format date/datetime phổ biến |
169 | | - // YYYY-MM-DD, YYYY-MM-DD HH:MM:SS, DD/MM/YYYY, v.v. |
170 | | - $datePatterns = [ |
171 | | - '/^\d{4}-\d{2}-\d{2}$/', // 2026-04-06 |
172 | | - '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', // 2026-04-06 12:30:45 |
173 | | - '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/', // 2026-04-06T12:30:45 (ISO 8601) |
174 | | - '/^\d{2}\/\d{2}\/\d{4}$/', // 06/04/2026 |
175 | | - '/^\d{2}-\d{2}-\d{4}$/', // 06-04-2026 |
176 | | - ]; |
177 | | - |
178 | | - foreach ($datePatterns as $pattern) { |
179 | | - if (preg_match($pattern, $value)) { |
180 | | - return true; |
181 | | - } |
| 157 | + foreach ($bindings as $key => $value) { |
| 158 | + $literal = self::toUnicodeLiteral($value); |
| 159 | + $pattern = '/:' . preg_quote($key, '/') . '/'; |
| 160 | + $query = preg_replace($pattern, $literal, $query); |
182 | 161 | } |
183 | 162 |
|
184 | | - return false; |
| 163 | + return $query; |
185 | 164 | } |
186 | 165 | } |
0 commit comments