아마존 웹서비스

S3 SDK - PHP

시작하기전에

본 수업은 'SDK - PHP' 토픽을 선행 학습으로 한다. 따라서 아직 이 수업을 보기 전이라면 꼭 보자.

예제

EC2 인스턴스에 파일을 업로드 하면 PHP가 SDK를 이용해서 S3로 파일을 전송하고, 그 결과를 화면에 출력한다. 이 때 버킷 내에 포함된 모든 객체들의 리스트를 출력한다. 

본 예제는 두개의 파일로 이루어져있다. 

  • s3.html : S3를 사용하기 위한 인증정보와 업로드 할 파일을 선택하고 전송하는 웹페이지
  • s3_receiver.php - s3.html을 통해서 업로드한 이미지를 받아서 이를 S3로 전송하고, 그 결과 페이지를 생성해주는 웹에플리케이션

본 예제를 이해하는데 도움이 될만한 수업들은 아래와 같다. 

s3.html

<!DOCTYPE html>
<html>
	<head> 
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
	</head>
	<body>
		<form enctype="multipart/form-data" action="s3_receiver.php" method="POST">
			<p><label>key</label><input type="text" name="key" /></p>
			<p><label>secret</label><input type="text" name="secret" /></p>
			<p><label>버킷</label><input type="Bucket" name="bucket" /></p>
			<p><label></label><input name="userfile" type="file" /></p>
			<p><label></label><input type="submit" value="업로드"></p>
		</form>
	</body>
</html>

s3_receiver.php

<!DOCTYPE HTML>
<html>
	<head> 
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
	</head>
	<body>
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
$uploaddir = '/tmp/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
	echo "파일이 유효하고, 성공적으로 업로드 되었습니다.\n";
} else {
	die('업로드에 실패 했습니다');
}

require './vendor/autoload.php';

use Aws\Common\Aws;
use Aws\S3\Enum\CannedAcl;
use Aws\Common\Enum\Region;

try{
	// Instantiate an S3 client
	$s3 = Aws::factory(array(
		'key'=>$_POST['key'],
		'secret'=>$_POST['secret'],
		'region'=>Region::AP_NORTHEAST_1
	))->get('s3');
	// Upload a publicly accessible file. File size, file type, and md5 hash are automatically calculated by the SDK
	$result = $s3->putObject(array(
		'Bucket' => $_POST['bucket'],
		'Key'    => $_FILES['userfile']['name'],
		'Body'   => fopen($uploadfile, 'r'),
		'ACL'    => CannedAcl::PUBLIC_READ,
		'ContentType'=>mime_content_type($uploadfile)
	));
	$list = $s3->listObjects(array(
		'Bucket' => $_POST['bucket']
	));
} catch(S3Exception $e){
	print_r($e);
}
?>
		<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorials/<?=$_FILES['userfile']['name']?>" />
		<br />
		<ul>
<?php
foreach($list['Contents'] as $object){
	echo "<li><a href=\"https://s3-ap-northeast-1.amazonaws.com/opentutorials/{$object['Key']}\" target=\"_blank\">{$object['Key']}</a></li>";
}
?>
		</ul>
	</body>
</html>

댓글

댓글 본문
  1. 김현수
    PHP 최근 버전에 맞게 수정한 버전 공유 드립니다. 참고하세요. s3.html은 같습니다.
    region은 본인 ec2 확인하시고 수정하시면 됩니다.

    그리고 key랑 secret 값을 가져오기 위해서 생성하시는 IAM User의 Permissions은,
    S3에 대한 접근 권한(AmazonS3FullAccess) 또는 AdministratorAccess로의 접근 권한을 추가해주시면 됩니다.

    s3_receiver.php

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    </head>
    <body>
    <?php
    error_reporting(E_ALL);
    ini_set('display_errors','On');
    $uploaddir = '/tmp/';
    $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "파일이 유효하고, 성공적으로 업로드 되었습니다.\n";
    } else {
    die('업로드에 실패 했습니다');
    }

    require './vendor/autoload.php';

    use Aws\S3\S3Client;
    use Aws\Exception\AwsException;

    $region = 'ap-northeast-2';
    $bucket_name = $_POST['bucket'];

    try{
    $s3Client = new S3Client([
    'region' => $region,
    'version' => 'latest',
    'credentials' => [
    'key' => $_POST['key'],
    'secret' => $_POST['secret']
    ]
    ]);

    // Upload a publicly accessible file. File size, file type, and md5 hash are automatically calculated by the SDK
    $result = $s3Client->putObject([
    'Bucket' => $bucket_name,
    'Key' => $_FILES['userfile']['name'],
    'SourceFile' => $uploadfile,
    'ACL' => 'public-read'
    ]);
    $list = $s3Client->listObjects([
    'Bucket' => $bucket_name
    ]);
    } catch(S3Exception $e){
    echo $e->getMessage() . "\n";
    }
    ?>
    <img src="https://s3-<?=$region?>.amazonaws.com/<?=$bucket_name?>/<?=$_FILES['userfile']['name']?>" />
    <br />
    <ul>
    <?php
    foreach($list['Contents'] as $object){
    echo "<li><a href=\"https://s3-{$region}.amazonaws.com/{$bucket_name}/{$object['Key']}\" target=\"_blank\">{$object['Key']}</a></li>";
    }
    ?>
    </ul>
    </body>
    </html>
  2. yomybaby
    업로드시 "Please use AWS4-HMAC-SHA256" 관련 에러가 나는 분들은 aws cli를 apt-get으로 설치하지 말고 공식 가이드에 있는 것처럼 pip를 통해 설치해보세요.

    두 설치방법에 따라 설치되는 버전이 다르더군요. pip 설치한 이후에는 위와 같은 에러가 나지 않았습니다.
    대화보기
    • toby
      s3에 업로드한 후 tmp폴더를 비우려면 어떻게 하면 좋을까요?
    • fred
      저도 아래와 같은 오류가 나는데...왜 그런걸까요?

      Fatal error: Uncaught Aws\S3\Exception\InvalidRequestException: AWS Error Code: InvalidRequest, Status Code: 400, AWS Request ID: 7F5D777C82EE9538, AWS Error Type: client, AWS Error Message: The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256., User-Agent: aws-sdk-php2/2.8.27 Guzzle/3.9.3 curl/7.40.0 PHP/5.3.29 thrown in /var/www/html/funfunlife.net/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php on line 91
    • hohyoung
      파일이 유효하고, 성공적으로 업로드 되었습니다. Fatal error: Uncaught Aws\S3\Exception\InvalidRequestException: AWS Error Code: InvalidRequest, Status Code: 400, AWS Request ID: 7F5D777C82EE9538, AWS Error Type: client, AWS Error Message: The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256., User-Agent: aws-sdk-php2/2.8.27 Guzzle/3.9.3 curl/7.40.0 PHP/5.3.29 thrown in /var/www/html/funfunlife.net/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php on line 91


      이런 오류가 나는데 왜그런걸까요?? ㅡㅡ
    • 김종진
      유저권한 설정어떻게하셔서해결하셨나요
      대화보기
      • 김종진
        유저권한 설정어떻게하셔서해결하셨나요
        대화보기
        • 김종진
          파일이 유효하고, 성공적으로 업로드 되었습니다.
          Fatal error: Class 'Aws\Common\Aws' not found in /var/www/html/aws-sdk-php-master/s3_receiver.php on line 26

          26번 라인 코드시작입니다 $s3 = Aws::factory(array(
        • 용용이
          바보같이 유저 권한설정을 안해줬었네요;;;

          다시 한번 좋은 강좌 감사합니다!!!
        • 용용이
          파일이 유효하고, 성공적으로 업로드 되었습니다.
          Fatal error: Uncaught Aws\S3\Exception\AccessDeniedException: AWS Error Code: AccessDenied, Status Code: 403, AWS Request ID: B7CB39EB6BA35A10, AWS Error Type: client, AWS Error Message: Access Denied, User-Agent: aws-sdk-php2/2.8.3 Guzzle/3.9.3 curl/7.35.0 PHP/5.5.9-1ubuntu4.9 thrown in /var/www/aws-sdk-php-master/src/Aws/Common/Exception/NamespaceExceptionFactory.php on line 91

          이런 에러가 뜨는데 secret access key 가 잘못된건가요??
          구글링 해도 잘 모르겠어요..ㅠㅠ

          좋은 강좌 잘봤습니다!!
        • 까만거북이
          이고잉님, "PHP 파일 다루기"의 링크 URL이 깨진 것 같습니다. 수정 부탁드립니다! :)
        • egoing
          도움 주셔서 감사합니다!
          대화보기
          • openhiun
            튜토리얼대로 따라했는데 안되시는 분들은 SDK로딩하는
            require './vendor/autoload.php';
            부분을
            require './aws-sdk-php-master/vendor/autoload.php';
            로 바꾸어서 해보시면 좋을것 같습니다.
            unzip으로 압축풀어보면 sdk가 담겨있는 폴더가 aws-sdk-php-master이기 때문에 저 폴더경로를 포함해서
            SDK를 로딩해주는 autoload.php를 require해주는것이 좋을것 같습니다.
            좋은 강좌 잘봤습니다.
          • oobba
            수정했습니다
            Xshell 4 메뉴 - 인코딩 (utf-8)
          • Guest
            수정완료
          • egoing
            방금 수정했습니다.
            대화보기
            • oobba
              한글깨짐..??.수정했습니다.