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

2015-04-27 21:30:25 +08:00
 viskem
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有没有什么更好的办法处理这种问题?
有没有其他方法来存图片。
4068 次点击
所在节点    PHP
14 条回复
itaotao
2015-04-27 21:34:44 +08:00
我建议你去网上搜一段现成的代码吧 这是最基本的功能了
viskem
2015-04-27 21:36:08 +08:00
@itaotao 其实上面那段就是我搜到的……
myleon
2015-04-27 21:46:50 +08:00
可以用file_put_contents
file_put_contents("保存路径包括文件名","远程地址");
ashong
2015-04-27 21:52:02 +08:00
$fp2=@fopen($filename, "a");
myleon
2015-04-27 21:54:45 +08:00
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
2015-04-27 22:04:21 +08:00
fopen执行成功了吗?为什么要加@?
hiboshi
2015-04-28 00:00:32 +08:00
直接file_get_content 拿到文件名 然后再去写
esile
2015-04-28 04:40:47 +08:00
用curl并且设置合适的超时
Hello1995
2015-04-28 08:35:11 +08:00
<?php
$img = file_get_contents('http://www.baidu.com/img/baidu_logo.gif');
file_put_contents('baidu_logo.gif',$img);
?>

我是这么干的。
Arrowing
2015-04-28 13:52:27 +08:00
我以前写的
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
2015-04-28 20:33:55 +08:00
@Hello1995
@Arrowing
@hiboshi
@myleon
今天翻阅了一篇文章,不知道这个是否能说明fwrite效率要高那么一点,因为我抓取的量比较大。
感谢各位的提示。
viskem
2015-04-28 20:34:52 +08:00
suchasplus
2015-05-06 13:56:40 +08:00
还在搞vglook啊
viskem
2015-05-08 17:44:17 +08:00
@suchasplus 是啊,再烂也得坚持嘛~哈哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/186807

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX