【Laravel】Azure Blob Storageを使ってみる

AWSが大人気ですが、Azureも世界で見れば大人気です。

機会があってAzureを使うことになったので、記事を投下していきます。

Azureの良いところは

○管理画面見やすい

○スタートアップ支援に力を入れてる
https://www.microsoft.com/ja-jp/biz/startups/newspicks-20190819.aspx

だと思います。

早速本題に行きます！


#ドキュメント

https://docs.microsoft.com/ja-jp/azure/storage/blobs/

AWSもそうですが、ドキュメント読むの大変です。

#サンプルURL

https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-php?tabs=linux

該当する場所を探すのが大変だと思うので先に貼っときます。

#パッケージのインストール

https://github.com/Azure/azure-storage-php

```composer.json
"require": {
"microsoft/azure-storage-blob": "*"
}
```

```ターミナル.
composer install
```

#.envに記載

Azureでストレージアカウントの作成→左のメニューからアクセスキー

<img width="1413" alt="スクリーンショット 2020-04-05 22.46.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447711/71a82962-7151-e022-ee20-e40b512959e6.png">


ストレージアカウント名と、キーを使います。

```env.
AZURE_BLOB_ACCOUNT_NAME=こぴぺしたストレージアカウント名をここに
AZURE_BLOB_ACCOUNT_KEY=こぴぺしたkeyをここに。
```


configディレクトリでazure.phpというファイルを作ります。

```azure.php
  'account_name' => env('AZURE_BLOB_ACCOUNT_NAME'),
  'account_key' => env('AZURE_BLOB_ACCOUNT_KEY'),
```

としておきます。

##保存

```TestController.php
//これ使いました。
use Illuminate\Http\Request;
use Auth;
use Illuminate\Support\Str;

//AzureBlobのパッケージ
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions;
use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions;
use MicrosoftAzure\Storage\Blob\Models\PublicAccessType;

class UploaderController extends Controller {

public function uploadImage(Request $request)
    {
        //.envのアクセスキーを呼び出す
        $connectionString = "DefaultEndpointsProtocol=https;AccountName=".config('azure.account_name').";AccountKey=".config('azure.account_key');
        //おまじない
        $blobClient = BlobRestProxy::createBlobService($connectionString);

        //inputでファイルが送られてきてます
        $image = $request->file('image');

        //もしイメージがあれば
        if (!empty($image)) {
            //送られてきた画像を読み込む
            $content = fopen($image, "r");
            //コンテナ名
            $containerName = 'test';
            //アップロード先はは「/」で階層を指定できる
            $upload_path = Auth::id().'/image/';
　　　　　　　//ファイル名
            $file_name = Str::random(10).'.jpg';
            //ここで保存（コンテナ名、ファイル名、ファイル）
            $blobClient->createBlockBlob($containerName,$upload_path.$file_name, $content); 
         }  else {
            //エラー
         }
    }
}
```

AWSと違うのは、「コンテナ」というのがあるところだと思います。
コンテナは公式のGUIで操作して作成することもできますが、コードでも作れます。

```php
   $blobClient->createContainer($containerName, $createContainerOptions);
    //オプション
    $createContainerOptions = new CreateContainerOptions();
    //コンテナ、BLOB両方ともパブリックを与えてる
    $createContainerOptions->setPublicAccess(PublicAccessType::CONTAINER_AND_BLOBS);
    // メタデータを与えられる
    $createContainerOptions->addMetaData("key1", "value1");
    $createContainerOptions->addMetaData("key2", "value2");
　　 //コンテナ名
    $containerName = 'test';
    //コンテナ作成
    $blobClient->createContainer($containerName, $createContainerOptions);
```

これでコンテナを作成できます。

注意点は
####「既に存在するコンテナ名で作成しようとするとエラー」になります

自分はコンテナはポータルサイト上で作成しておいて、そのコンテナ上にアップするような使い方をしています。


##消す
```TestController.php
$blobClient = BlobRestProxy::createBlobService($connectionString);
//コンテナとファイル名
$blobClient->deleteBlob($containerName, $upload_path.$file_name);
```

これだけで消せます。

##保存先を取得して消す

```TestContoller.php
$blobClient = BlobRestProxy::createBlobService($connectionString);
//リストで取得する
$listBlobsOptions = new ListBlobsOptions();
//オプションでファイルの階層を指定
$upload_path = Auth::id().'/image'
$listBlobsOptions->setPrefix($upload_path);
//resultに結果が全て入ってくる
$result = $blobClient->listBlobs($container, $listBlobsOptions);
foreach ($result->getBlobs() as $blob) {
   //urlの取得
   $url = $blob->getUrl();
   //例えばこのリスト全部消すなら
   //コンテナファイルの場所取得
   $delete_url = Str::after($url, $container.'/');
   //消す
   $blobClient->deleteBlob($container, $delete_url);
}
```


####コンテナを消すメソッドはあるがディレクトリを消す方法がわからなかった（涙）

ストリーミングの動画のファイルを全て消したいときにこのように書きました。

多分ディレクトリで消せないようになっているのではと推測しています（知ってる方いれば教えてください）


#まとめ

LaravelというよりはPHP。

S3より行数は多いけど、ビビる必要なし！

MicrosoftはGithubやVisual Studio Onlineなどとの連携で楽しいことしてくれそうな気がします！

ご静聴ありがとうございました！

#参考文献
https://www.microsoft.com/ja-jp/biz/startups/newspicks-20190819.aspx
https://docs.microsoft.com/ja-jp/azure/storage/blobs/
https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-php?tabs=linux