【问题标题】:cURL Save File to Server With Mime Type CheckcURL 使用 Mime 类型检查将文件保存到服务器
【发布时间】:2013-03-07 07:20:30
【问题描述】:

我正在为我的团队创建一个内部工具,允许受信任的团队成员通过 php 和 curl 将远程文件保存到我们的服务器。我的 open、write 和 close 工作正常,但我想在创建和写入本地文件之前添加一个检查以确保文件是某种 mime 类型。

根据一组 mime 类型,我该如何做到这一点?

$ch = curl_init();
$fp = fopen($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);

【问题讨论】:

  • 我希望你知道服务器发送的 mime 类型在服务器端是可配置的。例如。任何使用 php 的人都可以设置他们想要的任何 mime 类型。您可能需要检查文件扩展名,或使用“文件”之类的实用程序来检查内容

标签: php curl mime-types fopen


【解决方案1】:

我通过在文件传输后通过 fileinfo 检查 mime 解决了这个问题。如果它不是有效的 mime 类型,则将其删除。

$ch = curl_init();
$fp = fopen($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);

$finfo = new finfo(FILEINFO_MIME);
$mime_type = $finfo->file($local_file);

if (strpos($mime_type, 'application/xml') === false) {
    unlink($local_file);
}

【讨论】:

    【解决方案2】:

    例如:

    $ch = curl_init('http://static.php.net/www.php.net/images/php.gif');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_exec($ch);
    
    $mime = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    

    $mime 中具有 mime 类型的文件。

    【讨论】:

      【解决方案3】:

      棘手!您可以先下载整个文件(到内存或临时文件夹中)。如果您想流式传输它,您可能必须:

      1. 设置 CURLOPT_HEADER 以在您返回的数据中包含 HTTP 响应标头

      2. 设置 CURLOPT_WRITEFUNCTION 而不是 CURLOPT_FILE,读取并解析 http 标头以查看 mime 类型,然后决定是否要创建/写入文件。

      显然,这是一项相当多的工作,因为您必须对 HTTP 标头进行一些基本的解析,并且可能会进行缓冲以一次获取整个 HTTP 标头。

      希望有人会发布一个更简单的解决方案。

      伪代码:

      state = headers
      buf = ''
      fd = null
      func writefunc(ch, data)
         if state is headers
            buf .= data
            div = buf.strpos "\r\n\r\n"
            if div !== false
               mime = get_mime buf, div
               if mime_ok mime
                  fd = fopen ...
                  fd.write buf.substr div+4
                  state = saving
               else
                  # returns other than data.length() abort connection
                  return 0
        else
           fd.write data
        return data.length()
      

      【讨论】:

      • 如果服务器不通过 Content-Type 怎么办?我想在下载之前检查文件大小?
      • 如果没有 mime 类型,mime_ok 将返回 false。 HTTP 协议并不总是发送 Content-Length。
      猜你喜欢
      • 2011-10-29
      • 2012-07-19
      • 2021-12-18
      • 2012-09-10
      • 1970-01-01
      • 2013-04-24
      • 2016-01-28
      • 1970-01-01
      • 2013-11-19
      相关资源
      最近更新 更多