php 换行符问题

php 换行符问题

背景

公司有个业务需要用户上传csv文件,里面的内容以逗号(,)分隔 ,然后每一行代表一条数据,业务代码读取数据根据业务规则入库。
有用户反馈,自己上传的csv文件“符合规范”,但上传后提示数据为空

问题定位

拿到用户的csv文件,用notepad++打开文件,发现换行符和期望的\r\n ,不一样,用户的csv文件换行符是\r,跟用户确认后,明确用户用的mac电脑,因为mac和windows上换行符不一致到这该问题,业务代码是用php编写的,默认无法识别\r,把csv里面的内容当作一行来处理,导致业务报错

解决

  1. 先紧急解决用户的问题

拿到用户的csv文件后,手动替换\r为\r\n,引导用户重新上传,解决问题先

  1. 修改业务代码,解决该问题,有两种方案
  2. 修改php.ini文件,打开**auto_detect_line_endings **配置,具体如下:
auto_detect_line_endings = On
  1. 在业务代码中,加入如下代码:
ini_set("auto_detect_line_endings", true);

原理

unix系列用 \n
windows系列用 \r\n
mac用 \r

\n是换行,英文是New line,表示使光标到行首
\r是回车,英文是Carriage return,表示使光标下移一格
\r\n表示回车换行
我们在平时使用电脑时,已经习惯了回车和换行一次搞定,敲一个回车键,即是回车,又是换行。


Unix系统里,每行结尾只有“<换行>”,即"\n";
Windows系统里面,每行结尾是“<回车><换行>”,即“\r\n”;
Mac系统里,每行结尾是“<回车>”,即"\r";
一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;
而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。




auto_detect_line_endings boolean
当设为 On 时,PHP 将检查通过 fgets()file() 取得的数据中的行结束符号是符合 Unix,MS-DOS,还是 Macintosh 的习惯。
这使得 PHP 可以和 Macintosh 系统交互操作,但是默认值是 Off,因为在检测第一行的 EOL 习惯时会有很小的性能损失,而且在 Unix 系统下使用回车符号作为项目分隔符的人们会遭遇向下不兼容的行为。


参考资料

https://blog.csdn.net/qq_40395278/article/details/81199281 (推荐)
https://www.php.net/manual/zh/filesystem.configuration.php

posted @ 2020-05-08 19:57  whendream  阅读(147)  评论(0编辑  收藏