最近实验了下MinIO,发现这个分布式存储还是很好用的,具体不做赘述。此处记录下使用PHP操作存储桶下的文件及文件夹。
我使用了yii2框架(其实并没有使用到yii中从函数),操作minio的前提是要先下载一个模块:aws-sdk-php,minio自己的sdk并不支持PHP(minio api 文档),但是它支持亚马逊s3的对象存储,使用亚马逊s3的标准也能操作minio。
首先,在yii2项目根目录下,使用composer安装下s3工具包。
composer require aws/aws-sdk-php
若不想使用composer,或者没有条件使用可以下载zip包(下载链接),可以参考亚马逊s3文档,文档地址为:安装AWS SDK for PHP版本 3 - AWS SDK for PHP
工具包安装完毕,就可以调用工具包了,我写了一个简单的对桶中文件及文件夹的代码示例,如下:
s3Client = new S3Client([ 'version' => 'latest', 'region' => 'cn-north-1', //China (Beijing) 'endpoint' => $this->endpoint, 'use_path_style_endpoint' => true, 'credentials' => [ 'key' => $this->key, 'secret' => $this->secret, ], ]); } public function bucketExist($bucket = null) { return $this->s3Client->doesBucketExist($bucket); } public function bucketExists($bucket = null) { $result = $this->s3Client->listBuckets(); $names = $result->search('Buckets[].Name'); if($bucket){ if(!in_array($bucket, $names)){ return false; } }else{ if(!in_array($this->bucket, $names)){ return false; } } return true; } public function objectExist($object) { return $this->s3Client->doesObjectExist($this->bucket, $object); } public function upLoadObject($objectPath, $objectName = null) { if(!$objectName){ $objectName = basename($objectPath); } $uploader = new MultipartUploader($this->s3Client, $objectPath, [ 'bucket' => $this->bucket, 'key' => $objectName, ]); $result=$uploader->upload(); if(isset($result["@metadata"]["statusCode"]) && $result["@metadata"]["statusCode"] == 200){ return [ 'bucket' => $this->bucket, 'name' => $objectName, 'path' => $this->bucket . '/' . $objectName ]; }else{ return false; } } public function upLoadObjectToFolder($objectPath, $folderPath, $objectName = null) { if(!$objectName){ $objectName = basename($objectPath); } $key = $folderPath . '/' . $objectName; $result = $this->s3Client->putObject([ 'Bucket' => $this->bucket, 'Key' => $key, 'Body' => file_get_contents($objectPath) //要上传的文件 ]); if(isset($result["@metadata"]["statusCode"]) && $result["@metadata"]["statusCode"] == 200){ return [ 'bucket' => $this->bucket, 'name' => $objectName, 'path' => $this->bucket . '/' . $key ]; }else{ return false; } } public function batchUpload($objectPathArr) { //路径数组 $pathArr = array(); $s3 = $this->s3Client; foreach ($objectPathArr as $object) { if(file_exists($object)){ //文件扩展名 $extend = substr(strrchr($object,'.'),1); //文件名 $fileName = date('Ymd') . '-' . uniqid() . '.' . $extend; $return = $s3->putObject([ 'Bucket' => $this->bucket, //存储桶名称 'Key' => $fileName, //文件名(包括后缀名) 'Body' => file_get_contents($object) //要上传的文件 ]); if (isset($return['@metadata']['statusCode']) && $return['@metadata']['statusCode'] == 200) { $pathArr[] = [ 'bucket' => $this->bucket, 'name' => $fileName, 'path' => $this->bucket . '/' . $fileName ]; } else { //此处可增加日志记录 continue; } } } return $pathArr; } public function copyObject($sourceObject, $objectName = null) { if(!$objectName){ $extend = substr(strrchr($sourceObject,'.'),1); $objectName = date('Ymd') . '-' . uniqid() . '.' .$extend; } //源对象需包含桶+key $source = '/' . $this->bucket . '/' . $sourceObject; $result = $this->s3Client->copyObject([ 'Bucket' => $this->bucket, //存储桶名称 'CopySource' => $source, 'Key' => $objectName, ]); if(isset($result["@metadata"]["statusCode"]) && $result["@metadata"]["statusCode"] == 200){ return [ 'bucket' => $this->bucket, 'name' => $objectName, 'path' => $this->bucket . '/' . $objectName ]; }else{ return false; } } public function getMetaData($object){ $retrive = $this->s3Client->getObject([ 'Bucket' => $this->bucket, 'Key' => $object, ]); if(!isset($retrive['@metadata'])){ return []; } return $retrive['@metadata']; } public function getUrl($object, $expires = null){ $cmd = $this->s3Client->getCommand('GetObject', [ 'Bucket' => $this->bucket, 'Key' => $object ]); if(!$expires){ $expires = '+1 days'; } $request=$this->s3Client->createPresignedRequest($cmd,$expires); $presignedUrl = (string)$request->getUri(); return $presignedUrl; //测试-图片 //return ""; } public function getAll($data){ $param = [ 'Bucket' => $this->bucket ]; if(isset($data['num'])){ $param['MaxKeys'] = $data['num']; } if(isset($data['prefix'])){ $param['Prefix'] = $data['prefix']; } $retrive = $this->s3Client->listObjects($param); if(isset($retrive['Contents'])){ return $retrive['Contents']; }else{ return []; } } public function deleteObject($object){ $result = $this->s3Client->deleteObject([ 'Bucket' => $this->bucket, 'Key' => $object, ]); if(isset($result['@metadata']['statusCode']) && $result['@metadata']['statusCode'] == 204){ return true; }else{ return false; } } public function batchDeleteObject($objectArr) { $keys = array(); foreach ($objectArr as $item) { $keys[] = array('Key' => $item); } $s3 = $this->s3Client; $result = $s3->deleteObjects([ 'Bucket' => $this->bucket, 'Delete' => ['Objects' => $keys] ]); if(isset($result["@metadata"]["statusCode"]) && $result["@metadata"]["statusCode"] == 200){ return true; }else{ return false; } } public function uploadFolder($folderPath, $folderName = null) { if(!$folderName) { $folderName = basename($folderPath); } $keyPrefix = $folderName . '/'; $options['params']['ACL'] = 'public-read'; $this->s3Client->uploadDirectory($folderPath, $this->bucket, $keyPrefix , $options); return true; } public function deleteFolder($folderPath) { $folderName = basename($folderPath); $keyPrefix = $folderName . '/'; $this->s3Client->deleteMatchingObjects($this->bucket, $keyPrefix); return true; }}
在本地使用docker安装一个minio的命令:
先docker pull minio的镜像。由于我本地是windows,所以目录映射就写为这样D:\data\minio\data:/data,本地9000端口已经被php占用,所以分配9001给minio使用。docker run --name minio -p 9001:9000 -p 9090:9090 -d --restart=always -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=admin123" -v D:\data\minio\data:/data -v D:\data\minio\config:/root/.minio minio/minio:[版本tag] server /data --console-address ':9090'启动后,访问http://127.0.0.1:9090/browser即可进入控制台
来源地址:https://blog.csdn.net/qq_32737755/article/details/129958304