定制 bfitech/zapchupload 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

bfitech/zapchupload

Composer 安装命令:

composer require bfitech/zapchupload

包简介

Server-side chunk upload.

README 文档

README

Server-side chunk uploader.

Latest Stable Version Latest Unstable Version Build Status Codecov GitHub license

This package provides PHP the ability to upload possibly ultra-big file in smaller chunks.

But why? What's wrong with standard HTTP form?

Some primary considerations:

pros:

  • No worry about RAM and other server intrinsic limitations.
  • If configured properly, no worry about upload_max_filesize and consequently max_execution_time directives. Filesize limit may still come from disk space or filesystem limitation.
  • Each chunk can be processed for, e.g. fingerprinting, so there's a way to fail early when file is corrupt in transit.
  • Easily configurable to work with your other web app routers.
  • Works on plain PHP. No web server tweaks necessary.

cons:

  • Network overhead explodes because multiple requests must be made to upload even a single file.
  • A special client must be crafted. Standard HTTP upload form will not work.

Installation

$ composer require bfitech/zapchupload
$ vim index.php

Tutorial

server-side

Quick index.php setup:

<?php

require_once __DIR__ . '/vendor/autoload.php';

use BFITech\ZapCore\Router;
use BFITech\ZapCore\Logger;
use BFITech\ZapChupload\ChunkUpload;

// create a logging service
$log = new Logger;

// create a router
$core = (new Router)->config('logger', $log);

// instantiate the chunk uploader class
$chup = new ChunkUpload(
    $core, '/tmp/tempdir', '/tmp/destdir',
    null, null, null, $log);

// uploader route
$core->route('/upload', [$chup, 'upload'], 'POST');

// downloader route for testing
$core->route('/', function($args) use($core) {
	$file = $args['get']['file'] ?? null;
	if ($file)
		$core->static_file('/tmp/destdir/' . $file);
	$core::halt('HELLO WORLD');
});

// that's it

You can run it on your local machine with builtin server as follows:

$ php -S 0.0.0.0:9999 &

client-side

Here's a simple client written in Python:

#!/usr/bin/env python3

# chupload-client.py

import os
import sys
import stat
import hashlib

# use pip3 to install this
import requests

# from your toy service
UL_URL = 'http://localhost:9999/upload'

# from your toy service
DL_URL = 'http://localhost:9999/?file='

# ChunkUpload default prefix
PREFIX = "__chupload_"

# ChunkUpload default chunk size
CHUNK_SIZE = 1024 * 100


def upload(path):
    try:
        fst = os.stat(path)
    except FileNotFoundError:
        sys.exit(2)
    if stat.S_ISDIR(fst.st_mode):
        sys.exit(3)
    size = fst.st_size
    base = os.path.basename(path)

    # chupload must have this as _POST data
    data = {
        PREFIX + 'index': 0,
        PREFIX + 'size': size,
        PREFIX + 'name': base,
    }

    # calculate max number of chunks for test
    chunk_max = divmod(size, CHUNK_SIZE)[0]

    index = 0
    with open(path, 'rb') as fhn:

        while True:

            # chupload must have this as uploaded chunk, where the
            # filename doesn't matter
            files = {
                PREFIX + 'blob': ('noop', fhn.read(CHUNK_SIZE)),
            }

            # make request on each chunk
            resp = requests.post(UL_URL, files=files, data=data).json()
            assert(resp['errno'] == 0)
            rdata = resp['data']

            # upload complete
            if rdata['done'] == True:
                assert(index == chunk_max == rdata['index'])
                print("UPLOAD: OK")
                return "%s%s" % (DL_URL, rdata['path'])

            # increment index for next chunk
            index += 1
            data[PREFIX + 'index'] = index

    raise Exception("Oops! Something went wrong.")


def compare(path, url):
    resp = requests.get(url)
    assert(resp.status_code == 200)
    print("DOWNLOAD: OK")

    # compare download with local file
    rhash = hashlib.sha256(resp.content)
    lhash = hashlib.sha256(open(path, 'rb').read())
    assert(rhash.hexdigest() == lhash.hexdigest())
    print("COMPARE: OK")


if __name__ == '__main__':
    try:
        path = sys.argv[1]
    except IndexError:
        sys.exit(1)
    compare(path, upload(path))

that you can run from the CLI as follows:

$ python3 chupload-client.py ~/some-file.dat || echo FAIL

To see how it works on the browser, run the demo:

$ php -S 0.0.0.0:9998 -t ./demo &
$ x-www-browser localhost:9998

Documentation

Complete documentation is available with:

$ doxygen
$ x-www-browser docs/html/index.html

bfitech/zapchupload 适用场景与选型建议

bfitech/zapchupload 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 148 次下载、GitHub Stars 达 1, 最近一次更新时间为 2017 年 03 月 29 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 bfitech/zapchupload 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 bfitech/zapchupload 我们能提供哪些服务?
定制开发 / 二次开发

基于 bfitech/zapchupload 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 148
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2017-03-29