気ままに

プログラム関連で困ったことを調べて気ままに投稿

【AWS】PHPからS3に画像をアップロードする

AWS SDKのバージョン3を使って、S3にファイルをアップロードしようとしたハマってしまったので、 自分のメモも兼ねて書いておこう。

composerを使って、AWS SDK の3系をインストール。まずは、composer.jsonを編集

{
        "aws/aws-sdk-php": "3.*"
}

composerをインストール

 $ composer update

環境変数に以下のパラメータ名で、IAM情報を記載

AWS_ACCESS_KEY_ID=<アクセスキー>
AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>
S3_BUCKET_NAME=<S3バケット名>

以下のPHPファイルを表示して、画像ファイルを選択してアップロードするとエラー。。。

<?php
require '../vendor/autoload.php';
?>

<html>
    <head><meta charset="UTF-8"></head>
    <body>
        <h1>S3 upload example</h1>
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['userfile']) && $_FILES['userfile']['error'] == UPLOAD_ERR_OK && is_uploaded_file($_FILES['userfile']['tmp_name'])) {
    // FIXME: add more validation, e.g. using ext/fileinfo
    try {
        // FIXME: do not use 'name' for upload (that's the original filename from the user's computer)
        $s3client  = new Aws\S3\S3Client([
            'credentials' => [
                'key' => getenv('AWS_ACCESS_KEY_ID'),
                'secret' => getenv('AWS_SECRET_ACCESS_KEY'),
            ],
            'region' => 'ap-northeast-1',
            'version' => 'latest',
        ]);
        $bucket = getenv('S3_BUCKET_NAME');
        $result = $s3client->putObject([
            'ACL' => 'public-read',
            'Bucket' => $bucket,
            'Key' => $_FILES['userfile']['name'],
            'Body' => fopen($_FILES['userfile']['tmp_name'],'rb'),
            'ContentType' => mime_content_type($_FILES['userfile']['tmp_name']),
        ]);

?>
        <p>Upload <a href="<?=htmlspecialchars($result->get('ObjectURL'))?>">successful</a></p>
<?php } catch(Exception $e) { ?>
        <p>Upload error : ( <?php echo $e->getMessage(); ?> </p>
<?php } } ?>
        <h2>Upload a file</h2>
        <form enctype="multipart/form-data" action="<?=$_SERVER['PHP_SELF']?>" method="POST">
            <input name="userfile" type="file"><input type="submit" value="Upload">
        </form>
    </body>
</html>

まずは、環境の問題でxmlの問題なので、以下の手順で追加

CentOSだと以下のコマンドで php-xmlを追加する。すでにインストールが済んでいれば、差分だけ実行する。

$ yum -y install --enablerepo=remi,remi-php56 php php-devel php-mbstring php-pdo php-gd php-pgsql php-xml php-mcrypt

これでアップロードできる?と思ったら、AccessDenied でできない。 putObjectのパラメータから 'ACL' => 'public-read',の行をコメントアウトしてアップロードするとアップロードできるけど、 URLにアクセスしたら同じエラーが出たので、原因を調べるとIAMユーザのACL制限の問題しでした。。。

google先生に聞いても完全なソースがなく、試行錯誤。今まで他の人が書いたソースだけ見てたから、環境設定や権限の設定まわり見えてなかったのが原因。 忘れないようにメモしとこう。

WEB+DB PRESS Vol.105

WEB+DB PRESS Vol.105

  • 作者: 小笠原みつき,西村公宏,柳佳音,志甫侑紀,池田友洋,木村涼平,?橋優介,大塚雅和,飯塚直,吉川竜太,末永恭正,久保田祐史,浜田真成,穴井宏幸,大島一将,桑原仁雄,牧大輔,池田拓司,はまちや2,竹原,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/06/23
  • メディア: 単行本
  • この商品を含むブログを見る