使用fopen()编码问题解析PHP

时间:2015-07-11 10:45:54

标签: php sql-server csv encoding

我在使用fopen()接收API数据解析php中的csv文件时遇到问题。

当我使用在浏览器中显示csv文件的URL时,我的代码可以正常工作,如下面 1)中所述。但是我从URL输出的随机字符以格式= csv结尾,如下面的 2)所示。

1) 工作网址:返回预期值 https://www.kimonolabs.com/api/csv/duo2mkw2?apikey=yjEl780lSQ8IcVHkItiHzzUZxd1wqSJv

2) 不工作的网址:返回随机字符 https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv

以下是我的代码: - 使用上面的网址(2)

var subTable = new PdfPTable(new float[] { 10, 100 });                        
subTable.AddCell(new PdfPCell(new Phrase("First line text")) { Colspan = 2, Border = 0 });
subTable.AddCell(new PdfPCell() { Border = 0 });
subTable.AddCell(new PdfPCell(new Phrase("Second line text")) {  Border = 0 });
subTable.AddCell(new PdfPCell() { Border = 0 });
subTable.AddCell(new PdfPCell(new Phrase("Third line text")) { Border = 0 });
subTable.AddCell(new PdfPCell(new Phrase("Fourth line text")) { Colspan = 2, Border = 0 });
myTable.AddCell(subTable);


输出:对于(2)中提到的网址

root @ MorryServer:/#php testing.php

?IU Q + JL??/ Q?R 10 /)?J-.?))VH?/OM?K-NI?T0?P?*ͩT0204jzԴ2 H ??? X ??? @ D ?? K


正确输出:如果我使用(1)

中所述的网址类型

root @ MorryServer:/#php testing.php

PHP注意:未定义的偏移量:第24行的/testing.php中为1 的
头奖
€2893210

1 个答案:

答案 0 :(得分:1)

这是编码问题。

给定文件包含UTF-8字符。它们由fgetcsv函数读取,该函数是二进制安全的。行结尾是Unix格式(“\ n”)。

终端上的输出是混乱的。查看发送的标头,我们看到:

GET https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv --> 200 OK
Connection: close
Date: Sat, 11 Jul 2015 13:15:24 GMT
Server: nginx/1.6.2
Content-Encoding: gzip
Content-Length: 123
Content-Type: text/csv; charset=UTF-8
Last-Modified: Fri, 10 Jul 2015 11:43:49 GMT
Client-Date: Sat, 11 Jul 2015 13:15:23 GMT
Client-Peer: 107.170.197.156:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
Client-SSL-Cert-Subject: /OU=Domain Control Validated/OU=PositiveSSL/CN=www.parsehub.com

请注意Content-Encoding: gzipfgetcsv处理网址并不会明显处理gzip。 scrumbled String只是“文件”的gzip压缩内容。

查看PHP的gzip库,在解析它之前先解压缩它。 证明:

srv:~ # lwp-download 'https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv' data
123 bytes received
srv:~ # file data
data: gzip compressed data, was "tcW80-EcI6Oj2TYPXI-47XwK.csv", from Unix, last modified: Fri Jul 10 11:43:48 2015, max compression
srv:~ # gzip -d < data
"title","jackpot"
"Lotto Results for Wednesday 08 July 2015","€2,893,210"

要获得正确的输出,需要进行最少的更改:只需添加一个流包装器:​​

<?php

        $f_pointer=fopen("compress.zlib://https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv","r");

        if ( $f_pointer === false )
                die ("invalid URL");

        $ar = array();
        while(! feof($f_pointer)){
                $ar[]=fgetcsv($f_pointer);
        }

        print_r($ar);

?>

输出:

Array
(
    [0] => Array
        (
            [0] => title
            [1] => jackpot
        )

    [1] => Array
        (
            [0] => Lotto Results for Wednesday 08 July 2015
            [1] => €2,893,210
        )

)