【问题标题】:Some images downloaded corrupted via using CURL in PHP通过在 PHP 中使用 CURL 下载的一些图像损坏
【发布时间】:2019-02-12 13:00:55
【问题描述】:

我在 PHP 中使用 CURL 从 CSV 文件中的 URL 下载图像,但如果单行中有多个图像,则下载的某些图像已损坏并且该图像的大小为 0 字节。 例子:- 如果 CSV 文件是这样的,那么第二个文件总是损坏。

Image 1, "https://d2qx4k6xgs9iri.cloudfront.net/ProductImages/ce363947-f23a-46d6-b106-1201cdca37f0.jpg, https://homepages.cae.wisc.edu/~ece533/images/airplane.png"

但是,如果我删除了第一张或第二张图片,则该图片将成功保存。示例:

Image 2, https://homepages.cae.wisc.edu/~ece533/images/arctichare.png

这是我读取 CSV 文件的代码

    $file = fopen($file, "r");
    while (!feof($file)) {
        $data = fgetcsv($file);
        $images = $data[1];
        $images = explode(',', $images); //exploding images by ,
        foreach ($images as $image) {
            $milliseconds = md5(round(microtime(true) * 1000)) . '.jpg';
            $imagename = saveImage($image, $milliseconds);
        }
}

下面saveImage函数

function saveImage($url,$image_name){

echo $url.'<br/>'; //URL is correct and have image. I have checked it manually
$ch = curl_init ($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
    $raw=curl_exec($ch);
    curl_close ($ch);

    $fp = fopen('assets/products/large/' . $image_name,'x');
    fwrite($fp, $raw);
    fclose($fp);
}

我正在使用的 CSV 文件的确切示例

Images 1, "https://d2qx4k6xgs9iri.cloudfront.net/ProductImages/ce363947-f23a-46d6-b106-1201cdca37f0.jpg, https://homepages.cae.wisc.edu/~ece533/images/airplane.png"
Images 2, https://homepages.cae.wisc.edu/~ece533/images/arctichare.png
Images 3, "https://homepages.cae.wisc.edu/~ece533/images/fruits.png, https://homepages.cae.wisc.edu/~ece533/images/girl.png"
Images 4, "https://homepages.cae.wisc.edu/~ece533/images/goldhill.bmp, https://homepages.cae.wisc.edu/~ece533/images/tulips.png"

【问题讨论】:

    标签: php curl


    【解决方案1】:

    我认为问题很可能是协议之前的 url 中有空格 - 使用 trim 删除空格会有所帮助。我没有使用 curl 进行测试,而是简单地使用了file_get_contents,它下载了所有文件。

    $dir = 'c:/temp/downloads/';
    
    $file=__DIR__ . DIRECTORY_SEPARATOR . 'img.csv';
    $file=fopen( $file, 'r' );
    
    
    while( !feof( $file ) ){
        $line = fgetcsv( $file );
        if( !empty( $line[1] ) ){
            $urls = explode( ',', $line[1] );
    
            foreach( $urls as $url ){
                $url=trim( $url );
    
                $bytes = file_put_contents( $dir . basename( $url ), file_get_contents( $url ) );
                printf('Saved %s - size: %sKb<br />',basename( $url ),$bytes / 1024 );
            }
        }
    }
    fclose( $file );
    

    curl 函数也需要稍作调整——因为 url 是通过 SSL 的,所以你真的应该在 curl 请求中添加额外的参数。我像这样修改了函数:

    function saveImage( $url, $image_path ){
        global $cacert;
        $fp = fopen( $image_path, 'w+' );
    
        $ch = curl_init( $url );
        curl_setopt($ch, CURLOPT_HEADER, 0 );
        curl_setopt($ch, CURLOPT_TIMEOUT, 10 );
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true );
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true );
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2 );
        curl_setopt($ch, CURLOPT_CAINFO, $cacert );
        curl_setopt($ch, CURLOPT_ENCODING, '' );
        curl_setopt($ch, CURLOPT_FILE, $fp );
    
        curl_exec($ch);
        curl_close ($ch);
        fclose($fp);
    }
    

    $cacert 在其他地方定义,但本质上,在我的系统上是c:\wwwroot\cacert.pem ~ 你可以从here - curl.haxx.se 下载副本

    我运行的是这段代码而不是上面的代码:

    while( !feof( $file ) ){
        $line = fgetcsv( $file );
        if( !empty( $line[1] ) ){
            $urls = explode( ',', $line[1] );
    
            foreach( $urls as $url ){
                $url=trim( $url );
                saveImage( $url, $dir . basename( $url ) );
            }
        }
    }
    fclose( $file );
    

    【讨论】:

      猜你喜欢
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多