Azure WebApp + PHP + BLOBストレージで、ファイルアップロード

FNCT創造工学演習、予備実験向けにハンズオンを作成しました。

# ストレージアカウント作成
<img width="806" alt="スクリーンショット 2018-04-24 0.05.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/69744/959fa253-5447-9a11-5bd2-00cf233f692d.png">
[Microsoft Azureポータル](https://portal.azure.com/)にログインして、**＋リソースの作成**→**Storage**→**ストレージ アカウント**を選択する

<img width="308" alt="スクリーンショット 2018-04-24 0.09.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/69744/c4d10eaf-f60a-2927-df33-00df2ffbae91.png">
適切な名前を入力し、アカウントの種類に**BLOBストレージ**、レプリケーションに**ローカル冗長ストレージ**を選択する。
またリソースグループは、適切なものを選択(または作成)しておく。

### コンテナ作成
![スクリーンショット 2018-04-24 1.05.25.png](https://qiita-image-store.s3.amazonaws.com/0/69744/9f8eae06-fd43-a545-dbfb-aee77742cda8.png)
ストレージアカウント→**概要**→**BLOB**をクリックする。

![スクリーンショット 2018-04-24 1.06.00.png](https://qiita-image-store.s3.amazonaws.com/0/69744/e8b45d60-63c1-1919-0f36-605e6f340a7c.png)
新しいコンテナーから、名前に`container1`を入力、パブリックアクセスレベルに**コンテナー**を選択し、**作成**ボタンをクリックする。

# WebApp作成
<img width="306" alt="スクリーンショット 2018-04-24 0.14.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/69744/91822c91-3b9e-eba8-535a-d4b7c703714b.png">
WebAppを作成する。
App Serviceプランで適切なプランを選択しておくことを忘れずに。

<img width="295" alt="スクリーンショット 2018-04-24 0.22.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/69744/fbabf848-ec71-e1dc-a4fa-3551cb897172.png">
WebAppメニューを下にスクロールして、**App Service Editor**→**移動**をクリックし、App Service Editor(ブラウザ内開発環境)を開いておく。

### composer.phar
[https://getcomposer.org/download/](https://getcomposer.org/download/)の**Latest Snapshot**リンクからcomposer.pherをダウンロードし、App Service Editorを使ってWebAppのルートフォルダにアップロードしておく(ドラッグ アンド ドロップでアップロードできる)。

### composer.json

```composer.json
{
   "require": {
     "microsoft/windowsazure": "^0.4"
   }
}
```
同ルートフォルダに、上記の内容でcomposer.jsonを作成する。

### Azureのライブラリをインストールする
<img width="742" alt="スクリーンショット 2018-04-24 0.37.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/69744/82064f79-22a5-0e47-4d62-b934b12a1dae.png">
上記2項目で用意したファイルを利用して、Azureのライブラリをインストールする。
App Service Editorのメニューから**Open Console**を選択し、`php composer.phar install`を実行する。しばらく時間がかかるので、少々お待ちを。。。

# ソース記述
Web Appルートフォルダに下記2ファイルを作成する。

```index.html
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>test</title>
</head>
<body>
    <form method="post" action="upload.php" enctype="multipart/form-data">
        ファイル:<input type="file" name="up_file"><br>
        <input type="submit" value="upload">
    </form>
</body>
</html>
```

```upload.php
<html>
	<body>
<?php
	require_once 'vendor/autoload.php';
	
	use WindowsAzure\Common\ServicesBuilder;
	use MicrosoftAzure\Storage\Common\ServiceException;	
	
	// 接続
	$connectionString = "******";
	$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);
	
	// アップロード
	$tempFileName = $_FILES["up_file"]["tmp_name"];
	$originalFileName = $_FILES["up_file"]["name"];
	
    if( is_uploaded_file( $tempFileName ) )
	{
		$content = fopen( $tempFileName, "r" );
	    $blobRestProxy->createBlockBlob( "container1", $originalFileName, $content );
		
		echo "uploaded<br />"; 
    }

    echo "OK<br />";	
?>
	</body>
</html>
```

コード中の`$connectionString = "******";`の部分には、ストレージアカウントのメニューから**アクセスキー**→**key1**→**接続文字列**をコピーする。
ただし末尾の`EndpointSuffix=*****`部分は実行時にエラーになるため、貼り付けたあと削除すること。`***==;`までを残す。
![スクリーンショット 2018-04-24 0.47.09.png](https://qiita-image-store.s3.amazonaws.com/0/69744/edf82f1c-ad0d-acc8-a2f4-bbde11b4c959.png)

# 動作確認
作成したWeb Appにブラウザからアクセスすると、下記Webページが表示される。
<img width="706" alt="スクリーンショット 2018-04-24 0.53.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/69744/6885e7e4-c769-5b29-3121-f1eb077aaf17.png">

適当なファイルを選択して**upload**ボタンをクリックすると、アップロードが完了する。
アップロード後のページはこちら。**uploaded**と**OK**が表示されることを確認。
![スクリーンショット 2018-04-24 10.09.13.png](https://qiita-image-store.s3.amazonaws.com/0/69744/030ce1bb-dd0d-52ab-90f1-ca9569652a89.png)

また[Azureポータル](https://portal.azure.com/)からストレージアカウントを表示すると、アップロードされたファイルが確認できる。
![スクリーンショット 2018-04-24 10.11.04.png](https://qiita-image-store.s3.amazonaws.com/0/69744/9dbe4a4c-f82a-7593-9b8f-67a41124471a.png)


# ストレージのファイル一覧を表示
```upload.php
	// リスト
	$blob_list = $blobRestProxy->listBlobs("container1");
	$blobs = $blob_list->getBlobs();

    foreach($blobs as $blob)
    {
        echo "<a href='".$blob->getUrl()."' target='_blank'>". $blob->getName()."</a><br />";
    }			
```
上記で作成した**upload.php**の`// アップロード`の一連の処理のあとに、上記コードを追加する。
アップロードされたファイル一覧が表示される。

# content-typeを設定
このままでは適切にcontent-typeが設定されておらず、例えば画像ファイルでもブラウザで表示されるダウンロードされるなど意図しない挙動になる恐れがある(ブラウザによる)。

```upload.php
 use WindowsAzure\Common\ServicesBuilder;
 use MicrosoftAzure\Storage\Blob\Models\CreateBlobOptions; // この行を追加
 use MicrosoftAzure\Storage\Common\ServiceException; 

// ...

$content = fopen( $tempFileName, "r" );
$options = new CreateBlobOptions(); // この行を追加
$options->setBlobContentType($contentType); // この行を追加
$blobRestProxy->createBlockBlob( "container1", $originalFileName, $content, $options ); // 引数に $options を追加
```

**upload.php**を既存のコードのうち、2カ所に上記のようなコードを追加する。
するとアップロード元と同じcontent-typeが設定され、適切な挙動が期待できるようになる。