👋

AWS SDK for PHPでAWS S3へ画像をアップロードする

2023/06/20に公開

はじめに

今回はをAWS S3へ画像をアップロードの実装を行いました。
AWS SDKを使用するメリットは
・大容量のファイルのアップロードに特化している
・高速かつ信頼性の高いアップロードを実現できる
・セキュリティやスケーラビリティなどの面でも利点がある
・AWSのサービスとの統合が容易になりますので、バケットの作成、アップロード、アクセス制御などのタスクを簡単に実行できる
になります。

前提条件

AWSアカウントの取得

1.IAMより 「アクセスキー」と「シークレットキー」を作成する

①ポリシーの作成

ポリシーエディタ:JSONを選択
以下を貼り付ける(今回はバケットにオブジェクトを追加するアクセス許可を付与)
※他に権限を付与したい場合はこちら

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3::: [バケット名]",
                "arn:aws:s3::: [バケット名]/*"
            ]
        }
    ]
}

ポリシー名:なんでもOK
作成をクリック

<説明>
・Action
s3:DeleteObject:オブジェクトの削除
s3:GetObject:オブジェクトの取得
s3:ListBucket:バケットのリスト表示
s3:PutObject:オブジェクトの作成
s3:PutObjectAcl:オブジェクトのACL設定
の操作が許可されている

②ユーザーの作成

ユーザー名:なんでもOK
許可のオプション:ポリシーを直接アタッチする
許可ポリシーの検索バーより①で作成したポリシーを選択する
作成をクリック

③タブから「セキュリティ認証情報」を選択し、アクセスキーの「アクセスキーを作成」をクリック

④アクセスキーを作成

主要なベストプラクティスと代替案にアクセスする:AWS コンピューティングサービスで実行されるアプリケーションを選択
上記のレコメンデーションを理解し、アクセスキーを作成します:チェックいれる
説明タグ値:任意
「アクセスキーを作成」をクリック

⑤作成された「アクセスキー」と「シークレットキー」をメモ or CSVダウンロードしておく

2.S3に画像の格納場所を作る

①バケットの作成

バケット名:なんでもOK
AWSリージョン:アジアパシフィック(東京)ap-northeast-1

オブジェクト所有者:ACL有効(希望するバケット所有者)

このバケットのブロックパブリックアクセス設定:
「パブリックアクセスをすべてブロック」をチェックを外し、下から2つにチェックを入れる

バケットを作成をクリック

②バケットポリシーの設定

①で作成したバケットを選択して、上のバーより「アクセス許可」をクリック
バケットポリシーに以下を設定

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "[IAMユーザーARN]"
            },
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::[バケット名]",
                "arn:aws:s3:::[バケット名]/*"
            ]
        }
    ]
}

・[IAMユーザーARN]:1.①で作成したIAMユーザーのARNを設定
・[バケット名]:2.①で作成したバケット名を記載

3.AWS SDK for PHPをインストールする

①アップデート可能なパッケージを更新

sudo apt update -y

②依存関係のインストール

$ sudo apt install curl php-cli php-mbstring git unzip

<説明>

  • curl:php-cliをインストールするのに必要
  • php-cli:Composerのインストールと実行に必要
  • php-mbstring:使用するライブラリに機能を提供
  • git:Composerの依存関係をダウンロードするのに必要
  • unzip:圧縮されたパッケージの解凍に必要

③Composerのインストール

公式のコマンドからインストール

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

※インストールされたらバージョンが表示される

composer --version

④プロジェクトのベースディレクトリに移動して、AWS SDK for PHPをインストールする

composer require aws/aws-sdk-php

vendor,composer.json,composer.lockが入ってるか確認
ちなみに「aws-sdk-php」は下記に格納されている
/vendor/aws/aws-sdk-php

4.アクセスキー,シークレットキーを設定する

①phpdotnvをインストールする

環境変数設定のライブラリです。

composer require vlucas/phpdotenv

②.envファイルを作成する

S3_ACCESS_KEY="アクセスキー"
S3_SECRET_KEY="シークレットキー"

<説明>
・[アクセスキー]:1.④で作成したアクセスキーを記載
・[シークレットキー]:1.④で作成したシークレットキーを記載

※.envファイルは、.htaccess等でアクセス拒否設定 をしたり、パーミッション(400) を見直す。
記述例

<Files ".env">
    Order Allow,Deny
    Deny from all
</Files>

5.画像をアップロードする

<?php
require_once('vendor/autoload.php');

use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();

$credentials = [
	'key'    => $_ENV['S3_ACCESS_KEY'],
	'secret' => $_ENV['S3_SECRET_KEY'],
];
$bucket = '[バケット名]';

$source_file = @$_FILES['source_file'];
if ($source_file) {
	if ($source_file['size'] && $source_file['size'] > 0) {
		upload($source_file, $credentials, $bucket);
	}
}

// S3へアップロード
function upload($source_file, $credentials, $bucket)
{
	try {
		$s3Client = new S3Client([
			'credentials' => $credentials,
			'region'  => 'ap-northeast-1',
			'version' => 'latest',
		]);

		$option = [
			'ACL'        => 'public-read',
			'Bucket'     => $bucket,
			'Key'        => 'imgs/' . basename($source_file['name']),
			'SourceFile' => $source_file['tmp_name'],
			'ContentType'  => mime_content_type($source_file['tmp_name']),
			'CacheControl' => 'max-age=300',
		];

		$result = $s3Client->putObject($option);

		echo '<pre>';
		print_r($result);
		echo '</pre>';
		exit;
	} catch (S3Exception $e) {
		echo $e->getMessage();
	}
}
?>

<html>

<head>
	<meta charset="UTF-8">
	<title>S3</title>
</head>

<body>
	<h1>S3アップロード</h1>
	<form method="post" action="/upload.php" enctype="multipart/form-data">
		<input type="file" name="source_file">
		<input type="submit">
	</form>
</body>

</html>

・[バケット名]:2.①で作成したバケット名を記載

~終了~

参考にした記事

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/s3-example-photo-album.html

Discussion