我想使用fopen,fwrite将文件从外部服务器保存到服务器上的文件夹中。
首先加载外部网站的页面,然后扫描任何图像链接。然后该列表从一个fwrite函数发送。文件已创建,但它们不是有效的jpg文件,在浏览器中查看它们似乎是在我的服务器上写入它们的路径。
以下是代码:
//read the file
$data = file_get_contents("http://foo.html");
//scan content for jpg links
preg_match_all('/src=("[^"]*.jpg)/i', $data, $result);
//save img function
function save_image($inPath,$outPath)
{
$in= fopen($inPath, "rb");
$out= fopen($outPath, "wb");
while ($chunk = fread($in,8192))
{
fwrite($out, $chunk, 8192);
}
fclose($in);
fclose($out);
}
//output each img link from array
foreach ($result[1] as $imgurl) {
echo "$imgurl<br />\n";
$imgn = (basename ($imgurl));
echo "$imgn<br />\n";
save_image($imgurl, $imgn);
}
如果我写出一个列表,save_image函数会起作用:
save_image('http://foo.html', foo1.jpg);
save_image('http://foo.html', foo1.jpg);
我希望我能够从数组中的匹配项中循环列表。
谢谢你的期待。
答案 0 :(得分:1)
您的脚本有两个问题。首先,引号标记包含在外部图像URL中。要解决这个问题,你的正则表达式应该是:
/src="([^"]*.jpg)/i
其次,图像URL可能不是绝对的(不包括http://和文件路径)。把它放在你的foreach的开头,以解决这个问题:
$url = 'http://foo.html';
# If the image is absolute.
if(substr($imgurl, 0, 7) == 'http://' || substr($imgurl, 0, 8) == 'https://')
{
$url = '';
}
# If the image URL starts with /, it goes from the website's root.
elseif(substr($imgurl, 0, 1) == '/')
{
# Repeat until only http:// and the domain remain.
while(substr_count($url, '/') != 2)
{
$url = dirname($url);
}
}
# If only http:// and a domain without a trailing slash.
elseif(substr_count($imgurl, '/') == 2)
{
$url .= '/';
}
# If the web page has an extension, find the directory name.
elseif(strrpos($url, '.') > strrpos($url, '/'))
{
$url = dirname($url);
}
$imgurl = $url. $imgurl;
答案 1 :(得分:0)
fopen不能保证有效。您应该检查任何可能在错误时返回不同内容的返回值...
fopen()
- 成功时返回文件指针资源,错误时返回FALSE。
实际上所有文件函数在出错时都返回false。
要弄清楚它失败的地方,我建议使用调试器,或在save_image函数中打印出一些信息。即$ inPath和$ outPath是什么,因此您可以验证它们正在传递您期望的内容。
答案 2 :(得分:0)
我看到的主要问题是正则表达式可能无法捕获完整的http://
路径。大多数网站都将其关闭并使用相对路径。您应该对其进行编码并将其添加(如果不存在)。
答案 3 :(得分:0)
你的匹配包括src位,所以请尝试这样做:
preg_match_all('/(?<=src=")[^"]*.jpg/i', $data, $result);
然后我认为这应该有效:
unset($result[0]);
//output each img link from array
foreach ($result as $imgurl) {
echo "$imgurl<br />\n";
$imgn = (basename ($imgurl));
echo "$imgn<br />\n";
save_image($imgurl, $imgn);
}