@@ -95,7 +95,7 @@ protected function import(array $resources, callable $callback): void
9595 }
9696
9797 foreach ($ buffer ['lines ' ] as $ line ) {
98- if (\fputcsv ( $ handle , $ line , $ this ->delimiter , $ this -> enclosure , $ this -> escape ) === false ) {
98+ if (! $ this ->writeCSVLine ( $ handle , $ line ) ) {
9999 throw new \Exception ("Failed to write CSV line to file: $ log " );
100100 }
101101 }
@@ -192,6 +192,29 @@ public function shutdown(): void
192192 }
193193 }
194194
195+ /**
196+ * Write a CSV line with RFC 4180 compliant escaping (double-quote method)
197+ * Optimized for maximum performance: array building + single implode
198+ * @param resource $handle
199+ * @param array $fields
200+ * @return bool
201+ */
202+ protected function writeCSVLine ($ handle , array $ fields ): bool
203+ {
204+ $ parts = [];
205+
206+ foreach ($ fields as $ field ) {
207+ $ field = (string )$ field ;
208+ if (\strpbrk ($ field , $ this ->delimiter . "\n\r" . $ this ->enclosure ) !== false ) {
209+ $ parts [] = $ this ->enclosure . \str_replace ($ this ->enclosure , $ this ->enclosure . $ this ->enclosure , $ field ) . $ this ->enclosure ;
210+ } else {
211+ $ parts [] = $ field ;
212+ }
213+ }
214+
215+ return \fwrite ($ handle , \implode ($ this ->delimiter , $ parts ) . "\n" ) !== false ;
216+ }
217+
195218 /**
196219 * Helper to ensure a directory exists.
197220 * @throws \Exception
@@ -275,27 +298,10 @@ protected function convertArrayToCSV(array $value): string
275298 if (empty ($ value )) {
276299 return '' ;
277300 }
278-
279301 if (isset ($ value ['$id ' ])) {
280302 return $ value ['$id ' ];
281303 }
282-
283- $ isStringArray = \array_reduce (
284- $ value ,
285- fn ($ carry , $ item ) => $ carry && is_string ($ item ),
286- true
287- );
288-
289- if ($ isStringArray ) {
290- // For string arrays, escape quotes and join with commas
291- return \implode (', ' , \array_map (
292- fn ($ item ) => \str_replace ('" ' , '"" ' , $ item ),
293- $ value
294- ));
295- }
296-
297- // For complex arrays, use JSON with escaped quotes
298- return \str_replace ('" ' , '"" ' , \json_encode ($ value ));
304+ return \json_encode ($ value );
299305 }
300306
301307 /**
@@ -306,8 +312,6 @@ protected function convertObjectToCSV($value): string
306312 if ($ value instanceof Row) {
307313 return $ value ->getId ();
308314 }
309-
310- // Escape quotes for CSV by doubling them
311- return \str_replace ('" ' , '"" ' , \json_encode ($ value ));
315+ return \json_encode ($ value );
312316 }
313317}
0 commit comments