-
-
Save saxenap/5f69c0dffeeccad280047de7e1b4fbdb to your computer and use it in GitHub Desktop.
S3 PHP Example (without an SDK)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class S3 { | |
private $key = 'ABC123'; | |
private $secret = 'lolftw'; | |
private $region = 'us-west-2'; | |
private $bucket = 'examplebucket'; | |
private $host = 's3.amazonaws.com'; | |
public function uploadFile($file_path) { | |
$default_timezone = date_default_timezone_get(); | |
date_default_timezone_set('UTC'); | |
$file_contents = file_get_contents($file_path); | |
$file_name = basename($file_path); | |
$hashed_payload = hash('sha256', $file_contents); | |
$date_full = date('D, d M Y H:i:s \G\M\T'); // @todo don't force GMT! | |
$date_time = date('Ymd\THisZ'); // @todo don't force Z! | |
$date = date('Ymd'); | |
// Set headers. | |
$headers = array( | |
'Host' => $this->bucket . '.' . $this->host, | |
'Content-Type' => mime_content_type($file_name), | |
'x-amz-content-sha256' => $hashed_payload, | |
'x-amz-date' => $date_full, | |
); | |
ksort($headers); | |
$signed_headers_string = strtolower(implode(';', array_keys($headers))); | |
// Build canonical request. | |
$canonical_request = "PUT\n"; // HTTP Method | |
$canonical_request .= '/' . urlencode($file_name) . "\n"; // Canonical URI | |
$canonical_request .= "\n"; // CanonicalQueryString | |
foreach ($headers as $header => $value) { | |
$canonical_request .= strtolower($header) . ':' . trim($value) . "\n"; | |
} | |
$canonical_request .= "\n"; | |
$canonical_request .= $signed_headers_string . "\n"; // SignedHeaders | |
$canonical_request .= $hashed_payload; // HashedPayload | |
print "\n\nCanonical Request:\n" . $canonical_request; | |
// Build string to sign. | |
$string_to_sign = "AWS4-HMAC-SHA256\n"; | |
$string_to_sign .= $date_full . "\n"; | |
$string_to_sign .= $date . '/' . $this->region . "/s3/aws4_request\n"; | |
$string_to_sign .= hash('sha256', $canonical_request); | |
print "\n\nString to Sign:\n" . $string_to_sign; | |
// Calculate signature. | |
$signature_date = hash_hmac('sha256', $date, 'AWS4' . $this->secret, true); | |
$signature_region = hash_hmac('sha256', $this->region, $signature_date, true); | |
$signature_service = hash_hmac('sha256', 's3', $signature_region, true); | |
$signature_request = hash_hmac('sha256', 'aws4_request', $signature_service, true); | |
$signature = hash_hmac('sha256', $string_to_sign, $signature_request); | |
// Calculate final `Authorization` header. | |
$headers['Authorization'] = 'AWS4-HMAC-SHA256 Credential=' . $this->key . '/' . $date . '/' . $this->region . '/s3/aws4_request,'; | |
$headers['Authorization'] .= 'SignedHeaders=' . $signed_headers_string . ','; | |
$headers['Authorization'] .= 'Signature=' . $signature; | |
print "\n\nAuthorization:\n" . $headers['Authorization']; | |
// Convert headers to key:value strings. | |
$curl_headers = array(); | |
foreach ($headers as $header => $value) { | |
$curl_headers[] = "{$header}:{$value}"; | |
} | |
// Init curl. | |
$curl = curl_init(); | |
$url = 'https://' . $this->bucket . '.' . $this->host . '/' . $file_name; | |
curl_setopt($curl, CURLOPT_URL, $url); | |
curl_setopt($curl, CURLOPT_VERBOSE, 1); | |
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); | |
curl_setopt($curl, CURLINFO_HEADER_OUT, true); | |
curl_setopt($curl, CURLOPT_HEADER, true); | |
curl_setopt($curl, CURLOPT_HTTPHEADER, $curl_headers); | |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($curl, CURLOPT_POSTFIELDS, $file_contents); | |
// Run request. | |
$result = curl_exec($curl); | |
print "\n\nHeaders sent:\n"; | |
$headers_sent = curl_getinfo($curl, CURLINFO_HEADER_OUT); | |
print_r($headers_sent); | |
$error = true; | |
$http_code = null; | |
if ($result) { | |
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); | |
if ($http_code === 200) { | |
print "\n\nSuccess!\n"; | |
$error = false; | |
} | |
} | |
if($error) | |
{ | |
print "\n\nError!\n"; | |
print_r(array( | |
'code' => curl_errno($curl), | |
'message' => curl_error($curl), | |
)); | |
} | |
print $http_code . "\n\n"; | |
print_r($result); | |
@curl_close($curl); | |
date_default_timezone_set($default_timezone); | |
} | |
} | |
$foo = new S3(); | |
$foo->uploadFile(__DIR__ . '/phpinfo.php'); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment