PHP - 下载大文件的安全方法?

2024-04-01

信息

PHP下载文件的方法有很多种,文件获取内容 http://php.net/manual/en/function.file-get-contents.php + 文件放置内容 http://php.net/manual/en/function.file-put-contents.php, fopen http://php.net/manual/en/function.fopen.php, readfile http://php.net/manual/en/function.readfile.php和卷曲。

问题?

  • 当有一个大文件时,假设来自另一个服务器/域的 500 MB,安全下载它的“正确”方法是什么?如果连接失败,它应该找到位置并继续,或者如果文件包含错误,则再次下载文件。
  • 它将在网站上使用,而不是在 php.exe shell 中使用。

到目前为止我想到了什么

  • 我读过有关带有进度条的 AJAX 解决方案,但我真正寻找的是 PHP 解决方案。
  • 我不需要像 file_get_contents 那样将文件缓冲到字符串中。这可能也使用内存。
  • 我还读过有关记忆问题的文章。不使用那么多内存的解决方案可能是首选。

Concept

如果结果是假的,这就是我想要的。

function download_url( $url, $filename ) {
    // Code
    $success['success'] = false;
    $success['message'] = 'File not found';
    return $success;
}

复制大文件的最简单方法可以在这里演示从 php stdin 保存大文件 https://stackoverflow.com/questions/14187993/save-large-files-from-php-stdin/14188059#14188059但没有显示如何复制具有 http 范围的文件

$url = "http://REMOTE_FILE";
$local = __DIR__ . "/test.dat";

try {
    $download = new Downloader($url);
    $download->start($local); // Start Download Process
} catch (Exception $e) {
    printf("Copied %d bytes\n", $pos = $download->getPos());
}

当发生异常时,您可以恢复最后一点的文件下载

$download->setPos($pos);

使用的类别

class Downloader {
    private $url;
    private $length = 8192;
    private $pos = 0;
    private $timeout = 60;

    public function __construct($url) {
        $this->url = $url;
    }

    public function setLength($length) {
        $this->length = $length;
    }

    public function setTimeout($timeout) {
        $this->timeout = $timeout;
    }

    public function setPos($pos) {
        $this->pos = $pos;
    }

    public function getPos() {
        return $this->pos;
    }

    public function start($local) {
        $part = $this->getPart("0-1");

        // Check partial Support
        if ($part && strlen($part) === 2) {
            // Split data with curl
            $this->runPartial($local);
        } else {
            // Use stream copy
            $this->runNormal($local);
        }
    }

    private function runNormal($local) {
        $in = fopen($this->url, "r");
        $out = fopen($local, 'w');
        $pos = ftell($in);
        while(($pos = ftell($in)) <= $this->pos) {
            $n = ($pos + $this->length) > $this->length ? $this->length : $this->pos;
            fread($in, $n);
        }
        $this->pos = stream_copy_to_stream($in, $out);
        return $this->pos;
    }

    private function runPartial($local) {
        $i = $this->pos;
        $fp = fopen($local, 'w');
        fseek($fp, $this->pos);
        while(true) {
            $data = $this->getPart(sprintf("%d-%d", $i, ($i + $this->length)));

            $i += strlen($data);
            fwrite($fp, $data);

            $this->pos = $i;
            if ($data === - 1)
                throw new Exception("File Corupted");

            if (! $data)
                break;
        }

        fclose($fp);
    }

    private function getPart($range) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->url);
        curl_setopt($ch, CURLOPT_RANGE, $range);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        $result = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        // Request not Satisfiable
        if ($code == 416)
            return false;

            // Check 206 Partial Content
        if ($code != 206)
            return - 1;

        return $result;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP - 下载大文件的安全方法? 的相关文章

  • 从关系中合并 Laravel 中的集合

    假设我有 3 张桌子 Images Subject Style 关系是多对多 图像 主题 和多对多 图像 样式 现在我想做一些类似的事情 result subjectResult gt images gt merge styleResult
  • 如何更改 Ubuntu 14.04 上的 php-cli 版本?

    我是 Linux 新手 在篡改时破坏了一些 php 设置 如果我执行一个包含以下内容的 php 脚本 phpinfo 它显示 php 版本为 5 6 但通过命令行 如果我运行php v它返回 7 0 版本 我想让两个版本匹配 我怎样才能修复
  • 计算特定产品类别的购物车商品数量

    我试图仅从 WooCommerce 中的特定产品类别获取购物车中的商品数量 我正在为一家酒厂做一个网站 它有酒精和非酒精产品 所有葡萄酒都属于 葡萄酒 主类别或类别 ID 34 其下有许多子类别和产品 对于属于此类别的任何商品 我需要知道此
  • Monolog,如何将 PHP 数组记录到控制台?

    我正在使用浏览器处理程序将消息记录到 JS 控制台 require once vendor autoload php use Monolog Logger use Monolog Handler BrowserConsoleHandler
  • 简单的颜色变化

    我正在创建一个用户界面 用户可以在其中更改页面的颜色值 我想要的是获取分配给其背景颜色的值并将其变亮一定程度 我只是想获得一条亮点线 而不必每次都制作新图像 示例 用户将背景颜色设置为 ECECEC 现在我希望某个元素边框变成 F4F4F4
  • preg_match 所有以@开头的单词?

    我对正则表达式不太确定 所以我不得不问你 如何用 PHP 判断字符串中是否包含以 开头的单词 例如我有一个像 This is for codeworxx 这样的字符串 我很抱歉 但我没有任何起点 希望你能帮忙 谢谢 萨沙 好的 谢谢你的结果
  • 如何处理 PHP 中浮点数的奇怪舍入

    众所周知 浮点运算并不总是完全准确 但是如何处理它的不一致之处呢 As an example in PHP 5 2 9 this doesn t happen in 5 3 echo round 14 99225 4 14 9923 ech
  • 从 json 数组获取值并执行 sql 插入

    这是我的数组 json 1 Device ID a9a3346be4375a92 Date 2012 05 31 Time 15 22 59 Latitude 51 4972912 Longitude 0 1108178 2 Device
  • 匹配括号内任何字符的正则表达式

    尝试创建一个与括号内的任何字符匹配的正则表达式 我的正则表达式模式是这样的 preg match listanswer answer 括号内的所有字符串都是匹配模式 但问题是 当我尝试匹配例如 this word sample data 它
  • 如何使用 PHP 查找目录中的前 5 个文件?

    如何使用 PHP 列出按字母顺序排序的目录中的前 5 个文件或目录 Using scandir array slice array filter scandir path to dir is file 0 5 The array filte
  • Symfony 学说错误“DoctrineMigrationsBundle 需要启用 DoctrineBundle。”

    我创建了一个新的 Symfony 项目 并且不断收到此消息 DoctrineMigrationsBundle 需要启用 DoctrineBundle 错误并且无法摆脱它 显然我是这个星球上唯一一个收到此错误的人 因为谷歌并没有太大帮助 在
  • ajax 会增加还是降低安全性?

    我正在创建一个网站 到目前为止它是纯 PHP 的 我在想 既然很少有人没有启用 JavaScript 我想知道为什么 也许我应该将我的网站创建为一个完全 PHP 的网站 而不使用任何 AJAX 难道是我想错了 可以肯定的是 如果我实施一些
  • 计算轮班工作时间并检测

    我有个问题 我的英语很差 我需要用PHP做一个加班计算 已经有一个代码可以实现这一点 但当工作时间超过2天时 计算就会出错 工作开始 2018 09 09 13 43 工作结束 2018 09 11 07 13 结果 07 18 04 00
  • 如何让Symfony2直接加载CSS、JS文件而不是通过PHP?

    老问题 请参阅下面的更新版本 我的开发环境不是最快的 每个 PHP 请求大约需要 500 毫秒 它开始成为 Symfony2 资源文件的问题 因为每个资源文件都是通过 Symfony 的内部控制器请求的 http localhost myp
  • Mandrill 验证错误

    很高兴能在 StackOverflow 上提出我的第一个问题 多年来我一直依靠它自学了很多东西 我的问题是这样的 尝试通过 Mandrill 的 API 发送邮件时出现以下错误 status error code 1 name Valida
  • 使用 Flot、html、PHP 和 MySql 查询绘制多个图表

    我正在尝试使用 Flot html PHP 和 MySql 查询绘制多个图表 但我陷入了困境 因为我找不到在同一个 html 页面中绘制多个 flot 的方法 为简单起见 在数据库 test db3 映像中包含以下字段 表1 用户名 发送邮
  • 将价格格式设置为逗号分隔

    在我的数据库中 我有类似的值 256 23 200 33 89 33 133 45 我必须将这些值乘以千 然后将结果格式化为价格 逗号分隔 256 23 x 1000 256230 I want to show this as 256 23
  • 仅在 Chrome 上我收到此错误:Uncaught TypeError: Illegal constructor [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 当我在 Chrome 上加载 jQuery 时 我会收到此错误 Uncaught TypeError Illegal constr
  • 下载进度条在 iOS 企业发行版中没有改变进度

    我正在通过企业分发开发和分发 iPad 应用程序 它们下载并执行良好 因此一切正常 Web 链接 ipa 文件 plist 文件 配置 问题 是 当用户单击链接进行下载时 iPad 中显示下载进度的进度条显示 正在等待 但却是空的并且永远不
  • 如何检查号码是否是巴基斯坦用户的手机号码而不是固定电话号码

    我所做的是从开头删除 92 或 0092 并使用以下代码检查它是否是巴基斯坦人的有效手机号码 if preg match 3 0 4 0 9 number 1 Pakistani mobile number else not a pakis

随机推荐

  • 如何在 TypeScript 中链接/连接/关联两个类字段的类型?

    如何让 TypeScript 识别类中一个字段的值限制另一个字段的类型 示例代码 操场 https www typescriptlang org play code MYGwhgzhAEDCYBdoG9oAcCuAnLAKAlCgPQBUA
  • 将操作数放在 getopt() 的前面

    使用getopt C 中的函数 可以这样做 program a arg for a b arg for b c operand1 operand2 并且它的工作没有问题 但是 如何让它以这种方式工作 program operand1 ope
  • 如何找到 MIT 方案中出现错误的地方?

    当你在 MIT 方案中遇到错误时 它不会告诉你错误发生在哪里 例如 它只打印如下内容 Unbound variable top left To continue call RESTART with an option number REST
  • data.table 中多次转换时如何避免相同的列名?

    我尝试对同一列进行多次转换data table并发现这个答案 https stackoverflow com a 16367829 3409615 但是 如果我按照那里的步骤操作 我会得到相同的列名称 而不是mean Obs 1 etc l
  • 如何为 php mvc 构建一个好的路由器

    我正在尝试 php mvc 但遇到了以下问题 我的请求和路由器类非常简单 我想扩展主题以处理来自子文件夹的控制器调用 并且控制器类函数应该能够拾取 url 变量发送它抛出 get 和 post 我的路由器如下所示 class Router
  • helm 图表模板:如果值不存在,则默认为 true

    我试图声明 如果变量为 true 或不存在 即 var 的默认值为 true 则应存在 helm 模板中的代码块 以下作品 if or Values livenessProbe not hasKey Values livenessProbe
  • 在Spyder中创建子单元格

    是否有任何解决方法可以在 Spyder 中创建子单元 例如 我知道与 Cell 1 我可以创建一个新的单元格 但是有没有办法创建一个子单元格 该子单元格分组在单元格下 如下所示 Cell 1 1 我已经发现this https github
  • scala:如何以函数式方式处理验证

    我正在开发一种方法 如果它通过了一系列条件 则该方法应该保留对象 如果任何 或多个 条件失败 或出现任何其他类型的错误 则应返回包含错误的列表 如果一切顺利 则应返回已保存的实体 我正在考虑这样的事情 当然 这是伪代码 request bo
  • 运行控制器方法的异步 PHP 调用

    我想在按钮单击事件上执行 localhost codeigniter controller method 该方法将从网页中提取关键字并将其存储在数据库中 其中有多个子方法也应该在后台运行 我不想让用户在此期间等待 我读this https
  • 错误:对于类字符的对象没有整洁的方法

    我正在尝试转换表中的以下元素列表 下面您可以找到创建列表的方法 alt 1 data long gt ggpubr compare means value COND group by c SES signals method t test
  • OCMock:存根 @dynamic 属性

    我正在尝试将单元测试添加到现有的 iOS 应用程序中 其中使用OCMock 在此应用程序中 我们有一堆 CoreData 实体和生成的类 这些类显然包含 dynamic特性 我尝试按如下方式存根这些属性之一 self event OCMoc
  • 这两种在 JavaScript 中构造对象的方法等效吗?

    Given function A name this name name is var a1 new A A1 完全等同于 var a1 A call a1 A1 a1 proto A prototype Thanks 嗯 有一个问题是 p
  • Facebook 会话在 Android 登录过程后关闭

    我正在开发 Android 应用程序 需要登录 Facebook 才能发布 Facebook 评论 但是我在登录时遇到了困难 所以我按照以下教程进行操作https developers facebook com docs tutorials
  • 为什么prometheus Operator无法启动

    我正在尝试在全新的 k8s 集群中使用操作符创建 prometheus 我使用以下文件 我正在创建一个命名空间监控 应用这个文件 就可以正常工作了 apiVersion apps v1beta2 kind Deployment metada
  • 获取 GCM 时如何在锁屏上显示弹出对话框(如 Android 闹钟)

    我需要在锁定屏幕顶部显示消息 就像 Android 闹钟一样 当该起床的时候 它会全屏显示闹钟 这是出现警报时弹出的屏幕之一的照片 截屏 https i stack imgur com lPrFe jpg Window window get
  • 使用外部 C DLL 时 Python 中的内存泄漏

    我有一个 python 模块 它调用 C 编写的 DLL 来编码 XML 字符串 一旦函数返回编码字符串 它就无法取消分配在此步骤中分配的内存 具体来说 编码MyString ctypes create string buffer 4096
  • 在 Visual Studio 扩展中,如何检测调试器何时继续

    我需要 Visual Studio 扩展来对调试事件做出反应 我已经注册了一个IDebugEventCallback2我正在接收事件 但我为每个事件得到的只是一个不透明的IDebugEvent2和一个 Guid 其中许多不仅没有记录 而且不
  • 如何逆序获取输入流的内容?

    我正在使用 txt 文件进行关卡设计 我使用下面的内容来获取内容并转换为字符串缓冲区 然后迭代各行以生成我的游戏对象 问题是它是从上到下读取的 所以我必须颠倒设计我的关卡 以便它们是正确的 如何更改流以相反的方式读取 或者以相反的方式将行写
  • os.path python 模块在heroku 中不起作用

    我正在 heroku 上构建 django 应用程序 但遇到了很多麻烦os path模块 我的项目无法找到templates在 Heroku 上 同时它在 localhost 上完美运行 这是我的项目层次结构 简而言之 project pr
  • PHP - 下载大文件的安全方法?

    信息 PHP下载文件的方法有很多种 文件获取内容 http php net manual en function file get contents php 文件放置内容 http php net manual en function fi