【问题标题】:Using fopen, fwrite multiple times in a foreach loop在一个foreach循环中使用fopen、fwrite多次
【发布时间】:2011-03-06 22:21:06
【问题描述】:

我想使用 fopen、fwrite 将文件从外部服务器保存到我服务器上的文件夹中。

首先加载来自外部站点的页面,并扫描任何图像链接。然后将该列表从 an 发送到 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);

我希望我能够从数组中的匹配项中循环列表。

感谢收看。

【问题讨论】:

    标签: php arrays loops foreach fwrite


    【解决方案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;
    

    【讨论】:

      【解决方案2】:

      fopen 不能保证正常工作。您应该检查它们在错误时可能返回不同内容的任何返回值...

      fopen() - 成功返回文件指针资源,错误返回 FALSE。

      事实上,所有的文件函数都会在出错时返回 false。

      要找出失败的地方,我建议使用调试器,或者在 save_image 函数中打印一些信息。即 $inPath 和 $outPath 是什么,因此您可以验证它们是否按照您的预期传递。

      【讨论】:

        【解决方案3】:

        我看到的主要问题是正则表达式可能无法捕获完整的http:// 路径。大多数站点都将其关闭并使用相对路径。您应该对此进行编码并在不存在的情况下将其添加。

        【讨论】:

          【解决方案4】:

          您的匹配项包含 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);
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-25
            • 1970-01-01
            • 1970-01-01
            • 2012-03-22
            • 2016-08-08
            相关资源
            最近更新 更多