V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
viskem
V2EX  ›  PHP

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

  •  
  •   viskem · 2015-04-27 21:30:25 +08:00 · 4265 次点击
    这是一个创建于 3523 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 条回复    2015-05-08 17:44:17 +08:00
    itaotao
        1
    itaotao  
       2015-04-27 21:34:44 +08:00   ❤️ 1
    我建议你去网上搜一段现成的代码吧 这是最基本的功能了
    viskem
        2
    viskem  
    OP
       2015-04-27 21:36:08 +08:00
    @itaotao 其实上面那段就是我搜到的……
    myleon
        3
    myleon  
       2015-04-27 21:46:50 +08:00   ❤️ 1
    可以用file_put_contents
    file_put_contents("保存路径包括文件名","远程地址");
    ashong
        4
    ashong  
       2015-04-27 21:52:02 +08:00   ❤️ 1
    $fp2=@fopen($filename, "a");
    myleon
        5
    myleon  
       2015-04-27 21:54:45 +08:00   ❤️ 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  
       2015-04-27 22:04:21 +08:00   ❤️ 1
    fopen执行成功了吗?为什么要加@?
    hiboshi
        7
    hiboshi  
       2015-04-28 00:00:32 +08:00   ❤️ 1
    直接file_get_content 拿到文件名 然后再去写
    esile
        8
    esile  
       2015-04-28 04:40:47 +08:00 via iPhone   ❤️ 1
    用curl并且设置合适的超时
    Hello1995
        9
    Hello1995  
       2015-04-28 08:35:11 +08:00 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  
       2015-04-28 13:52:27 +08:00   ❤️ 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
       2015-04-28 20:33:55 +08:00
    @Hello1995
    @Arrowing
    @hiboshi
    @myleon
    今天翻阅了一篇文章,不知道这个是否能说明fwrite效率要高那么一点,因为我抓取的量比较大。
    感谢各位的提示。
    viskem
        12
    viskem  
    OP
       2015-04-28 20:34:52 +08:00
    suchasplus
        13
    suchasplus  
       2015-05-06 13:56:40 +08:00   ❤️ 1
    还在搞vglook啊
    viskem
        14
    viskem  
    OP
       2015-05-08 17:44:17 +08:00
    @suchasplus 是啊,再烂也得坚持嘛~哈哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1027 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 19:53 · PVG 03:53 · LAX 11:53 · JFK 14:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.