使用 curl 作为 fgetcsv 的 fopen 文件资源的替代方法
Posted
技术标签:
【中文标题】使用 curl 作为 fgetcsv 的 fopen 文件资源的替代方法【英文标题】:Using curl as an alternative to fopen file resource for fgetcsv 【发布时间】:2012-08-08 15:22:29 【问题描述】:是否可以进行 curl,访问 url 并将结果作为文件资源?就像 fopen 是怎么做的一样。
我的目标:
-
解析 CSV 文件
将其传递给 fgetcsv
我的障碍:fopen 被禁用
我的代码块(在 fopen 中)
$url = "http://download.finance.yahoo.com/d/quotes.csv?s=USDEUR=X&f=sl1d1t1n&e=.csv";
$f = fopen($url, 'r');
print_r(fgetcsv($f));
然后,我在 curl 上试试这个。
$curl = curl_init();
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
curl_setopt($curl, CURLOPT_URL, $url);
$content = @curl_exec($curl);
curl_close($curl);
但是,像往常一样。 $content 已经返回一个字符串。
现在,curl 是否可以将它作为文件资源指针返回?就像fopen一样?使用 php
我的错误
警告:fgetcsv() 期望参数 1 是资源,给定的布尔值
谢谢
【问题讨论】:
您是否考虑过使用函数文档从评论中添加 str_getcsv ? us2.php.net/manual/en/function.str-getcsv.php#100579 它仅在 5.3 上可用。 :( 我通常的错误,因为它还不存在。致命错误:调用未定义函数 str_getcsv() 【参考方案1】:假设 fopen is disabled
的意思是“allow_url_fopen
已禁用”,CURLOPT_FILE
和 php://temp
的组合使这相当容易:
$f = fopen('php://temp', 'w+');
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_FILE, $f);
// Do you need these? Your fopen() method isn't a post request
// curl_setopt($curl, CURLOPT_POST, true);
// curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
curl_exec($curl);
curl_close($curl);
rewind($f);
while ($line = fgetcsv($f))
print_r($line);
fclose($f);
基本上,这会创建一个指向“虚拟”文件的指针,然后 cURL 将响应存储在其中。然后你只需将指针重置到开头,它就可以被视为像往常一样使用fopen($url, 'r');
打开它
【讨论】:
我试图通过发出来获取资源类型.. get_resource_type($f);它返回一个“流”,这是正确的吗?同样的错误,警告:fgetcsv() 期望参数 1 是资源,给定的布尔值 解决了。这绝对是答案。非常感谢! 我在 PHP 5.5.6 本地 xampp 中试过,print_r($line); 没有输出任何东西,是否需要任何其他设置? 我发现了问题,这是由于我的目标使用的是 HTTPS,我需要关闭 SSL 验证。现在好了。非常感谢。【参考方案2】:您可以使用fopen()
创建一个临时文件,然后使用fwrite()
将内容放入其中。之后,fgetcsv()
将可以读取新创建的文件。 tempnam()
函数应该处理任意临时文件的创建。
根据str_getcsv()
上的cmets,无法访问该命令的用户可以尝试以下功能。 cmets 中还有其他各种方法,请务必查看它们。
function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = '\n')
if (is_string($input) && !empty($input))
$output = array();
$tmp = preg_split("/".$eol."/",$input);
if (is_array($tmp) && !empty($tmp))
while (list($line_num, $line) = each($tmp))
if (preg_match("/".$escape.$enclosure."/",$line))
while ($strlen = strlen($line))
$pos_delimiter = strpos($line,$delimiter);
$pos_enclosure_start = strpos($line,$enclosure);
if (
is_int($pos_delimiter) && is_int($pos_enclosure_start)
&& ($pos_enclosure_start < $pos_delimiter)
)
$enclosed_str = substr($line,1);
$pos_enclosure_end = strpos($enclosed_str,$enclosure);
$enclosed_str = substr($enclosed_str,0,$pos_enclosure_end);
$output[$line_num][] = $enclosed_str;
$offset = $pos_enclosure_end+3;
else
if (empty($pos_delimiter) && empty($pos_enclosure_start))
$output[$line_num][] = substr($line,0);
$offset = strlen($line);
else
$output[$line_num][] = substr($line,0,$pos_delimiter);
$offset = (
!empty($pos_enclosure_start)
&& ($pos_enclosure_start < $pos_delimiter)
)
?$pos_enclosure_start
:$pos_delimiter+1;
$line = substr($line,$offset);
else
$line = preg_split("/".$delimiter."/",$line);
/*
* Validating against pesky extra line breaks creating false rows.
*/
if (is_array($line) && !empty($line[0]))
$output[$line_num] = $line;
return $output;
else
return false;
else
return false;
【讨论】:
如我所说,fopen 已禁用。 如果fopen()
完全禁用并且您缺少str_getcsv()
(这可能是您的救星),那么请尝试cmets 中描述的方法。另外,请参阅我的编辑。以上是关于使用 curl 作为 fgetcsv 的 fopen 文件资源的替代方法的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 PHP 和 fgetcsv 函数从 CSV 文件创建数组
PHP 高效导入导出Excel(csv)方法之fgetcsv()和fputcsv()函数
php读取csv文件时 用phpexcel很慢 用fgetcsv()函数中文乱码 请问还有啥excel库或函数方法来读csv文件吗