Amazon Web Services

PHP를 위한 S3 SDK

본 수업은 PHP SDK를 이용해서 S3를 이용하는 방법에 대한 수업입니다. 

선수학습

본 수업은 AWS SDK for PHP 수업을 먼저 들으셔야 합니다. 

권한

본 수업을 진행하기 위해서는 사용자나 역할이 AmazonS3FullAccess 권한이 있어야 합니다. 

API 사용법

파일 전송

s3_put.php

<?php
require 'vendor/autoload.php';
$param = Array('region'=>'ap-northeast-2', 'version'=>'2006-03-01');
$s3 = new Aws\S3\S3Client($param);
$s3->putObject(Array(
    'ACL'=>'public-read',
    'SourceFile'=>'sample.txt',
    'Bucket'=>'codingeverybody2',
    'Key'=>'sample.txt'
));
?>

파일 목록 가져오기

s3_list.php

<?php
require 'vendor/autoload.php';
$param = Array('region'=>'ap-northeast-2', 'version'=>'2006-03-01');
$s3 = new Aws\S3\S3Client($param);
$list = $s3->listObjects(Array('Bucket'=>'codingeverybody2'));
$listArray = $list->toArray();
foreach($listArray['Contents'] as $item){
    print($item['Key']."\n");
}
?>

파일 다운로드

s3_get.php

<?php
require 'vendor/autoload.php';
$param = Array('region'=>'ap-northeast-2', 'version'=>'2006-03-01');
$s3 = new Aws\S3\S3Client($param);
$s3->getObject(Array(
    'Bucket'=>'codingeverybody2',
    'Key'=>'sample.txt',
    'SaveAs'=>fopen('sample_saved.txt', 'w')
));

웹애플리케이션에서 S3 활용

업로드 폼

upload.html

<html>
<body>
    <form enctype="multipart/form-data" action="./s3_upload.php" method="POST">
        <input type="file" name="userfile">
        <input type="submit">
    </form>
</body>
</html>

s3로 파일 전송

s3_upload.php

<?php
require 'vendor/autoload.php';
$param = Array('region'=>'ap-northeast-2', 'version'=>'2006-03-01');
$s3 = new Aws\S3\S3Client($param);
$result = $s3->putObject(Array(
    'ACL'=>'public-read',
    'SourceFile'=>$_FILES['userfile']['tmp_name'],
    'Bucket'=>'codingeverybody2',
    'Key'=>$_FILES['userfile']['name'],
    'ContentType'=>$_FILES['userfile']['type']
));
unlink($_FILES['userfile']['tmp_name']);
$resultArray = $result->toArray();
var_dump($resultArray['ObjectURL']);
?>
<html>
<body>
<img src="<?php print($resultArray['ObjectURL']);?>" style="width:100%">
</body>
</html>

댓글

댓글 본문
  1. 당당
    2023.06.24
  2. bbae
    220507 감사합니다.
  3. 의기천추
    2022.1.30

    * 400 에러
    1, IAM의 권한 ->AdministratorAccess
    2. bucket의 권한 -> 모든 퍼블릭 엑세스 차단(비활성화)
    객체소유권 -> ACL 활성화됨 클릭(ACL 편집 가능 -> 그래야 putObject 할때 ACL 설정할수 있음)

    * 403 에러
    'Bucket'=>'본인의 버켓이름'
  4. zeronlee
    완료!!
  5. 클라우드엔지니어
    완료
  6. Woori
    bucket 권한을 full public access로 했는데도
    파일 전송이 안되네요..
  7. ㅅㄱ
    몽땅 해결했습니다.. s3버킷 권한설정에서 ACL을 통해 부여된 퍼블릭액세스차단을 해제해야하네요 이래도 되려나
  8. ㅅㄱ
    덕분에 해결했습니다 감사합니다!
    그런데 이러면 보안상 문제가 있는건 아닌지 걱정되는데 기우인가요?
    대화보기
    • ㅅㄱ
      s3 full access를 줬는데도 403forbidden뜨네요 ㅠㅠ
    • 않돼요
      php파일이 url에서는 아무것도 않나오는 백지인데
      이유 아시는분 계시나요?
    • lunaman
      오제관님 2번 답변 따라해서 해결 되었네요. 감사합니다.
    • lunaman
      1
      대화보기
      • uoou
        모든 댓글 다 읽고 해봤는데 저는 이런 에러가납니다 ㅠㅠ 도대체 무슨소리인지 ㅠㅠ
        구글에도 안나와서 답답해요..혹시 아시는분 계신가요..?
        -> Entering step init, name 'idempotency_auto_fill'
        ---------------------------------------------------

        command was set to array(3) {
        ["instance"]=>
        string(32) "0000000004a06dbc000000003bb87a04"
        ["name"]=>
        string(9) "PutObject"
        ["params"]=>
        array(5) {
        ["ACL"]=>
        string(11) "public-read"
        ["SourceFile"]=>
        NULL
        ["Bucket"]=>
        string(17) "codingeverybody93"
        ["Key"]=>
        NULL
        ["@http"]=>
        array(1) {
        ["debug"]=>
        resource(2) of type (stream)
        }
        }
        }

        request was set to array(0) {
        }



        -> Entering step init, name 's3.ssec'
        -------------------------------------

        no changes


        -> Entering step init, name 's3.source_file'
        --------------------------------------------

        no changes


        -> Entering step init, name 's3.save_as'
        ----------------------------------------

        no changes


        -> Entering step init, name 's3.location'
        -----------------------------------------

        no changes


        -> Entering step init, name 's3.auto_encode'
        --------------------------------------------

        no changes


        -> Entering step init, name 's3.head_object'
        --------------------------------------------

        no changes
      • yoojat
        와 2번 덕분에 해결했습니다 감사합니다 ㅠㅠ
        대화보기
        • 오제관
          500 에러에 관해
          1. 정확히 에러가 무엇인지 봅시다.
          $s3 = new Aws\S3\S3Client([
          'region'=>'ap-northeast-2',
          'version'=>'2006-03-01',
          'debug'=> true
          ]);
          클라이언트 오브젝트 생성시 debug라는 키에 트루를 주면 어디서 에러가 나왔는지 볼 수 있습니다.

          2. Error retrieving credentials from the instance profile metadata server
          저 또한 이 에러를 발견했습니다.
          문제의 원인은 이렇습니다.
          [credentials에 우리가 저장한 키와 시크릿키를 브라우저에서 실행하니 참조하지 못한다.]
          $s3 = new Aws\S3\S3Client([
          'region'=>'ap-northeast-2',
          'profile'=>'default',
          'version'=>'2006-03-01',
          'debug'=> true
          ]);
          크레덴셜스 안에 있는 키들의 프로필 명을 직접 가리켰는데도 안되었습니다.
          실제로 vendor/autoload.php를 읽어보고 별내용 없이 autoload_real.php를 리콰이어 하길래 가서 읽어봤더니
          딱히 크레덴셜의 확보에 대한 내용이 어딘지 찾기 어려웠습니다.

          [ 솔루션 ]
          결국 웹애플리케이션 파일 하나하나마다 권한 통제를 포기하고
          EC2에 IAM을 붙이기로 했습니다.

          EC2콘솔 -> 인스턴스 오른쪽 클릭 -> 인스턴스 세팅 -> Attach/Replace IAM role 클릭
          (저처럼 직접만드는 분들은 아마 IAM롤을 만들어두지 않았을 겁니다)
          -Create new IAM role 클릭
          -Create new role 클릭
          -이름을 정합니다.
          -AWS service roles 에서 [Amazon EC2]를 선택하고 다음
          -[AmazonS3FullAccess]을 체크하고 다음
          -create Role
          이제 다시 EC2콘솔의 IAM role 선택 창으로 돌아가 옆의 새로고침누르면 방금 만든 IAM롤이 뜰겁니다.
          선택하시고 적용 - > reboot

          저는 이후로 완벽히 동작하고 있습니다. 다른 분들도 도움이 되셨으면 좋겠네요.
        • 시험모드
          음.. 우선 500 에러 에 대한 해결방법입니다.

          일단 과정을 말씀드리면..

          제 경우에는
          pubObject부분에서 계속 에러가 발생했기 때문에
          try catch 문을 넣어서 에러를 뽑았습니다.

          <?php
          require 'vendor/autoload.php';
          $param = Array('region'=>'ap-northeast-2', 'version'=>'2006-03-01');
          $s3 = new Aws\S3\S3Client($param);
          try
          {
          $s3->putObject(Array(
          'ACL'=>'public-read',
          'SourceFile'=>'sample.txt',
          'Bucket'=>'codingeverybody2',
          'Key'=>'sample.txt'
          ));
          } catch (Exception e){
          echo $e;
          }
          ?>

          에러 로그를 보니..
          Error retrieving credentials from the instance profile metadata server
          이런 문구가 보이더군요.

          뭐.. 인증 정보가 제대로 인식이 안되는것 같습니다.

          그래서 우선,
          $param = Array('region'=>'ap-northeast-2', 'version'=>'2006-03-01', 'credentials' => array(
          'key' => '서버키',
          'secret' => '보안키',
          ));

          의 형태로 강제로 인증키를 넣어보았더니.. 에러 없이 파일이 잘 들어가더라구요.

          테스트 단계라 다른 인증방식은 사용해 보지 않았지만..
          인증키 부분만 잘 삽입되도록 하면 될 것같습니다.


          이걸 몰라서.. 이전에는 ec2 instance 새로 만들어서 IAM role 부여해서 했었는데..
          이번에는 다행히도 해결책을 찾았네요.

          도움이 되셨으면 좋겠습니다.
          대화보기
          • 시험모드
            답변 달아주신 그 부분에서 막히고 있습니다.

            CLI 로 실행하면 다운로드가 잘 되는데,
            브라우저 에서 실행하면 500 에러가 뜨고 아무 반응이 없습니다.

            로컬이 아닌 AWS EC2+S3 사용중이에요.

            IAM role을 부여하면 해결된다고 하셨는데..혹시 방법 좀 알 수 있을까요?
            대화보기
            • 구녹수수
              저도 서버오류500이 발생하는데 어떻게 해야하나요?
            • fabxoe
              9분 20초 무렵에, 저도 서버오류 500이 발생했어요.
            • SK Kim
              마지막 부분 작동이 안되어서 좀 고생했네요.
              원격으로 CLI에서 PHP가 정상 작동되지만 browser를 사용하면 서버오류 500가 나면서 작동을 안합니다.
              AWS를 사용하면 instance 생성시 IAM role을 부여하면 문제가 해결 되는데...
              로컬 환경에서 VM으로 서버를 생성하면 문제는 그대로 있네요.
            • egoing
              수정했습니다 ^^
              대화보기
              • humit
                강의 잘보고 있습니다! 글에 있는 s3_get.php에 해당하는 소스코드가 잘못 된 것 같네요.
              버전 관리
              egoing
              현재 버전
              선택 버전
              graphittie 자세히 보기