【问题标题】:Trouble reading online .csv file in php?在 php 中读取在线 .csv 文件时遇到问题?
【发布时间】:2013-07-07 19:33:10
【问题描述】:

雅虎有一个金融 API,允许个人获取当前和历史股票信息。他们有多种方法来检索这些信息,其中一种是使用 Yahoo Query Language,另一种是直接下载/读取他们的 .csv(逗号分隔文件)文件。

我发现了一个非常有用的脚本,用于通过 php 读取 csv 文件。但是,我似乎只获得了 csv 文件的前 9,000 个字符左右。我尝试过使用文件大小但无济于事,我想知道我的上限到底在哪里,是否有办法解决这个问题。

是 php 限制了我,yahoo 限制了我(似乎不太可能),还是只能通过 http 协议传递这么多信息?我欢迎任何知情的 cmets,并非常感谢任何建设性的批评。我的代码如下:

<?php

// Setup Variables
$requestUrl = "http://ichart.yahoo.com/table.csv?s=GOOG&a=0&b=1&c=2000&d=0&e=31";

// Pull data (download CSV as file)
$filesize=1000000;
$handle = fopen($requestUrl, "r");
$raw = fread($handle, $filesize);
fclose($handle);

echo $raw; //error checking, turns out the $raw is only about 8000 characters long


// Split results, trim way the extra line break at the end
$quotes = explode("\n",trim($raw));


foreach($quotes as $quoteraw) {
$quoteraw = str_replace(", I", " I", $quoteraw);
$quote = explode(",", $quoteraw);

echo $quote[0]."
"; // output the first element of the array, the Company Name
}

?>

编辑:将对所有建设性建议投赞成票,非常感谢:))。

【问题讨论】:

  • Read php.net/manual/en/function.fread.php ,它说“如果流被读取缓冲并且它不代表普通文件,最多一次读取最多等于块大小的字节数(通常为 8192 ) ;根据之前缓冲的数据,返回数据的大小可能大于块大小。"所以我猜你只读了一大块。 while-loop 通过文件而不是获取所有内容。该手册还展示了如何使用循环读取文件。
  • 感谢您的反馈丹尼斯,我会马上解决的,CodeAngry 的回答可能更适合我的需要,但无论如何我肯定需要重新考虑。谢谢。
  • 丹尼斯提出的好问题和有用的信息。

标签: php http yql


【解决方案1】:

由于是 csv 文件,请改用fgetcsv

来自 php.net 的示例代码:

<?php
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $num = count($data);
        echo "<p> $num fields in line $row: <br /></p>\n";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />\n";
        }
    }
    fclose($handle);
}
?>

【讨论】:

  • 感谢 Sumoanand,感谢您的回答,像上面建议的 CodeAngry 一样,使用 fgetcsv 而不是 file_get_contets 有什么好处吗? +1。
  • 是的,因为如果描述列中有逗号,您的代码可能会产生不正确的输出。在这种情况下,您的描述字段也将被分解命令划分。在 fgetcsv 中,有相同的 $enclosure 参数,默认为双引号。
【解决方案2】:
$CSV = file_get_contents('http://ichart.yahoo.com/table.csv?s=GOOG&a=0&b=1&c=2000&d=0&e=31');
var_dump($CSV);

^ 试穿这件的尺码。

您只能fread 一次。你没有得到全部的东西是很自然的。它需要阅读到feof()。您不能指望 TCP/IP 提供您预期的缓冲区大小。您说 fread() 最多 ##### 字节,但您得到的回报与服务器希望(/可以)一次发送的一样多。

PS:要更棒,请使用cURL!但是file_get_contents 应该在这里做。

【讨论】:

  • CodeAngry,谢谢你的建议。就像我上面所说的,我拥有的原始 php 脚本是我在网上找到的。我对使用 fread 不是很熟悉,我很欣赏你的建议,不仅是我如何使用 fread 和 feof 来做到这一点,而且 file_get_contents 函数如何可能更好地满足我的需求。我刚刚在我的脚本中实现了 file_get_contents 函数,并且我成功地检索了所有历史数据。这个答案完全符合我的需要,非常感谢,+1,最佳答案。
猜你喜欢
  • 2015-05-19
  • 1970-01-01
  • 2012-09-28
  • 2017-07-21
  • 1970-01-01
  • 2020-04-21
  • 1970-01-01
  • 2013-04-10
  • 2019-02-21
相关资源
最近更新 更多