fei/filer-client

Flash 应用 Filer - 客户端组件

安装次数: 6,472

依赖: 1

建议者: 0

安全: 0

星标: 0

关注者: 26

分支: 0

开放问题: 3

类型:项目

v3.0.1 2018-12-13 00:34 UTC

README

GitHub license continuousphp Build Status GitHub issues

这是您用于消费 Filer 服务的客户端。

客户端可以使用两种类型的传输发送请求

  • BeanstalkProxyTransport 实现的异步传输
  • BasicTransport 实现的同步传输

BeanstalkProxyTransport 通过向 Beanstalkd 队列发送文件属性,将 API 消费委托给工作进程。

BasicTransport 使用 经典 HTTP 层发送文件。

如果设置了异步传输,它将作为默认传输。如果异步传输失败,同步传输将作为回退。

本文件中的所有示例都将使用 BeanstalkProxyTransportBasicTransport

安装

Filer 客户端需要 PHP 5.5 或更高版本。

将此要求添加到您的 composer.json"fei/filer-client": : "^1.0"

或者在终端中执行 composer.phar require fei/filer-client

如果您想使用 Filer 客户端的异步功能(我们知道您想),您需要一个运行良好的 Beanstalkd 实例以及一个 api-client-worker.php 实例,该实例将消费 Beanstalk 的管道并将消息有效负载转发到 Filer API。

Filer Client -> Beanstalkd -> api-client-worker.php -> Filer API server

Beanstalkd 配置

运行 Beanstalkd 非常简单。然而,您必须注意 z 选项,它设置最大作业(或消息)大小(以字节为单位)。因此,如果您想将 100 Mo 的文件传输到 Filer API,您应该考虑至少为 z 参数设置 160 Mo 的值。

beanstalkd -z 167772160

运行 api-client-worker.php

以下是如何运行 api-client-worker.php 的示例。

php /path/to/filer-client/vendor/bin/api-client-worker.php --host 127.0.0.1 --port 11300 --delay 3

您可以使用 Supervisor 控制进程。

实体和类

文件实体

除了传统的 ID 和 CreatedAt 字段外,文件实体还有 *六个 重要属性

  • $uuid(通用唯一标识符)是与文件对应的 唯一标识符。其格式基于 36 个字符,如 RFC4122 中定义,并在 后端 id 前缀,并用 : 分隔。例如:bck1:f6461366-a414-4b98-a76d-d7b190252e74
  • filename 是表示文件名的字符串。
  • revision 是表示文件当前版本的整数。
  • category 是表示文件将在其中存储的数据库的整数。
  • contentType 定义 File 对象的内容类型。
  • data 包含文件的内容。
  • file 是一个 SplFileObject 实例。(有关更多详细信息,请参阅 https://secure.php.net/manual/en/class.splfileobject.php
  • contexts 是一个 ArrayCollection 实例,其中每个元素都是一个 Context 实体

基本用法

为了使用 File 方法,您必须定义一个新的 Filer 实例并设置传输类型(异步和同步)

<?php

use Fei\Service\Filer\Client\Filer;
use Fei\ApiClient\Transport\BasicTransport;
use Fei\ApiClient\Transport\BeanstalkProxyTransport;
use Pheanstalk\Pheanstalk;

$filer = new Filer([
    Filer::OPTION_BASEURL => 'https://filer.api.com', // Put your filer API base URL here
    Filer::OPTION_HEADER_AUTHORIZATION => 'apiKey'
]); 
$filer->setTransport(new BasicTransport());

$proxy = new BeanstalkProxyTransport();
$proxy->setPheanstalk(new Pheanstalk('127.0.0.1'));

$filer->setAsyncTransport($proxy);

// Use the filer client...

Filer 客户端实例将首先尝试使用 Beanstalkd 转移消息,如果过程失败,则客户端将尝试直接将文件有效负载发送到正确的 API 端点。

Filer 类中有几个方法,以下表格列出了所有方法

$uuid(通用唯一标识符)是对应于文件的唯一标识。(参见文件实体部分)

客户端选项

只有一个选项可用,可以传递给构造函数或Filer::setOptions(array $options)方法

注意:以下所有示例均可在examples目录中找到。

搜索文件

您可以使用Filer::search($builder)直接从客户端搜索文件

  • $builder必须是一个SearchBuilder实例

您可以使用SearchBuilder创建搜索,使搜索更容易使用。

<?php

use Fei\Service\Filer\Client\Filer;
use Fei\Service\Filer\Client\Builder\SearchBuilder;

// Creating a Filer client instance...
$filer = new Filer([
    Filer::OPTION_BASEURL => 'http://127.0.0.1:8080',
    Filer::OPTION_HEADER_AUTHORIZATION => 'apiKey'
]);

$builder = new SearchBuilder();
$builder->category()->equal(1);
$builder->context()->key('test 1')->equal('test 1');
$builder->context()->key('test 2')->equal('test 2');
$builder->filename()->beginsWith('avatar');

$files = $filer->search($builder);

如您所见,有多个方法可用,例如filename,还有多个运算符方法,例如

  • like:使用LIKE运算符
  • equal:使用=运算符
  • beginsWith:使用LIKE运算符,并且字符串必须以指定的值开头
  • endsWith:使用LIKE运算符,并且字符串必须以指定的值结尾

注意,您可以通过添加多个分类过滤器在多个分类上进行搜索

$builder->category()->equal(1);
$builder->category()->equal(2);
$builder->category()->equal(3);

注意,您可以根据上下文进行筛选。默认情况下,如果您有多个上下文筛选器,将执行“AND”条件。您可以选择执行“OR”条件,通过以下筛选器

    $searchBuilder->contextCondition('OR');

您还可以通过提供一个uuid来搜索文件。如果您这样做,您不需要按分类进行筛选,但您仍然可以这样做,如果您想的话。

以下是一个如何使用uuid搜索文件的示例

$builder->uuid()->equal('bck1:30d6a8ed-f9cf-4a6d-a76e-04ec941d1f45');

上传新文件

您可以使用Filer::upload($file, $flags)上传文件实例

  • $file必须是一个File实例
  • $flags可以是null或一个Filer常量
    • Filer::ASYNC_UPLOAD:准备上传,而不等待API响应
    • Filer::NEW_REVISION:为特定的uuid(显然必须在$file中声明)创建新修订版

该函数将返回null或一个描述新文件路径的string

示例

<?php

use Fei\Service\Filer\Entity\File;
use Fei\Service\Filer\Client\Filer;

// Creating a Filer client instance...

$file = new File();
$file->setCategory(File::CATEGORY_IMG)
    ->setContexts(['test 1' => 'test 1', 'test 2' => 'test 2'])
    ->setFile(new SplFileObject(__DIR__ . '/../file/path.pdf');

$uuid = $filer->upload($file, Filer::ASYNC_UPLOAD);

// Add a new revision:

$uuid = $filer->upload(
    (new File())
        ->setCategory(File::CATEGORY_IMG)
        ->setUuid($uuid)
        ->setFile(new SplFileObject(__DIR__ . '/../file/path2.pdf')),
    Filer::NEW_REVISION
);

创建File实例的另一种方法是使用静态方法Filer::embed($path),它允许您使用本地文件路径创建文件实例

<?php

use Fei\Service\Filer\Client\Filer;

// Creating a Filer client instance...

$file = Filer::embed('/path/to/the/file.pdf');
$file = $filer->upload($file, Filer::ASYNC_UPLOAD);

检索文件

您可以使用Filer::retrieve($uuid)检索文件实例。唯一必要的参数是有效的文件uuid

此方法返回一个File实例或null(如果找不到文件)。

示例

<?php

// Creating a Filer client instance...

$file = $filer->retrieve('bck1:f6461366-a414-4b98-a76d-d7b190252e74');

删除文件

您可以使用Filer::delete($uuid)删除文件。唯一必要的参数是有效的文件uuid

示例

<?php

use Fei\Service\Filer\Entity\File;

// Creating a Filer client instance...

$filer->delete('bck1:f6461366-a414-4b98-a76d-d7b190252e74');

echo $filer->retrieve('bck1:f6461366-a414-4b98-a76d-d7b190252e74') instanceof File; // false

截断文件

Filer::truncate($uuid, $keep = 0)方法允许您删除文件的所有修订版,除了指定数量的修订版。

示例

<?php

use Fei\Service\Filer\Entity\File;
use Fei\Service\Filer\Client\Filer;

// Creating a Filer client instance...

$uuid = $filer->upload(
    (new File())
        ->setCategory(File::CATEGORY_IMG)
        ->setContexts(['test 1' => 'test 1', 'test 2' => 'test 2'])
        ->setFile(new SplFileObject(__DIR__ . '/../tests/_data/avatar.png')),
    Filer::ASYNC_UPLOAD
);

$uuid = $filer->upload(
    (new File())
        ->setCategory(File::CATEGORY_IMG)
        ->setUuid($uuid)
        ->setFile(new SplFileObject(__DIR__ . '/../tests/_data/capture.png')),
    Filer::ASYNC_UPLOAD|Filer::NEW_REVISION
);

// truncate the file and keep the last revisions
$filer->truncate($uuid, 1);

保存

Filer::save($uuid, $path, $as = null)方法是一种检索和保存远程文件本地副本的方法。

示例

<?php

use Fei\Service\Filer\Entity\File;

// Creating a Filer client instance...

$uuid = $filer->upload(
    (new File())
        ->setCategory(File::CATEGORY_IMG)
        ->setContexts(['test 1' => 'test 1', 'test 2' => 'test 2'])
        ->setFile(new SplFileObject(__DIR__ . '/../tests/_data/file.png'))
);

// save the file at this location on the local server
$filer->save($uuid, __DIR__ . '/../tests/_data/save/file_saved.png');

提供文件

使用方法Filer::serve($uuid, $flag = Filer::FORCE_DOWNLOAD),您可以将文件提供给用户代理并强制下载。

如果您不想下载文件并显示它,您可以按如下方式调用该方法:Filer::serve($uuid, Filer::FORCE_INLINE)

示例

<?php

use Fei\Service\Filer\Entity\File;

// Creating a Filer client instance...

$uuid = $filer->upload(
    (new File())
        ->setCategory(File::CATEGORY_IMG)
        ->setContexts(['test 1' => 'test 1', 'test 2' => 'test 2'])
        ->setFile(new SplFileObject(__DIR__ . '/../tests/_data/avatar.png'))
);

// Serve the file
$filer->serve($uuid);

通过分块上传大文件

从本客户端的1.1.0版本开始,您可以通过分块上传大文件。为了做到这一点,您必须使用Filer::uploadByChunk(File $file, callable $fulfilled = null, callable $rejected = null)方法。

示例

<?php

use Fei\Service\Filer\Entity\File;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Exception\RequestException;

try {
    // Creating a Filer client instance...
    
    $file = (new File())
        ->setCategory(File::CATEGORY_IMG)
        ->setContexts(['test 1' => 'test 1', 'test 2' => 'test 2'])
        ->setFilename('avatar.png')
        ->setFile(new SplFileObject(__DIR__ . '/../tests/_data/avatar.png'));

    $uuid = $filer->uploadByChunks(
        $file,
        null,
        function (Response $response, $index) {
            var_dump($index);
        }
    );

    // Add a new revision:

    $file = (new File())
        ->setCategory(File::CATEGORY_IMG)
        ->setContexts(['test 1' => 'test 1', 'test 2' => 'test 2', 'test 3' => 'test 3'])
        ->setFile(new SplFileObject(__DIR__ . '/../tests/_data/capture.png'))
        ->setUuid($uuid);

    $uuid = $filer->uploadByChunks(
        $file,
        \Fei\Service\Filer\Client\Filer::NEW_REVISION
    );

    // Update file for the latest revision
    
    $file = $filer->retrieve($uuid);
    $file->setContexts(['test 1' => 'New value']);

    $uuid = $filer->uploadByChunks(
        $file
    );
} catch (\Fei\Service\Filer\Client\Exception\FilerException $e) {
    echo $e->getMessage() . PHP_EOL;
} catch (\Exception $e) {
    echo $e->getMessage() . PHP_EOL;
}

$fulfilled回调将在每次成功传输块时执行。否则,$rejected回调将在每次块未成功传输时执行。

默认情况下,$rejected等于

function (RequestException $reason, $index) {
    throw FilerException::createWithRequestException($reason);
};

您可以通过选项OPTION_CHUNK_SIZEOPTION_CHUNK_UPLOAD_CONCURRENCY分别设置块大小和上传并发性。