> 백엔드 개발 > PHP 튜토리얼 > PHP怎么在导出csv的时候加双引号

PHP怎么在导出csv的时候加双引号

WBOY
풀어 주다: 2016-06-06 20:50:46
원래의
1553명이 탐색했습니다.

用PHP输出一个csv文件

foreach ($old['lines'] as $line) {
     fputcsv($new, $line);
}
로그인 후 복사
로그인 후 복사

比如$line的内容是:

CA,12,Y
MU,13,Y
MU,12,N

我希望的数据:

"CA","12","Y"
"MU","13","Y"
"MU","12","N"

我这样做

foreach ($lines as &$line) {
    foreach ($line as &$column) {
        $column = '"' . $column . '"';
    }
}
로그인 후 복사
로그인 후 복사

结果出来每一列数据上都被加了两个双引号:

""CA"",""12"",""Y""
""MU"",""13"",""Y""
""MU"",""12"",""N""

这种方法不对,还是有其他更好的方法?

回复内容:

用PHP输出一个csv文件

foreach ($old['lines'] as $line) {
     fputcsv($new, $line);
}
로그인 후 복사
로그인 후 복사

比如$line的内容是:

CA,12,Y
MU,13,Y
MU,12,N

我希望的数据:

"CA","12","Y"
"MU","13","Y"
"MU","12","N"

我这样做

foreach ($lines as &$line) {
    foreach ($line as &$column) {
        $column = '"' . $column . '"';
    }
}
로그인 후 복사
로그인 후 복사

结果出来每一列数据上都被加了两个双引号:

""CA"",""12"",""Y""
""MU"",""13"",""Y""
""MU"",""12"",""N""

这种方法不对,还是有其他更好的方法?

我始终觉得 fputcsv() 挺土的 ... 不如自己实现一个 ... 也不是很麻烦 ...

当然如果你一定要用 ... 我们就要先研究一下为什么会出现多重双引号这个问题 ...

/* enclose a field that contains a delimiter, an enclosure character, or a newline */
if (FPUTCSV_FLD_CHK(delimiter) ||
	FPUTCSV_FLD_CHK(enclosure) ||
	FPUTCSV_FLD_CHK(escape_char) ||
	FPUTCSV_FLD_CHK('\n') ||
	FPUTCSV_FLD_CHK('\r') ||
	FPUTCSV_FLD_CHK('\t') ||
	FPUTCSV_FLD_CHK(' ')
) {
로그인 후 복사

/ext/standard/file.c 的第 1867 - 1875 行 ...

这里描述了 enclosure ... 我翻译成 包围符 出现的规则 ...

双引号本身正是默认的包围符 ... 触发了规则 ... 导致双引号外面再加双引号造成两个双引号的结果 ...

知道了原理 ... 我们来研究对策 ...

第一种方法 ... 使用默认的双引号做包围符 ... 但是强制所有元素触发 ...

foreach ($lines as &$line) {
    foreach ($line as &$column) {
        $column = $column . ' ';
    }
}
로그인 후 복사

产生的结果大概会类似于下面这样 ...

"CA ","12 ","Y "
"MU ","13 ","Y "
"MU ","12 ","N "

第二种方法 ... 我们去研究手册 ... 手册上关于这个函数的说明是这样的 ...

int fputcsv ( resource $handle , array $fields [, string $delimiter = ',' [, string $enclosure = '"' ]] )

你可以看到这个函数支持自定义包围符 ... 也就是第四个参数 $enclosure ...

于是我们可以手动在所有元素的两侧加上双引号 ... 并修改默认的包围符为空 ...

foreach ( $old['lines'] as $line ) {
     fputcsv( $new, $line, ',', ' ' );
}
로그인 후 복사

这种方式可以让你的例子返回完美的结果 ...

但是如果元素触发了包围符出现规则的话 ... 就会在分隔符也就是逗号的两端出现空格 ...

你可能会好奇为什么一定要是空格 ... 因为包围符必须是一个字符 ... 不能是空也不能是 null ...

如果你确定你的元素里一定不包含会触发包围符出现的所有字符以及另外的某个字符 ...

也可以修改成另外的那个字符 ... 反正想办法永远不要触发添加包围符的规则就对了 ...

两种方法 ... 都不是很完美 ... 选择哪种就看你的需要了 ...

当然最后的最后我还是要说 ... 这个函数实在是太土了还是自己实现一个吧 ...

比较不正规的方法,若字段中含有双引号,解析的时候会出错:

<?php $fp = fopen('php://stdout', 'w');

	fputcsv($fp, array_map(function ($item) {
		return '"' . $item . '"';
	}, array(1,2,'b c','\'ss"')), ',', ' ');

	fclose($fp);
로그인 후 복사
"1","2", "b  c" ,"'ss""
로그인 후 복사

fputcsv方法有4个参数,如下:

fputcsv(file,fields,seperator,enclosure);
로그인 후 복사

file 保存的文件名
fields 数据数组
seperator 字段分隔符,默认是逗号
enclosure 字段包围符,默认是双引号

你问题的点是第4个参数enclosure,由于你没有传(实际也不用传),默认就是双引号,所以经过你多余的处理后被加了2次。

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿