编程

PHP 8.4: CSV: 必须提供 $escape 参数

50 2025-04-15 08:40:00

PHP 提供了内置的 CSV 功能,允许读取和写入 CSV 文件。此实现存在一些有问题的转义行为,正在逐步淘汰。

CSV 功能使用三个字符来分隔/separate(默认为,)、包围/enclose(默认为")和转义/escape(目前默认为\)。通常情况下,如果数据字段中包含 enclose 字符,则通过重复该字符来进行转义。然而,PHP 的实现允许通过指定转义字符来自定义转义行为。

当转义字符设置为任何非空字符串或包围字符本身以外的值时,会导致不合规和错误的行为,例如数据无法在读-写循环中保持一致,如 fgetcsv -> fputcsv -> fgetcsv

以下函数和方法受到影响:

  • fputcsv
  • fgetcsv
  • str_getcsv
  • SplFileObject::setCsvControl
  • SplFileObject::getCsvControl
  • SplFileObject::fputcsv
  • SplFileObject::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 参数,并始终通过重复包围字符来转义。