viskem
V2EX  ›  PHP

我在做一些抓取外网图片到本地的功能,但 fwrite 总是写坏文件。

  •  
  •   viskem · Apr 27, 2015 · 4892 views
    This topic created in 4043 days ago, the information mentioned may be changed or developed.
    function GrabImage($url,$filename) {
    if($url==""||$filename==""):return false;
    endif;

    ob_start();
    readfile($url);
    $img = ob_get_contents();
    ob_end_clean();
    $size = strlen($img);

    $fp2=@fopen($filename, "a");
    fwrite($fp2,$img);
    fclose($fp2);

    return $filename;
    }

    我用了这样的一个方法,但有时候会出现两个问题:
    1、图片文件下了一半,图像损坏
    2、之前已经下载过的图片,再次下载不是覆盖,而是追加内容(原本7K的图片,再次写入就是14K了,但图片照样能看)(我的文件名也不能做成随机的,得固定,因为和访问路径有关联)。

    请问PHP有没有什么更好的办法处理这种问题?
    有没有其他方法来存图片。
    14 replies    2015-05-08 17:44:17 +08:00
    itaotao
        1
    itaotao  
       Apr 27, 2015   ❤️ 1
    我建议你去网上搜一段现成的代码吧 这是最基本的功能了
    viskem
        2
    viskem  
    OP
       Apr 27, 2015
    @itaotao 其实上面那段就是我搜到的……
    superliang
        3
    superliang  
       Apr 27, 2015   ❤️ 1
    可以用file_put_contents
    file_put_contents("保存路径包括文件名","远程地址");
    ashong
        4
    ashong  
       Apr 27, 2015   ❤️ 1
    $fp2=@fopen($filename, "a");
    superliang
        5
    superliang  
       Apr 27, 2015   ❤️ 1
    mode 说明
    "r" 只读方式打开,将文件指针指向文件头。
    "r+" 读写方式打开,将文件指针指向文件头。
    "w" 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
    "w+" 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
    "a" 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
    "a+" 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
    "x"

    创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。

    这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。

    此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。
    "x+"

    创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。

    这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。

    此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。
    mahone3297
        6
    mahone3297  
       Apr 27, 2015   ❤️ 1
    fopen执行成功了吗?为什么要加@?
    hiboshi
        7
    hiboshi  
       Apr 28, 2015   ❤️ 1
    直接file_get_content 拿到文件名 然后再去写
    esile
        8
    esile  
       Apr 28, 2015 via iPhone   ❤️ 1
    用curl并且设置合适的超时
    Hello1995
        9
    Hello1995  
       Apr 28, 2015 via Android   ❤️ 1
    <?php
    $img = file_get_contents('http://www.baidu.com/img/baidu_logo.gif');
    file_put_contents('baidu_logo.gif',$img);
    ?>

    我是这么干的。
    Arrowing
        10
    Arrowing  
       Apr 28, 2015   ❤️ 1
    我以前写的
    function get_local_pic_url($pic_url){

    $time = time();
    $pic_local_path = dirname(__FILE__).'/cache';
    $pic_local = $pic_local_path.'/'.$time;

    if(!file_exists($pic_local_path)){
    mkdir($pic_local_path,0777);
    @chmod($pic_local_path,0777);
    }

    ob_start(); //打开输出
    readfile($pic_url); //输出图片文件
    $img = ob_get_contents(); //得到浏览器输出
    ob_end_clean(); //清除输出并关闭
    file_put_contents($pic_local, $img);
    return $pic_local;
    }
    viskem
        11
    viskem  
    OP
       Apr 28, 2015
    @Hello1995
    @Arrowing
    @hiboshi
    @myleon
    今天翻阅了一篇文章,不知道这个是否能说明fwrite效率要高那么一点,因为我抓取的量比较大。
    感谢各位的提示。
    viskem
        12
    viskem  
    OP
       Apr 28, 2015
    suchasplus
        13
    suchasplus  
       May 6, 2015   ❤️ 1
    还在搞vglook啊
    viskem
        14
    viskem  
    OP
       May 8, 2015
    @suchasplus 是啊,再烂也得坚持嘛~哈哈
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1078 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 67ms · UTC 23:19 · PVG 07:19 · LAX 16:19 · JFK 19:19
    ♥ Do have faith in what you're doing.