代码笔记 | PHP支持断点续传,分块下载的类

socket-php文件分段上传(带进度条)(0分资源) 立即下载
 
<?php
  
/**
 * User: djunny
 * Date: 2016-04-29
 * Time: 17:18
 * Mail: 199962760@qq.com
 * 支持断点下载的类
 */
class downloader {
  
    /**
     * download file to local path
     *
     * @param       $url
     * @param       $save_file
     * @param int   $speed
     * @param array $headers
     * @param int   $timeout
     * @return bool
     * @throws Exception
     */
    static function get($url, $save_file, $speed = 10240, $headers = array(), $timeout = 10) {
        $url_info = self::parse_url($url);
        if (!$url_info['host']) {
            throw new Exception('Url is Invalid');
        }
  
        // default header
        $def_headers = array(
            'Accept'          => '*/*',
            'User-Agent'      => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
            'Accept-Encoding' => 'gzip, deflate',
            'Host'            => $url_info['host'],
            'Connection'      => 'Close',
            'Accept-Language' => 'zh-cn',
        );
  
        // merge heade
        $headers = array_merge($def_headers, $headers);
        // get content length
        $content_length = self::get_content_size($url_info['host'], $url_info['port'], $url_info['request'], $headers, $timeout);
  
        // content length not exist
        if (!$content_length) {
            throw new Exception('Content-Length is Not Exists');
        }
        // get exists length
        $exists_length = is_file($save_file) ? filesize($save_file) : 0;
        // get tmp data file
        $data_file = $save_file . '.data';
        // get tmp data
        $exists_data = is_file($data_file) ? json_decode(file_get_contents($data_file), 1) : array();
        // check file is valid
        if ($exists_length == $content_length) {
            $exists_data && @unlink($data_file);
            return true;
        }
        // check file is expire
        if ($exists_data['length'] != $content_length || $exists_length > $content_length) {
            $exists_data = array(
                'length' => $content_length,
            );
        }
        // write exists data
        file_put_contents($data_file, json_encode($exists_data));
  
        try {
            $download_status = self::download_content($url_info['host'], $url_info['port'], $url_info['request'], $save_file, $content_length, $exists_length, $speed, $headers, $timeout);
            if ($download_status) {
                @unlink($data_file);
            }
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
        return true;
    }
  
    /**
     * parse url
     *
     * @param $url
     * @return bool|mixed
     */
    static function parse_url($url) {
        $url_info = parse_url($url);
        if (!$url_info['host']) {
            return false;
        }
        $url_info['port']    = $url_info['port'] ? $url_info['host'] : 80;
        $url_info['request'] = $url_info['path'] . ($url_info['query'] ? '?' . $url_info['query'] : '');
        return $url_info;
    }
  
    /**
     * download content by chunk
     *
     * @param $host
     * @param $port
     * @param $url_path
     * @param $headers
     * @param $timeout
     */
    static function download_content($host, $port, $url_path, $save_file, $content_length, $range_start, $speed, &$headers, $timeout) {
        $request = self::build_header('GET', $url_path, $headers, $range_start);
        $fsocket = @fsockopen($host, $port, $errno, $errstr, $timeout);
        stream_set_blocking($fsocket, TRUE);
        stream_set_timeout($fsocket, $timeout);
        fwrite($fsocket, $request);
        $status = stream_get_meta_data($fsocket);
        if ($status['timed_out']) {
            throw new Exception('Socket Connect Timeout');
        }
        $is_header_end = 0;
        $total_size    = $range_start;
        $file_fp       = fopen($save_file, 'a+');
        while (!feof($fsocket)) {
            if (!$is_header_end) {
                $line = @fgets($fsocket);
                if (in_array($line, array("\\n", "\\r\\n"))) {
                    $is_header_end = 1;
                }
                continue;
            }
            $resp        = fread($fsocket, $speed);
            $read_length = strlen($resp);
            if ($resp === false || $content_length < $total_size + $read_length) {
                fclose($fsocket);
                fclose($file_fp);
                throw new Exception('Socket I/O Error Or File Was Changed');
            }
            $total_size += $read_length;
            fputs($file_fp, $resp);
            // check file end
            if ($content_length == $total_size) {
                break;
            }
            sleep(1);
            // for test
            //break;
        }
        fclose($fsocket);
        fclose($file_fp);
        return true;
  
    }
  
    /**
     * get content length
     *
     * @param $host
     * @param $port
     * @param $url_path
     * @param $headers
     * @param $timeout
     * @return int
     */
    static function get_content_size($host, $port, $url_path, &$headers, $timeout) {
        $request = self::build_header('HEAD', $url_path, $headers);
        $fsocket = @fsockopen($host, $port, $errno, $errstr, $timeout);
        stream_set_blocking($fsocket, TRUE);
        stream_set_timeout($fsocket, $timeout);
        fwrite($fsocket, $request);
        $status = stream_get_meta_data($fsocket);
        $length = 0;
        if ($status['timed_out']) {
            return 0;
        }
        while (!feof($fsocket)) {
            $line = @fgets($fsocket);
            if (in_array($line, array("\\n", "\\r\\n"))) {
                break;
            }
            $line = strtolower($line);
            // get location
            if (substr($line, 0, 9) == 'location:') {
                $location = trim(substr($line, 9));
                $url_info = self::parse_url($location);
                if (!$url_info['host']) {
                    return 0;
                }
                fclose($fsocket);
                return self::get_content_size($url_info['host'], $url_info['port'], $url_info['request'], $headers, $timeout);
            }
            // get content length
            if (strpos($line, 'content-length:') !== false) {
                list(, $length) = explode('content-length:', $line);
                $length = (int)trim($length);
            }
        }
        fclose($fsocket);
        return $length;
  
    }
  
    /**
     * build header for socket
     *
     * @param     $action
     * @param     $url_path
     * @param     $headers
     * @param int $range_start
     * @return string
     */
    static function build_header($action, $url_path, &$headers, $range_start = -1) {
        $out = $action . " {$url_path} HTTP/1.0\\r\\n";
        foreach ($headers as $hkey => $hval) {
            $out .= $hkey . ': ' . $hval . "\\r\\n";
        }
        if ($range_start > -1) {
            $out .= "Accept-Ranges: bytes\\r\\n";
            $out .= "Range: bytes={$range_start}-\\r\\n";
        }
        $out .= "\\r\\n";
  
        return $out;
    }
}
  
  
#use age
/*
try {
    if (downloader::get('http://dzs.aqtxt.com/files/11/23636/201604230358308081.rar', 'test.rar')) {
        //todo
        echo 'Download Succ';
    }
} catch (Exception $e) {
    echo 'Download Failed';
}<pre name="code" class="php">*/
?>


socket-php文件分段上传 socket方式连接php服务,可以选择要上传的文件后自动将文件分段上传到服务器上。 立即下载

相关推荐

最新tp5完整版

thinkphp_5.0.20_with_ext完整版框架,包涵验证码等拓展资源!

PHP----下载断点后续传

代码: <?php function dl_file_resume($file){        //检测文件是否存在     if (!is_file($file)) { die("404 File not found!"); }                     $len = filesize($file);//获取文件大小     $filename = basename(

Damys 542

打开socket 下载https文件

备份代码

php 分段下载文件,php中实现分段下载(简例) | 学步园

$fp = fsockopen("127.0.0.1", 20301, $errno, $errstr, 30);if (!$fp) {echo "$errstr ($errno)/n";} else {# 第一段下载$out = "GET /x.zip HTTP/1.1/r/n";$out .= "Range:0-10/r/n";$out .= "Host: 127.0.0.1/r/n";$o...

weixin_36479263的博客 261

VC Spyglass实战指南:从零开始掌握CDC约束配置与调试

本文详细介绍了如何使用VC Spyglass进行CDC约束配置与调试,从基础环境搭建到典型CDC问题调试实战,帮助开发者快速掌握跨时钟域验证技术。通过TCL脚本和SDC约束的深度解析,提升CDC验证效率,避免常见设计风险。

weixin_26757925的博客 294

LM Studio中文版零基础入门:从安装到模型下载的保姆级教程(附国内镜像源配置)

本文提供LM Studio中文版的零基础入门教程,涵盖从软件安装、中文界面切换到国内镜像源配置的全流程。特别针对模型下载速度慢的问题,详细介绍了如何通过修改配置文件使用国内镜像站,并推荐适合新手的入门模型及硬件配置建议,帮助用户快速上手本地大模型运行。

pz890123456的博客 2587

文件上传组件-WEBUPLOADER PHP版

前端:vue2,vue3,vue-cli,html5,jquery后端:php服务器:linux,centos功能:分片,断点续传,加密传输,加密存储昨天晚上一个网友给我发私信聊了一下这个需求,他也是最近在项目上遇到这个需求,但是之前没做过这块,技术积累不够,网上搜了一下大部分用的是HTML5,但是他们之前用过说是稳定性不是特别好。而且没有批量下载功能,只有打包下载,所以咨询这边有没有别的方案。包教会,免费提供培训服务,免费帮助我们公司技术人员培训,学会如何使用和维护,包括二次开发。

alisky119的博客 2021

工业质检实战:如何用MVTec AD数据集训练你的第一个无监督异常检测模型

本文提供了一份基于MVTec AD数据集的工业质检实战指南,详细介绍了如何从零开始训练一个无监督异常检测模型。内容涵盖数据预处理、模型架构选型(如CAE、GAN与特征字典方法)、特征提取、损失函数设计以及关键的阈值确定与后处理流程,旨在帮助工程师快速掌握将AI技术落地于实际产线质检的核心步骤与调参经验。

weixin_29182481的博客 458

php大文件及续传,php大文件下载代码(支持断点续传)

//下载文件,调用示例download($url,$file_name);function download($url, $filename) {// 获得文件大小, 防止超过2G的文件, 用sprintf来读//print "文件地址:".$url."";//print "文件大小:".filesize ($url)."";$filesize = sprintf ( "%u", getFileS...

weixin_42347324的博客 183

Android 13.0 Launcher3中去掉Hotseat功能实现

在13.0系统产品定制化开发中,在Launcher3的定制化需求也是特别多的,由产品是小屏幕的产品,所以产品需求Launcher3 页面布局的原因,要求Launcher3 需要去掉Hotseat 不显示Hotseat下面几个图标,而做满屏app的显示,从而达到美观的效果,下面就来分析去掉Hotseat从而实现这个功能

安卓兼职framework和app工程师的博客 1327

【麒麟桌面系统】企业微信提示当前副设备的企业微信版本较低

银河麒麟系统中登录企业微信时出现"副设备版本较低"的报错,可通过两种方案解决:1)更新最新版企业微信,需替换软件源并刷新软件商店安装8.0-50-4.1.26.6019kylin5版本;2)安装内测5.0版本企业微信,需下载deb包后使用sudo dpkg命令安装。文章还提供了常见问题解决表和长期维护建议,包括系统更新检查、软件源验证等维护项目及具体操作指南。

信创运维工程师 · 银河麒麟 & 容器实战 | 金融生产环境迁移·等保加固 | 142篇原创·17万+阅读 2268

php 通过ftp 下载文件,php实现从ftp服务器上下载文件树到本地电脑的程序

复制代码代码如下:/*用ftp_nlist()函授时,返回的数组值会有两种类型:因服务器不同而异a:单独的文件名b:包含目录的文件名。如果挪用,请注意更改此处。*/functiondownload_file($dir,$fc,$_FILE_){$fn=ftp_nlist($fc,".");//列出该目录的文件名(含子目录),存储在数组中$size=sizeof($fn);$dir=($dir=="...

weixin_31476341的博客 393

Python爬虫实战:利用Playwright与反反爬技术抓取Crunchbase企业数据

在当今数据驱动的商业环境中,获取准确的企业信息对于市场分析、竞争情报和投资决策至关重要。Crunchbase作为全球领先的企业信息平台,包含了数百万家公司、投资者和关键人员的详细数据。本文将深入探讨如何使用Python最新爬虫技术Playwright,结合多种反反爬策略,高效抓取Crunchbase企业数据。我们将从爬虫基础概念讲起,逐步深入到高级技巧,并提供完整的代码实现,帮助读者掌握现代网络数据采集的核心技术。网络爬虫技术自互联网诞生以来经历了显著演变。

2201_76125261的博客 1832

PHP大文件上传插件,支持分块与断点续传的有哪些?

要求:免费,开源,专业技术支持前端:vue2,vue3,vue-cli,html5,jquery,webuploader后端:php服务器:linux,centos,Windows,数据库:MySQL,达梦数据库,人大金仓平台:Windows,macOS,Linux,Ubuntu,RedHat,中标麒麟,银河麒麟,统信UOS,信创国产化CPU:x86(Intel,AMD,兆芯,海光),arm(鲲鹏,飞腾),龙芯(mips),龙芯(LoongArch)

alisky119的博客 1356

如何让 Mac mini 24小时不休眠运行 OpenClaw

如果 OpenClaw 每 5-10 分钟自动退出,launchd 连续 4 次快速重启后会判定为崩溃循环并卸载服务。:方案一(pmset)+ 方案三(launchd)组合使用,既防止系统休眠,又保证 OpenClaw 开机自启和崩溃自动恢复。:caffeinate 只在进程运行期间有效,终端关闭或进程结束后系统恢复正常睡眠策略。这条命令会自动创建 launchd plist 并启用服务,是最推荐的方式。替换为你的实际用户名路径,Node.js 路径也要改成你自己的。确保 plist 中有。

Maynor的博客 2199

YOLOv11改进 | 细节涨点篇 | DySample一种最新的轻量化动态上采样算子(效果完爆CARAFE)

本文给大家带来的最新改进机制是一种号称超轻量级且有效的动态上采样器——DySample。与传统的基于内核的动态上采样器相比,DySample采用了一种基于点采样的方法,相比于以前的基于内核的动态上采样器,DySample具有更少的参数、浮点运算次数、GPU内存和延迟。此外,DySample在包括语义分割、目标检测、实例分割、全景分割和单目深度估计在内的五个预测任务中,性能均优于其他上采样器(截至目前最有效的上采样算子),

Snu77的博客 4208

php 断点续传 类型,php支持断点续传、分块下载的类

本文是为大家分享php支持断点续传、分块下载的类,供大家参考,具体内容如下/*** User: djunny* Date: 2016-04-29* Time: 17:18* Mail: 199962760@qq.com* 支持断点下载的类*/class downloader {/*** download file to local path** @param $url* @param ...

weixin_42177768的博客 131

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

php实现的支持断点续传的文件下载类

本文实例讲述了php实现的支持断点续传的文件下载类及其用法,是非常实用的技巧。分享给大家供大家参考。具体方法如下: 通常来说,php支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现。

NiceGY 2203

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

php ftp 分块下载,关于php支持分块与断点续传文件下载功能代码

本文章要介绍了这篇文章是一篇关于php流下载,就是可以支持分块与断点续传文件下载,有需要的朋友可以看看。代码如下$dowmFile = dirname ( __FILE__ ) . ‘/Nokia – Always Here.mp3′; //要下载的文件,绝对或相对$dowmName = ‘Nokia – Always Here.mp3′;ob_start ();getlocalfile ( $d...

weixin_39717692的博客 155

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

php 支持断点续传的文件下载类

php 支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现。 HTTP断点续传原理 Http头 Range、Content-Range() HTTP头中一般断点下载时才用到Range和Content-Range实体头, Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300) Content-Range用于响应头

中国石油大学 INThe Du Jin Feng 431

php断点续传插件下载,php支持断点续传、分块下载的类

/*** User: djunny* Date: 2016-04-29* Time: 17:18* Mail: 199962760@qq.com* 支持断点下载的类*/class downloader {/*** download file to local path** @param $url* @param $save_file* @param int $speed* @para...

weixin_35748962的博客 200

PHP大文件上传插件,如何支持分块与断点续传?

要求:免费,开源,专业技术支持前端:vue2,vue3,vue-cli,html5,jquery,webuploader后端:php服务器:linux,centos,Windows,数据库:MySQL,达梦数据库,人大金仓平台:Windows,macOS,Linux,Ubuntu,RedHat,中标麒麟,银河麒麟,统信UOS,信创国产化CPU:x86(Intel,AMD,兆芯,海光),arm(鲲鹏,飞腾),龙芯(mips),龙芯(LoongArch)

2501_90699640的博客 854

PHP大文件上传插件推荐,支持分块、秒传与断点续传?

要求:免费,开源,专业技术支持前端:vue2,vue3,vue-cli,html5,jquery,webuploader后端:php服务器:linux,centos,Windows,数据库:MySQL,达梦数据库,人大金仓平台:Windows,macOS,Linux,Ubuntu,RedHat,中标麒麟,银河麒麟,统信UOS,信创国产化CPU:x86(Intel,AMD,兆芯,海光),arm(鲲鹏,飞腾),龙芯(mips),龙芯(LoongArch)

weixin_52050572的博客 842

php功能代码下载,php支持分块与断点续传文件下载功能代码

本文章要介绍了这篇文章是一篇关于php流下载,就是可以支持分块与断点续传文件下载,有需要的朋友可以看看。 代码如下 复制代码 $dowmFile = dirname ( __FILE__ ) . ‘/Nokia – Always Here.mp3′; //要下载的文件,绝对或相对 $dowmName = ‘Nokia – Alw本文章要介绍了这篇文章是一篇关于php流下载,就是可以支持分块与断点续...

weixin_32258195的博客 142

php文件断点续传,php实现的支持断点续传的文件下载类

本文实例讲述了php实现的支持断点续传的文件下载类及其用法,是非常实用的技巧。分享给大家供大家参考。具体方法如下:通常来说,php支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现。HTTP断点续传原理:Http头 Range、Content-Range()HTTP头中一般断点下载时才用到Range和Content-Range实体头,Range用户请求头中,指定第一个字节...

weixin_39789370的博客 154

php 分块输出,PHP支持断点续传,分块下载的类

/*** User: djunny* Date: 2016-04-29* Time: 17:18* Mail: [emailprotected]* 支持断点下载的类*/class downloader {/*** download file to local path** @param $url* @param $save_file* @param int $spee...

weixin_33515785的博客 180
上一篇: 代码笔记 | java实现牛顿插值法
下一篇: 代码笔记 | java 正则表达式高级篇(四种常用的处理方式:匹配 分割 替代 获取)
CodePudge
博客等级 码龄10年 8粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值