php 换行符问题
php 换行符问题
背景
公司有个业务需要用户上传csv文件,里面的内容以逗号(,)分隔 ,然后每一行代表一条数据,业务代码读取数据根据业务规则入库。 有用户反馈,自己上传的csv文件“符合规范”,但上传后提示数据为空
问题定位
拿到用户的csv文件,用notepad++打开文件,发现换行符和期望的\r\n ,不一样,用户的csv文件换行符是\r,跟用户确认后,明确用户用的mac电脑,因为mac和windows上换行符不一致到这该问题,业务代码是用php编写的,默认无法识别\r,把csv里面的内容当作一行来处理,导致业务报错
解决
- 先紧急解决用户的问题
拿到用户的csv文件后,手动替换\r为\r\n,引导用户重新上传,解决问题先
- 修改业务代码,解决该问题,有两种方案
- 修改php.ini文件,打开**auto_detect_line_endings **配置,具体如下:
auto_detect_line_endings = On
- 在业务代码中,加入如下代码:
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 的习惯。