PHP 8.4: CSV: 必须提供 $escape 参数
PHP 提供了内置的 CSV 功能,允许读取和写入 CSV 文件。此实现存在一些有问题的转义行为,正在逐步淘汰。
CSV 功能使用三个字符来分隔/separate(默认为,)、包围/enclose(默认为")和转义/escape(目前默认为\)。通常情况下,如果数据字段中包含 enclose 字符,则通过重复该字符来进行转义。然而,PHP 的实现允许通过指定转义字符来自定义转义行为。
当转义字符设置为任何非空字符串或包围字符本身以外的值时,会导致不合规和错误的行为,例如数据无法在读-写循环中保持一致,如 fgetcsv -> fputcsv -> fgetcsv。
以下函数和方法受到影响:
fputcsvfgetcsvstr_getcsvSplFileObject::setCsvControlSplFileObject::getCsvControlSplFileObject::fputcsvSplFileObject::fgetcsv
上述所有函数/方法的默认 $escape 参数值均为 \"。
为了逐步淘汰该转义机制,PHP 8.4 已弃用未传递 $escape 参数的情况,而 PHP 9.0 计划完全移除 $escape 参数。
这意味着,如果未按位置或作为命名参数传递 $escape 参数,上述所有函数/方法的使用将发出弃用通知。
例如,str_getcsv 函数具有以下签名:
str_getcsv(string $string, string $separator = ',', string $enclosure = '"', string $escape = '\\'): array在 PHP 8.4 及更高版本中使用上述所有函数时,未传递 $escape 参数会发出弃用通知:
str_getcsv($string, separator: ',', enclosure: '"');str_getcsv(): the $escape parameter must be provided as its default value will change ...为了避免弃用通知,请显式传递 $escape 参数:
- str_getcsv($string, separator: ',', enclosure: '"');
+ str_getcsv($string, separator: ',', enclosure: '"', escape: "");建议使用空字符串 "" 作为转义字符。这实际上禁用了转义机制,PHP 继续通过重复 $enclosure 字符来转义字段数据中的包围字符。
向后兼容性影响
在 PHP 8.4 中,未传递 $escape 参数会发出弃用通知。显式传递 $escape 参数可以避免弃用通知。
PHP 9.0 计划完全移除 $escape 参数,并始终通过重复包围字符来转义。