将数据保存为 CSV 并编码为 utf-8
Save data to CSV and encode to utf-8
我有一个编码为 utf8mb4
的数据库。我连接到这个数据库并设置了 utf8 字符集:
$dbHandler = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUsername, $dbPassword);
所有数据都属性编码在数据库中。我想获取数据并将其保存为 CSV:
$fp = fopen('data.csv', 'w+');
foreach ($result as $row) {
...
fputcsv($fp, $csvData, ';');
}
但是所有的编码都被破坏了:
groÃ<9f>e
,
Zubehör.
等
我尝试添加 BOM(没有帮助)并转换 array_map("utf8_encode", $csvData);
(一些字符显示正确:große
、Zubehör
,但有些字符不正确:Kabelverl?ng
, F?r
).有什么想法吗?
编辑:
Hexdump 输出文件开头:
00000000: efbb bf70 726f 6475 6374 3b61 7274 6963 ...product;artic
00000010: 6c65 3b73 6b75 3b64 6174 653b 6e61 6d65 le;sku;date;name
00000020: 0a30 3030 3239 3039 3530 3030 3b3b 3b3b .00028151000;;;;
00000030: 2242 7265 616b 6f75 742d 626f 7820 4b70 "Breakout-box Kp
00000040: 6c2e 223b 223c 7374 726f 6e67 3e42 7265 l.";"<strong>Bre
00000050: 616b 6f75 742d 626f 7820 4b70 6c2e 3c2f akout-box Kpl.</
文件的 Hexdump 输出有 1 条记录,我们可以在其中看到问题(F..r 而不是 Für)。顺便说一下 - 原始字符串被 ucwords 和 strtolower 修改过:
00000000: 3030 3032 3930 3936 3030 333b 3b3b 3b22 00028151000;;;;"
00000010: 4e65 747a 7465 696c 2032 3230 762f 3132 Netzteil 220v/12
00000020: 7620 46e3 9c72 2041 766c 223b 223c 7374 v F..r Avl";"<st
00000030: 726f 6e67 3e4e 6574 7a74 6569 6c20 3232 rong>Netzteil 22
00000040: 3076 2f31 3276 2046 e39c 7220 4176 6c3c 0v/12v F..r Avl<
00000050: 2f73 7472 6f6e 673e 3c62 723e 3c62 723e /strong><br><br>
00000060: 4f45 4d20 4e75 6d6d 6572 3a20 3030 3032 OEM Nummer: 0002
00000070: 3930 3936 3030 3322 3b31 3038 2e34 363b 9096003";108.46;
00000080: 3030 3032 3930 3936 3030 332d 6e65 747a 00028151000-netz
00000090: 7465 696c 2d32 3230 762d 3132 762d 6675 teil-220v-12v-fu
000000a0: 722d 6176 6c3b 4875 7371 7661 726e 613b r-avl;Husqvarna;
000000b0: 4452 4f50 444f 574e 3b59 3b4e 3b68 7474 DROPDOWN;Y;N;htt
000000c0: 7073 3a2f 2f73 7061 7265 7061 7274 7366 ps://sparepartsf
000000d0: 696e 6465 722e 6b74 6d2e 636f 6d2f 5350 inder.fha.com/SP
000000e0: 462f 496d 6167 6573 2f6d 6170 732f 3130 F/Images/maps/10
000000f0: 3030 3032 3932 302e 6769 663b 313b 4154 0002920.gif;1;AT
00000100: 3b57 6964 6765 743b 224b 544d 204f 7269 ;Ponret;"KTM Ori
00000110: 6769 6e61 6c20 4572 7361 747a 7465 696c ginal Ersatzteil
00000120: 6522 3b22 4875 7371 7661 726e 6120 4e65 e";"Husqvarna Ne
00000130: 747a 7465 696c 2032 3230 762f 3132 7620 tzteil 220v/12v
00000140: 46e3 9c72 2041 766c 202d 204f 454d 204e F..r Avl - OEM N
00000150: 756d 6d65 723a 2030 3030 3239 3039 3630 ummer: 000290960
00000160: 3033 223b 3b22 4b61 7566 656e 2053 6965 03";;"Kaufen Sie
00000170: 2048 7573 7176 6172 6e61 204e 6574 7a74 Husqvarna Netzt
00000180: 6569 6c20 3232 3076 2f31 3276 2046 e39c eil 220v/12v F..
00000190: 7220 4176 6c20 6d69 7420 4f45 4d2d 4e75 r Avl mit OEM-Nu
000001a0: 6d6d 6572 2030 3030 3239 3039 3630 3033 mmer 00028151000
000001b0: 2062 6569 2065 696e 656d 2048 7573 7176 bei einem Husqv
000001c0: 6172 6e61 2d56 6572 7472 6167 7368 c3a4 arna-Vertragsh..
000001d0: 6e64 6c65 722e 2057 6972 2068 6162 656e ndler. Wir haben
000001e0: 2065 696e 6520 6772 6fc3 9f65 2041 7573 eine gro..e Aus
000001f0: 7761 686c 2061 6e20 4875 7371 7661 726e wahl an Husqvarn
00000200: 612d 4572 7361 747a 7465 696c 656e 2c20 a-Ersatzteilen,
00000210: 4163 6365 7373 6f72 6965 732c 2043 6c6f Accessories, Clo
00000220: 7468 696e 672c 204d 5820 4265 6b6c 6569 thing, MX Beklei
00000230: 6475 6e67 2075 6e64 205a 7562 6568 c3b6 dung und Zubeh..
00000240: 722e 220a r.".
file data.csv
输出:
data.csv: Non-ISO extended-ASCII text, with very long lines
问题是我使用的是 strtolower
和 ucfirst
。我将其更改为
$name = mb_convert_case($name, MB_CASE_LOWER, "UTF-8");
$name = mb_convert_case($name, MB_CASE_TITLE, "UTF-8");
而且有效。
我有一个编码为 utf8mb4
的数据库。我连接到这个数据库并设置了 utf8 字符集:
$dbHandler = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUsername, $dbPassword);
所有数据都属性编码在数据库中。我想获取数据并将其保存为 CSV:
$fp = fopen('data.csv', 'w+');
foreach ($result as $row) {
...
fputcsv($fp, $csvData, ';');
}
但是所有的编码都被破坏了:
groÃ<9f>e
,
Zubehör.
等
我尝试添加 BOM(没有帮助)并转换 array_map("utf8_encode", $csvData);
(一些字符显示正确:große
、Zubehör
,但有些字符不正确:Kabelverl?ng
, F?r
).有什么想法吗?
编辑:
Hexdump 输出文件开头:
00000000: efbb bf70 726f 6475 6374 3b61 7274 6963 ...product;artic
00000010: 6c65 3b73 6b75 3b64 6174 653b 6e61 6d65 le;sku;date;name
00000020: 0a30 3030 3239 3039 3530 3030 3b3b 3b3b .00028151000;;;;
00000030: 2242 7265 616b 6f75 742d 626f 7820 4b70 "Breakout-box Kp
00000040: 6c2e 223b 223c 7374 726f 6e67 3e42 7265 l.";"<strong>Bre
00000050: 616b 6f75 742d 626f 7820 4b70 6c2e 3c2f akout-box Kpl.</
文件的 Hexdump 输出有 1 条记录,我们可以在其中看到问题(F..r 而不是 Für)。顺便说一下 - 原始字符串被 ucwords 和 strtolower 修改过:
00000000: 3030 3032 3930 3936 3030 333b 3b3b 3b22 00028151000;;;;"
00000010: 4e65 747a 7465 696c 2032 3230 762f 3132 Netzteil 220v/12
00000020: 7620 46e3 9c72 2041 766c 223b 223c 7374 v F..r Avl";"<st
00000030: 726f 6e67 3e4e 6574 7a74 6569 6c20 3232 rong>Netzteil 22
00000040: 3076 2f31 3276 2046 e39c 7220 4176 6c3c 0v/12v F..r Avl<
00000050: 2f73 7472 6f6e 673e 3c62 723e 3c62 723e /strong><br><br>
00000060: 4f45 4d20 4e75 6d6d 6572 3a20 3030 3032 OEM Nummer: 0002
00000070: 3930 3936 3030 3322 3b31 3038 2e34 363b 9096003";108.46;
00000080: 3030 3032 3930 3936 3030 332d 6e65 747a 00028151000-netz
00000090: 7465 696c 2d32 3230 762d 3132 762d 6675 teil-220v-12v-fu
000000a0: 722d 6176 6c3b 4875 7371 7661 726e 613b r-avl;Husqvarna;
000000b0: 4452 4f50 444f 574e 3b59 3b4e 3b68 7474 DROPDOWN;Y;N;htt
000000c0: 7073 3a2f 2f73 7061 7265 7061 7274 7366 ps://sparepartsf
000000d0: 696e 6465 722e 6b74 6d2e 636f 6d2f 5350 inder.fha.com/SP
000000e0: 462f 496d 6167 6573 2f6d 6170 732f 3130 F/Images/maps/10
000000f0: 3030 3032 3932 302e 6769 663b 313b 4154 0002920.gif;1;AT
00000100: 3b57 6964 6765 743b 224b 544d 204f 7269 ;Ponret;"KTM Ori
00000110: 6769 6e61 6c20 4572 7361 747a 7465 696c ginal Ersatzteil
00000120: 6522 3b22 4875 7371 7661 726e 6120 4e65 e";"Husqvarna Ne
00000130: 747a 7465 696c 2032 3230 762f 3132 7620 tzteil 220v/12v
00000140: 46e3 9c72 2041 766c 202d 204f 454d 204e F..r Avl - OEM N
00000150: 756d 6d65 723a 2030 3030 3239 3039 3630 ummer: 000290960
00000160: 3033 223b 3b22 4b61 7566 656e 2053 6965 03";;"Kaufen Sie
00000170: 2048 7573 7176 6172 6e61 204e 6574 7a74 Husqvarna Netzt
00000180: 6569 6c20 3232 3076 2f31 3276 2046 e39c eil 220v/12v F..
00000190: 7220 4176 6c20 6d69 7420 4f45 4d2d 4e75 r Avl mit OEM-Nu
000001a0: 6d6d 6572 2030 3030 3239 3039 3630 3033 mmer 00028151000
000001b0: 2062 6569 2065 696e 656d 2048 7573 7176 bei einem Husqv
000001c0: 6172 6e61 2d56 6572 7472 6167 7368 c3a4 arna-Vertragsh..
000001d0: 6e64 6c65 722e 2057 6972 2068 6162 656e ndler. Wir haben
000001e0: 2065 696e 6520 6772 6fc3 9f65 2041 7573 eine gro..e Aus
000001f0: 7761 686c 2061 6e20 4875 7371 7661 726e wahl an Husqvarn
00000200: 612d 4572 7361 747a 7465 696c 656e 2c20 a-Ersatzteilen,
00000210: 4163 6365 7373 6f72 6965 732c 2043 6c6f Accessories, Clo
00000220: 7468 696e 672c 204d 5820 4265 6b6c 6569 thing, MX Beklei
00000230: 6475 6e67 2075 6e64 205a 7562 6568 c3b6 dung und Zubeh..
00000240: 722e 220a r.".
file data.csv
输出:
data.csv: Non-ISO extended-ASCII text, with very long lines
问题是我使用的是 strtolower
和 ucfirst
。我将其更改为
$name = mb_convert_case($name, MB_CASE_LOWER, "UTF-8");
$name = mb_convert_case($name, MB_CASE_TITLE, "UTF-8");
而且有效。