「扩展包」优雅的 Oss Flysystem 扩展

file

先上链接

如果觉得帮助了你,节省了你的时间记得 Star 哟.

序言

之前用过很多 oss 扩展包但是暂时没有一个用的顺心的,一些扩展包配置太复杂,还有的扩展包不能集成 Laravel 文件驱动,对于喜欢优雅编码的同学可能不能忍受

最近闲下来看了一些优秀的开源项目,从中学到不少东西。看了超哥的 overtrue/flysystem-qiniu 后决定自己也写一个 oss 扩展包.

要求

  • PHP >= 7.0

第一个扩展包:直接使用不依赖框架

$ composer require "iidestiny/flysystem-oss" -vvv

配置

use League\Flysystem\Filesystem;
use Iidestiny\Flysystem\Oss\OssAdapter;
use Iidestiny\Flysystem\Oss\Plugins\FileUrl;

$accessKeyId = 'xxxxxx';
$accessKeySecret = 'xxxxxx';
$endpoint= 'oss.iidestiny.com';
$bucket = 'bucket';
$isCName = true; // 如果 isCname 为 false,endpoint 应配置 oss 提供的域名如:`oss-cn-beijing.aliyuncs.com`,cname 或 cdn 请自行到阿里 oss 后台配置并绑定 bucket

$adapter = new OssAdapter($accessKeyId, $accessKeySecret, $endpoint, $bucket, $isCName);

$flysystem = new Filesystem($adapter);

API

bool $flysystem->write('file.md', 'contents');

bool $flysystem->write('file.md', 'http://httpbin.org/robots.txt', ['options' => ['xxxxx' => 'application/redirect302']]);

bool $flysystem->writeStream('file.md', fopen('path/to/your/local/file.jpg', 'r'));

bool $flysystem->update('file.md', 'new contents');

bool $flysystem->updateStream('file.md', fopen('path/to/your/local/file.jpg', 'r'));

bool $flysystem->rename('foo.md', 'bar.md');

bool $flysystem->copy('foo.md', 'foo2.md');

bool $flysystem->delete('file.md');

bool $flysystem->has('file.md');

string|false $flysystem->read('file.md');

array $flysystem->listContents();

array $flysystem->getMetadata('file.md');

int $flysystem->getSize('file.md');

string $flysystem->getAdapter()->getUrl('file.md'); 

string $flysystem->getMimetype('file.md');

int $flysystem->getTimestamp('file.md');

Plugins

use Iidestiny\Flysystem\Oss\Plugins\FileUrl

$flysystem->addPlugin(new FileUrl());

string $flysystem->getUrl('file.md');

// 获取文件 url 地址
$flysystem->addPlugin(new SignUrl());

// 使用签名 url 进行临时授权访问
string $flysystem->signUrl('file.md', $timeout);

前端 web 直传配置

oss 直传有三种方式,当前扩展包使用的是最完整的 服务端签名直传并设置上传回调 方式,扩展包只生成前端页面上传所需的签名参数,前端上传实现可参考 官方文档中的实例 或自行搜索

use Iidestiny\Flysystem\Oss\Plugins\SignatureConfig

$flysystem->addPlugin(new SignatureConfig());

object $flysystem->signatureConfig($prefix, $callBackUrl, $expire);

第二个扩展包:专门为 Laravel 适配

该扩展包内部自动依赖了 iidestiny/flysystem-oss 所以两个包不需要重复安装,Laravel 用户直接使用下面这条语句安装就可以.

$ composer require "iidestiny/laravel-filesystem-oss" -vvv

配置

config/filesystems.php 添加 oss 配置

 <?php

 return [
    'disks' => [
         //...
         'oss' => [
             'driver' => 'oss',
             'access_key' => env('OSS_ACCESS_KEY'),
             'secret_key' => env('OSS_SECRET_KEY'),
             'endpoint'   => env('OSS_ENDPOINT'),
             'bucket'     => env('OSS_BUCKET'),
             'isCName'    => env('OSS_IS_CNAME', false), // 如果 isCname 为 false,endpoint 应配置 oss 提供的域名如:`oss-cn-beijing.aliyuncs.com`,否则为自定义域名,,cname 或 cdn 请自行到阿里 oss 后台配置并绑定 bucket
         ],
         //...
     ]
 ];

使用

<?php

$disk = Storage::disk('oss');

// create a file
$disk->put('avatars/filename.jpg', $fileContents);

// check if a file exists
$exists = $disk->has('file.jpg');

// get timestamp
$time = $disk->lastModified('file1.jpg');
$time = $disk->getTimestamp('file1.jpg');

// copy a file
$disk->copy('old/file1.jpg', 'new/file1.jpg');

// move a file
$disk->move('old/file1.jpg', 'new/file1.jpg');

// 获取文件内容
$contents = $disk->read('folder/my_file.txt');

// 获取文件 url
$url = $disk->getUrl('folder/my_file.txt');

// 使用签名 url 进行临时授权访问
$url = $disk->signUrl('file.md', $timeout);

// web 直传所需签名参数
$config = $disk->signatureConfig($prefix, $callBackUrl, $expire);

更多方法查看 Laravel 文档 laravel-filesystem-doc

扩展包开发参考

最新更新

请到扩展包查看 Readme

PS

感谢关注「GitHub 热门」公众号,带你了解技术圈内热门新鲜事!

file

本作品采用《CC 协议》,转载必须注明作者和本文链接
感谢关注「GitHub 热门」公众号
附言 1  ·  4年前

扩展包更新

  • 支持 visibility 访问设置 感谢 @wesen PR
  • 支持「前端 web 直传签名配置生成」
本帖由系统于 5年前 自动加精
Destiny
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 58

谢谢分享。关注了

很多oss的包 基本上都不维护了,可惜了。

5年前 评论
Destiny

@keer :relaxed::relaxed:

5年前 评论

感谢开发者,现在的或多或少有这样好样的问题,试试。

5年前 评论
Destiny

@晨雨零稀 :kissing_closed_eyes:

5年前 评论
clyde-cn

哈哈哈,之前也想搞一个 但是懒癌发作..... so 既然你写好了我就直接用了

5年前 评论
Destiny

@孙坤峰 :grin:

5年前 评论

可惜了我不用 阿里云...

5年前 评论
Destiny

@crazy :sweat: 我司是阿里全套。。。。

5年前 评论
Jennie

问一下 Lumen 也支持吗?

5年前 评论
Destiny

@Everan 应该也是支持的。如果使用不了 laravel 适配包,可以使用第一个包,不限制框架

5年前 评论
Destiny

新增文件权限访问功能

使用签名 URL 进行临时授权

// file access period
$url = $disk->signUrl('file.md', $timeout);
5年前 评论

你好 这个 SDK 支持私有读的 增加签名吗?

5年前 评论
Destiny

@wujunze 试试呢,目前加了一个对 url 的签名

5年前 评论

正想自己写一个,直接使用您的了,感谢

5年前 评论
bestony

好像没有针对 Private Bucket 的处理?

5年前 评论
running8

图片处理功能怎么使用?可以加水印么?

5年前 评论

谢谢大神,好人一生平安

4年前 评论

这个包应该是先上传文件到应用服务器,然后再上传到OSS服务器吧。有没有类似服务端签名直传并设置上传回调的功能?

4年前 评论
Destiny

@hustnzj 直传你需要看一下 oss 的文档嗯。这个是后端上传

4年前 评论
Toiu

测试了一下~ 非常棒. 感谢作者的贡献. 是否有考虑加一下前端直传的配置生成接口呢

4年前 评论
Destiny

@Toiu 可以,后续可以加上。

4年前 评论
Storage->put('avatars/filename.jpg', $fileContents,'private');

大佬,可否支持设置文件的私有属性?现在Storageput方法,设置private无效

4年前 评论

大佬,可以更新下OssAdapter.php添加一个setVisibility方法,便于设置某个文件的权限吗?已在git提了issue

<?php
namespace Iidestiny\Flysystem\Oss

……
use League\Flysystem\AdapterInterface;
……
class OssAdapter extends AbstractAdapter
{
   ……
  /**
     * {@inheritdoc}
     */
    public function setVisibility($path, $visibility)
    {
        $object = $this->applyPathPrefix($path);
        $acl = ( $visibility === AdapterInterface::VISIBILITY_PUBLIC ) ? OssClient::OSS_ACL_TYPE_PUBLIC_READ : OssClient::OSS_ACL_TYPE_PRIVATE;

        $this->client->putObjectAcl($this->bucket, $object, $acl);

        return compact('visibility');
    }
   ……
}
4年前 评论
Destiny

已合并 PR

4年前 评论
Destiny

@Toiu web 直传配置生成已支持,请更新对应扩展包

图片

4年前 评论
Destiny
4年前 评论

@Destiny 老哥,不知道为啥我这里获取 URL 会有两个 http,正常应该是 http://myoss.oss-cn-xxx.aliyuncs.com/2O0564BGVD32I39VO90DE2401GB59BX225.png

代码部分:

public function getUrlAttribute() {
    return \Storage::disk('oss')->url($this->attributes['filename']);
}

结果:
file

4年前 评论
Destiny

@Jea 看看你配置文件呢?是不是配置里面带了 http

4年前 评论

@Destiny 对的:joy: ,就是配置里的endpoint带了http ,去掉就可以了,感谢

4年前 评论

@Destiny 大神,目前点击返回的url,下载文件名是oss上的文件名,能不能增加一个指定文件名的功能?谢谢

4年前 评论
Destiny

@hustnzj 啥?上传之前你这边可以处理一下文件名哟。

4年前 评论
Rick946 4年前

@Destiny 对,上传的时候是可以处理的,我后来想出来了,谢谢大神回复

4年前 评论
flycool 3年前

配置 endpoint 写了 自定义域名 , isCName => true, 就报错,提示 endpoint is empty

4年前 评论
Destiny

@gyp719 好的,谢谢反馈,等会我看看

4年前 评论

大佬:今天发现getUrl方法有问题
在文档中,'endpoint' => env('OSS_ENDPOINT'), // 使用 ssl 这里设置如: https://oss-cn-beijing.aliyuncs.com
但是如果这么设置了,那么调用normalizeHost()方法,生成的domain就会错误

 protected function normalizeHost()
    {
        if ($this->isCName) {
            $domain = $this->endpoint;
        } else {
            $domain = $this->bucket.'.'.$this->endpoint;
            //如果是ssl,那么此处生成的donmin类似:bucket.https://oss-cn-beijing.aliyuncs.com
        }
        if (0 !== stripos($domain, 'https://') && 0 !== stripos($domain, 'http://')) {
            $domain = "http://{$domain}";
        }

        return rtrim($domain, '/').'/';
    }
4年前 评论
Destiny

@wesen 可以提一个 PR 感谢,最近一直在外地忙其他事情。

4年前 评论
EthanYep

试试看

4年前 评论

感谢、感谢,阿里云那个官方文档进行临时认证真看滴头晕

4年前 评论

endPoint=cdn加速域名,isCName=true,就报403错误了

4年前 评论
FrancisX

listContents方法有时候无法感知从第三方客户端创建的目录。但是可以进行操作

4年前 评论

一大堆的bug 真的不打算修复了吗?

4年前 评论
Destiny

@大张

  1. 直传的配置服务端返回后,前端需要组装一下,才可以使用
  2. 另外你提的自定义参数已经在 2.0 加上了,欢迎继续使用

2.0 发行说明:https://github.com/iiDestiny/laravel-files...

4年前 评论
Destiny

@WilliamQian @gyp719

使用了 cdn 加速的话会存在问题,官方 SDK 也存在这个 bug,建议上传的时候用 oss 控制台提供的域名,显示的时候用 cdn

https://github.com/iiDestiny/laravel-files...

3年前 评论

大神,传上去的文件怎么删除呢,$disk->delete();不管用呀

3年前 评论
Destiny

@flycool

api 功能是正常的。你看看你是否切换到 oss

3年前 评论
FrancisX

偶尔会报SignatureDoesNotMatch: The request signature we calculated does not match the signature provided. check you key and signing method. RequestId: xxxxxxxxxxxxxxxxxxxxx.
但并不是每次都能复现.

file 所有的操作都是基于上面图片里面返回的对象.

3年前 评论

菜鸟来感谢一些,谢谢

3年前 评论

临时授权signUrl()的原理是什么呢,是用的阿里sts吗

2年前 评论

要支持下 Laravel 9

2年前 评论
zhanghaidi

Laravel 9 是不是不能用了?

2年前 评论
Destiny

已更新支持 Laravel 9

1年前 评论
Destiny

CDN 上传存在问题查看:github.com/iiDestiny/laravel-files...

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!