Laravel-Admin Storage使用 ucloud
作用:laravel-admin 自带的images 和 multipleImage控件可直接上传到ucloud
Storage 也可直接使用 示例:
\Storage::disk('ucloud')->put('images/file.jpg', file_get_contents("public/images/loading.gif"));
//遇到一个坑 影响不大 mark一下
如果先拿这个文件名去浏览器访问了一下(提示文件不存在) 再去上传那么会上传不上去,很奇怪!!
三个新文件 (先放 App\Providers\UcloudLaravelAdmin 目录下吧)
1、UcloudUfileAdapter.php
<?php
namespace App\Providers\UcloudLaravelAdmin;
use League\Flysystem\Adapter\AbstractAdapter;
use League\Flysystem\Adapter\Polyfill\NotSupportingVisibilityTrait;
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
use League\Flysystem\Adapter\Polyfill\StreamedTrait;
use League\Flysystem\Config;
use LogicException;
class UcloudUfileAdapter extends AbstractAdapter {
use NotSupportingVisibilityTrait, StreamedTrait, StreamedCopyTrait;
protected $ufileSdk;
public function __construct(
$bucket,
$public_key,
$secret_key,
$suffix = '.ufile.ucloud.cn',
$pathPrefix = '',
$https = false
) {
$this->ufileSdk = new UfileSdk($bucket, $public_key, $secret_key, $suffix, $https);
$this->setPathPrefix($pathPrefix);
}
public function read($path) {
$path = $this->applyPathPrefix($path);
$data = [];
$data['contents'] = $this->ufileSdk->get($path);
return $data;
}
/**
* Write a new file.
*
* @param string $path
* @param string $contents
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function write($path, $contents, Config $config) {
$path = $this->applyPathPrefix($path);
$params = $config->get('params', null);
$mime = $config->get('mime', 'application/octet-stream');
$checkCrc = $config->get('checkCrc', false);
list($ret, $code) = $this->ufileSdk->put($path, $contents, ['Content-Type' => $mime]);
return $ret;
}
/**
* Write a new file using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function writeStream($path, $resource, Config $config) {
$path = $this->applyPathPrefix($path);
$params = $config->get('params', null);
$mime = $config->get('mime', 'application/octet-stream');
$checkCrc = $config->get('checkCrc', false);
list($ret, $code) = $this->ufileSdk->put($path, $resource, ['Content-Type' => $mime]);
return $ret;
}
/**
* Update a file.
*
* @param string $path
* @param string $contents
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function update($path, $contents, Config $config) {
return $this->write($path, $contents, $config);
}
/**
* Update a file using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function updateStream($path, $resource, Config $config) {
return $this->writeStream($path, $resource, $config);
}
/**
* Rename a file.
*
* @param string $path
* @param string $newpath
*
* @return bool
*/
public function rename($path, $newpath) {
throw new \Exception('not supprot');
}
/**
* Delete a file.
*
* @param string $path
*
* @return bool
*/
public function delete($path) {
$path = $this->applyPathPrefix($path);
return $this->ufileSdk->delete($path);
}
/**
* Delete a directory.
*
* @param string $dirname
*
* @return bool
*/
public function deleteDir($dirname) {
throw new LogicException(get_class($this) . ' does not support ' . __FUNCTION__);
}
/**
* Create a directory.
*
* @param string $dirname directory name
* @param Config $config
*
* @return array|false
*/
public function createDir($dirname, Config $config) {
return ['path' => $dirname];
}
/**
* Check whether a file exists.
*
* @param string $path
*
* @return array|bool|null
*/
public function has($path) {
$path = $this->applyPathPrefix($path);
return $this->ufileSdk->exists($path);
}
/**
* List contents of a directory.
*
* @param string $directory
* @param bool $recursive
*
* @return array
*/
public function listContents($directory = '', $recursive = false) {
throw new LogicException(get_class($this) . ' does not support ' . __FUNCTION__);
}
/**
* Get all the meta data of a file or directory.
*
* @param string $path
*
* @return array|false
*/
public function getMetadata($path) {
$path = $this->applyPathPrefix($path);
return $this->ufileSdk->meta($path);
}
/**
* Get all the meta data of a file or directory.
*
* @param string $path
*
* @return array|false
*/
public function getSize($path) {
$path = $this->applyPathPrefix($path);
$size = $this->ufileSdk->size($path);
return array('size' => $size);
}
/**
* Get the mimetype of a file.
*
* @param string $path
*
* @return array|false
*/
public function getMimetype($path) {
$path = $this->applyPathPrefix($path);
$mimeType = $this->ufileSdk->mime($path);
return array('mimetype' => $mimeType);
}
/**
* Get the timestamp of a file.
*
* @param string $path
*
* @return array|false
*/
public function getTimestamp($path) {
$meta = $this->getMetadata($path);
$timestamp = strtotime($meta['Last-Modified']);
return array('timestamp' => $timestamp);
}
public function getUrl($path){
if(strpos($path, 'http')!==false){
return $path;
}
return config("filesystems.disks.ucloud.url").$path;
}
}
2、UfileSdk.php
<?php
namespace App\Providers\UcloudLaravelAdmin;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
class UfileSdkException extends \Exception
{
}
class UfileSdk
{
protected $httpClient;
protected $bucket;
protected $pub_key;
protected $sec_key;
protected $host;
protected static function auth($bucket, $pub_key, $sec_key)
{
return function (callable $handler) use ($bucket, $pub_key, $sec_key) {
return function (
$request,
array $options
) use ($handler, $bucket, $pub_key, $sec_key) {
$path = $request->getUri()->getPath();
$method = strtoupper($request->getMethod());
$paramToSign['method'] = $method;
foreach (['Content-MD5', 'Content-Type', 'Date'] as $headNeedSign) {
$v = $request->getHeader($headNeedSign);
$paramToSign[$headNeedSign] = empty($v) ? "" : $v[0];
}
$authString = implode("\n", $paramToSign) . "\n";
//合并UCloud特殊头
$headers = $request->getHeaders();
//标准化CanonicalizedUCloudHeaders
foreach ($headers as $k => $v) {
$k = strtolower($k);
if (strncasecmp($k, "x-ucloud-", strlen('x-ucloud-')) !== 0) {
continue;
}
if (is_array($v)) {
$v = implode(',', $v);
}
$authString .= $k . ":" . trim($v, " ") . "\n";
}
//合并资源路径
$authString .= "/" . $bucket . $path;
$signature = base64_encode(hash_hmac('sha1', $authString, $sec_key, true));
$authToken = "UCloud " . $pub_key . ":" . $signature;
$request = $request->withHeader('Authorization', $authToken);
if (in_array($method, ['POST', 'PUT'])) {
$request = $request->withHeader('Content-Length', $request->getBody()->getSize());
}
return $handler($request, $options);
};
};
}
public function __construct($bucket, $pub_key, $sec_key, $suffix = '.ufile.ucloud.cn', $https = false, $debug = false)
{
$this->bucket = $bucket;
$this->pub_key = $pub_key;
$this->sec_key = $sec_key;
$this->host = ($https ? 'https://' : 'http://') . $bucket . $suffix;
$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(static::auth($bucket, $pub_key, $sec_key));
$this->httpClient = new Client(['base_uri' => $this->host, 'handler' => $stack, 'debug' => $debug]);
}
public function put($key_name, $contents, $headers = [])
{
$headers = [];
$resp = $this->httpClient->request('PUT', $key_name, [
'headers' => $headers,
'body' => $contents]);
if($resp->getStatusCode() == 200){
return [$key_name, $resp->getStatusCode()];
}
return [$resp->getBody()->getContents(), $resp->getStatusCode()];
}
public function putFile($key_name, $filePath, $headers = [])
{
$resp = $this->httpClient->request('PUT', $key_name, [
'headers' => $headers,
'body' => fopen($filePath, 'r')]);
if($resp->getStatusCode() == 200){
return [$key_name, $resp->getStatusCode()];
}
return [$resp->getBody()->getContents(), $resp->getStatusCode()];
}
public function get($key_name)
{
$resp = $this->httpClient->get($key_name);
if ($resp->getStatusCode() != 200) {
throw new UfileSdkException("get $key_name error :" . $resp->getStatusCode());
}
return $resp->getBody()->getContents();
}
public function exists($key_name)
{
$resp = $this->httpClient->head($key_name);
return $resp->getStatusCode() == 200;
}
public function size($key_name)
{
$resp = $this->httpClient->head($key_name);
if ($resp->getStatusCode() != 200) {
throw new UfileSdkException("size $key_name error :" . $resp->getStatusCode());
}
return (int)$resp->getHeader('Content-Length')[0];
}
public function mime($key_name)
{
$resp = $this->httpClient->head($key_name);
if ($resp->getStatusCode() != 200) {
throw new UfileSdkException("size $key_name error :" . $resp->getStatusCode());
}
return $resp->getHeader('Content-Type')[0];
}
public function delete($key_name)
{
$resp = $this->httpClient->delete($key_name);
if (!in_array($resp->getStatusCode(), [200, 204])) {
throw new UfileSdkException("delete $key_name error :" . $resp->getStatusCode());
}
return true;
}
public function meta($key_name)
{
$resp = $this->httpClient->head($key_name);
if ($resp->getStatusCode() != 200) {
throw new UfileSdkException("size $key_name error :" . $resp->getStatusCode());
}
$meta = [];
foreach ($resp->getHeaders() as $k => $v) {
$meta[$k] = $v[0];
}
return $meta;
}
}
3、UfileServiceProvider.php
<?php
namespace App\Providers\UcloudLaravelAdmin;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
class UfileServiceProvider extends ServiceProvider {
public function boot() {
/*
* extend方法的第一个参数是驱动名称,
* 第二个参数是获取$app和$config变量的闭包。
* 该解析器闭包必须返回一个League\Flysystem\Filesystem实例。
* $config变量即为 配置文件config/filesystems.php中为特定磁盘定义的选项。
* 创建好注册扩展的服务提供者后,就可以使用配置文件config/filesystem.php中的ucloud驱动了
*/
\Storage::extend(
'ucloud',
function ($app, $config) {
$ufileAdapter = new UcloudUfileAdapter(
$config['bucket'],
$config['public_key'],
$config['secret_key'],
$config['suffix'],
$config['prefix']
);
$fs = new Filesystem($ufileAdapter);
return $fs;
}
);
}
public function register() {
}
}
修改2个文件
1、config/app.php 中providers数组里 添加
App\Providers\UcloudLaravelAdmin\UfileServiceProvider::class
2、config/filesystems.php disks数组里 添加
'ucloud' => [
'driver' => 'ucloud',
'bucket' => '',
'public_key' => '',
'secret_key' => '',
'suffix' => '.ufile.ucloud.cn',//图片上传地址
'prefix' => '',
'url' => env('OSS_HOST'),//图片访问CDN地址
],
3、config/admin.php upload 数组里 更改
'disk' => 'ucloud',
需要安装的组件
guzzlehttp/guzzle league/flysystem

浙公网安备 33010602011771号