Using curl as an alternative to fopen file resource for fgetcsv

試著忘記壹切 提交于 2020-01-01 03:10:09

问题


Is it possible to make curl, access a url and the result as a file resource? like how fopen does it.

My goals:

  1. Parse a CSV file
  2. Pass it to fgetcsv

My obstruction: fopen is disabled

My chunk of codes (in 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));

Then, I am trying this on 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);

But, as usual. $content already returns a string.

Now, is it possible for curl to return it as a file resource pointer? just like fopen? Using PHP < 5.1.x something. I mean, not using str_getcsv, since it's only 5.3.

My error

Warning: fgetcsv() expects parameter 1 to be resource, boolean given

Thanks


回答1:


Assuming that by fopen is disabled you mean "allow_url_fopen is disabled", a combination of CURLOPT_FILE and php://temp make this fairly easy:

$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);

Basically this creates a pointer to a "virtual" file, and cURL stores the response in it. Then you just reset the pointer to the beginning and it can be treated as if you had opened it as usual with fopen($url, 'r');




回答2:


You can create a temporary file using fopen() and then fwrite() the contents into it. After that, the newly created file will be readable by fgetcsv(). The tempnam() function should handle the creation of arbitrary temporary files.

According to the comments on str_getcsv(), users without access to the command could try the function below. There are also various other approaches in the comments, make sure you check them out.

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;
    }
}


来源:https://stackoverflow.com/questions/11867870/using-curl-as-an-alternative-to-fopen-file-resource-for-fgetcsv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!