├── README.markdown ├── class.awis.php ├── class.ec2.php ├── class.s3.php ├── class.sqs.php └── examples └── awisexample.php /README.markdown: -------------------------------------------------------------------------------- 1 | # April, 2019 Update 2 | 3 | PHP-AWS had a good run when it debuted 11 years ago. One of the first PHP wrappers around Amazon's then fledgling AWS services, it was a great resource before there was an offical PHP SDK from Amazon. 4 | 5 | But now this code is ancient, uses a deprecated API, and is horribly insecure and based on PHP 5. DO NOT USE. I'm archiving the repo. Thanks to everyone who contributed! 6 | 7 | # PHP-AWS 8 | 9 | PHP-AWS is a collection of PHP classes for working with [Amazon's web services platform](http://www.amazonaws.com). Currently, we have classes for use with 10 | 11 | * [Simple Storage Service](http://www.amazonaws.com/s3/) (S3) 12 | * [ Simple Queue Service](http://www.amazonaws.com/sqs/) (SQS) 13 | * [Elastic Compute Cloud](http://www.amazonaws.com/EC2/) (EC2) 14 | * [Alexa Web Information Service](http://aws.amazon.com/awis/) (AWIS) 15 | 16 | If you're looking for a super-robust AWS solution in PHP, I'd suggest the [Tarzan AWS](http://tarzan-aws.com/) project. PHP-AWS was a good solution when AWS first launched, but Tarzan is a much more mature and supported project. Still, PHP-AWS is good example code for getting your feet wet with AWS. 17 | -------------------------------------------------------------------------------- /class.awis.php: -------------------------------------------------------------------------------- 1 | _key = $key; 17 | $this->_secret = $secret; 18 | } 19 | 20 | // If the path to curl isn't set, try and auto-detect it 21 | if($this->_pathToCurl == "") 22 | { 23 | $path = trim(shell_exec("which curl"), "\n "); 24 | if(is_executable($path)) 25 | $this->_pathToCurl = $path; 26 | else 27 | { 28 | $this->_error = "Couldn't auto-detect path to curl"; 29 | return false; 30 | } 31 | } 32 | 33 | return true; 34 | } 35 | 36 | function urlInfo($url, $responseGroup) 37 | { 38 | $req = array( "Url" => $url, "ResponseGroup" => $responseGroup ); 39 | $result = $this->go("UrlInfo", $req); 40 | return $result->Response->UrlInfoResult->Alexa; 41 | } 42 | 43 | 44 | function trafficHistory($url, $range=30, $start="") 45 | { 46 | 47 | if (!$start) { 48 | $start = date("Ymd", mktime(0,0,0,date("m"),date("d")-31,date("Y"))); 49 | } 50 | $req = array( "Url" => $url, "ResponseGroup" => "History", "Start" => $start, "Range" => $range ); 51 | $result = $this->go("TrafficHistory", $req); 52 | return $result->Response->TrafficHistoryResult->Alexa->TrafficHistory; 53 | } 54 | 55 | function sitesLinkingIn($url, $start=0, $count=10) 56 | { 57 | $req = array( "Url" => $url, "ResponseGroup" => "SitesLinkingIn", "Start" => $start, "Count" => $count ); 58 | $result = $this->go("SitesLinkingIn", $req); 59 | return $result->Response->SitesLinkingInResult->Alexa->SitesLinkingIn; 60 | } 61 | 62 | function go($action, $params, $url = null) 63 | { 64 | if(!is_array($params)) $params = array(); 65 | $params['Action'] = $action; 66 | $params['Timestamp'] = gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time()); 67 | $params['Version'] = $this->_version; 68 | $params['AWSAccessKeyId'] = $this->_key; 69 | $params['Signature'] = $this->calculate_RFC2104HMAC($params['Action'] . $params['Timestamp'],$this->_secret); 70 | if(!isset($url)) $url = $this->_server; 71 | 72 | $url .= "?"; 73 | foreach($params as $key => $val) 74 | $url .= "$key=" . urlencode($val)."&"; 75 | $xmlstr = $this->geturl($url); 76 | $xmlstr = preg_replace("/<(\/?)aws:/","<$1",$xmlstr); 77 | $xml = simplexml_load_string($xmlstr); 78 | if(isset($xml->Errors)) 79 | return false; 80 | else 81 | return $xml; 82 | } 83 | 84 | function calculate_RFC2104HMAC($data, $key) { 85 | return base64_encode ( 86 | pack("H*", sha1((str_pad($key, 64, chr(0x00)) 87 | ^(str_repeat(chr(0x5c), 64))) . 88 | pack("H*", sha1((str_pad($key, 64, chr(0x00)) 89 | ^(str_repeat(chr(0x36), 64))) . $data)))) 90 | ); 91 | } 92 | 93 | function geturl($url, $username = "", $password = "") 94 | { 95 | if(function_exists("curl_init")) 96 | { 97 | $ch = curl_init(); 98 | if(!empty($username) && !empty($password)) curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic ' . base64_encode("$username:$password"))); 99 | curl_setopt($ch, CURLOPT_URL, $url); 100 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 101 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 102 | $html = curl_exec($ch); 103 | curl_close($ch); 104 | return $html; 105 | } 106 | elseif(ini_get("allow_url_fopen") == true) 107 | { 108 | if(!empty($username) && !empty($password)) 109 | { 110 | $url = str_replace("http://", "http://$username:$password@", $url); 111 | $url = str_replace("https://", "https://$username:$password@", $url); 112 | } 113 | $html = file_get_contents($url); 114 | return $html; 115 | } 116 | else 117 | { 118 | // Cannot open url. Either install curl-php or set allow_url_fopen = true in php.ini 119 | return false; 120 | } 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /class.ec2.php: -------------------------------------------------------------------------------- 1 | _key = $key; 16 | $this->_secret = $secret; 17 | } 18 | 19 | // If the path to curl isn't set, try and auto-detect it 20 | if($this->_pathToCurl == "") 21 | { 22 | $path = trim(shell_exec("which curl"), "\n "); 23 | if(is_executable($path)) 24 | $this->_pathToCurl = $path; 25 | else 26 | { 27 | $this->_error = "Couldn't auto-detect path to curl"; 28 | return false; 29 | } 30 | } 31 | 32 | return true; 33 | } 34 | 35 | function getImages($ownerId = null) 36 | { 37 | $params = array("Action" => "DescribeImages"); 38 | if(isset($ownerId)) $params['Owner.1'] = $ownerId; 39 | $xmlstr = $this->sendRequest($params); 40 | $xml = new SimpleXMLElement($xmlstr); 41 | 42 | $images = array(); 43 | foreach($xml->imagesSet->item as $item) 44 | $images[(string) $item->imageId] = 45 | array("location" => (string) $item->imageLocation, 46 | "state" => (string) $item->imageState, 47 | "owner" => (string) $item->imageOwnerId, 48 | "public" => (string) $item->isPublic); 49 | return $images; 50 | } 51 | 52 | function getInstances() 53 | { 54 | $params = array("Action" => "DescribeInstances"); 55 | $xmlstr = $this->sendRequest($params); 56 | $xml = new SimpleXMLElement($xmlstr); 57 | 58 | $instances = array(); 59 | foreach($xml->reservationSet->item as $item) 60 | $instances[(string) $item->instancesSet->item->instanceId] = 61 | array("imageId" => (string) $item->instancesSet->item->imageId, 62 | "state" => (string) $item->instancesSet->item->instanceState->name, 63 | "dns" => (string) $item->instancesSet->item->dnsName); 64 | return $instances; 65 | } 66 | 67 | function runInstances($imageId, $min = 1, $max = 1, $keyName = "gsg-keypair") 68 | { 69 | $params = array("Action" => "RunInstances", 70 | "ImageId" => $imageId, 71 | "MinCount" => $min, 72 | "MaxCount" => $max, 73 | "KeyName" => $keyName); 74 | 75 | $xmlstr = $this->sendRequest($params); 76 | $xml = new SimpleXMLElement($xmlstr); 77 | 78 | $instances = array(); 79 | foreach($xml->instancesSet->item as $item) 80 | $instances[(string) $item->instanceId] = 81 | array("imageId" => (string) $item->imageId, 82 | "state" => (string) $item->instanceState->name, 83 | "dns" => (string) $item->dnsName); 84 | return $instances; 85 | } 86 | 87 | function getKeys() 88 | { 89 | $params = array("Action" => "DescribeKeyPairs"); 90 | $xmlstr = $this->sendRequest($params); 91 | $xml = new SimpleXMLElement($xmlstr); 92 | 93 | $keys = array(); 94 | foreach($xml->keySet->item as $item) 95 | $keys[] = array("name" => (string) $item->keyName, "fingerprint" => (string) $item->keyFingerprint); 96 | return $keys; 97 | } 98 | 99 | function terminateInstances($toKill) 100 | { 101 | $params = array("Action" => "TerminateInstances"); 102 | $toKill = explode(",", $toKill); 103 | $i = 0; 104 | foreach($toKill as $id) 105 | $params['InstanceId.' . ++$i] = $id; 106 | $xmlstr = $this->sendRequest($params); 107 | $xml = new SimpleXMLElement($xmlstr); 108 | 109 | $instances = array(); 110 | foreach($xml->instancesSet->item as $item) 111 | $instances[(string) $item->instanceId] = 112 | array("shutdownState" => (string) $item->shutdownState, 113 | "previousState" => (string) $item->previousState); 114 | return $instances; 115 | } 116 | 117 | function sendRequest($params) 118 | { 119 | $params['AWSAccessKeyId'] = $this->_key; 120 | $params['SignatureVersion'] = 1; 121 | $params['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z"); 122 | $params['Version'] = "2006-10-01"; 123 | uksort($params, "strnatcasecmp"); 124 | 125 | $toSign = ""; 126 | foreach($params as $key => $val) 127 | $toSign .= $key . $val; 128 | $sha1 = $this->hasher($toSign); 129 | $sig = $this->base64($sha1); 130 | $params['Signature'] = $sig; 131 | 132 | $uri = $this->_server . '/?'; 133 | 134 | foreach($params as $key => $val) 135 | $uri .= "$key=" . urlencode($val) . "&"; 136 | 137 | $ch = curl_init(); 138 | curl_setopt($ch, CURLOPT_URL, $uri); 139 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 140 | 141 | $result = curl_exec($ch); 142 | curl_close($ch); 143 | 144 | return $result; 145 | } 146 | 147 | function hasher($data) 148 | { 149 | // Algorithm adapted (stolen) from http://pear.php.net/package/Crypt_HMAC/) 150 | $key = $this->_secret; 151 | if(strlen($key) > 64) 152 | $key = pack("H40", sha1($key)); 153 | if(strlen($key) < 64) 154 | $key = str_pad($key, 64, chr(0)); 155 | $ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64)); 156 | $opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64)); 157 | return sha1($opad . pack("H40", sha1($ipad . $data))); 158 | } 159 | 160 | function base64($str) 161 | { 162 | $ret = ""; 163 | for($i = 0; $i < strlen($str); $i += 2) 164 | $ret .= chr(hexdec(substr($str, $i, 2))); 165 | return base64_encode($ret); 166 | } 167 | } 168 | ?> -------------------------------------------------------------------------------- /class.s3.php: -------------------------------------------------------------------------------- 1 | key = $key; 20 | $this->privateKey = $private_key; 21 | $this->host = $host; 22 | $this->date = gmdate('D, d M Y H:i:s T'); 23 | return true; 24 | } 25 | 26 | public function listBuckets() 27 | { 28 | $request = array('verb' => 'GET', 'resource' => '/'); 29 | $result = $this->sendRequest($request); 30 | $xml = simplexml_load_string($result); 31 | 32 | if($xml === false || !isset($xml->Buckets->Bucket)) 33 | return false; 34 | 35 | $buckets = array(); 36 | foreach($xml->Buckets->Bucket as $bucket) 37 | $buckets[] = (string) $bucket->Name; 38 | return $buckets; 39 | } 40 | 41 | public function createBucket($name) 42 | { 43 | $request = array('verb' => 'PUT', 'resource' => "/$name/"); 44 | $result = $this->sendRequest($request); 45 | return $this->curlInfo['http_code'] == '200'; 46 | } 47 | 48 | public function deleteBucket($name) 49 | { 50 | $request = array('verb' => 'DELETE', 'resource' => "/$name/"); 51 | $result = $this->sendRequest($request); 52 | return $this->curlInfo['http_code'] == '204'; 53 | } 54 | 55 | public function getBucketLocation($name) 56 | { 57 | $request = array('verb' => 'GET', 'resource' => "/$name/?location"); 58 | $result = $this->sendRequest($request); 59 | $xml = simplexml_load_string($result); 60 | 61 | if($xml === false) 62 | return false; 63 | 64 | return (string) $xml->LocationConstraint; 65 | } 66 | 67 | public function getBucketContents($name, $prefix = null, $marker = null, $delimeter = null, $max_keys = null) 68 | { 69 | $contents = array(); 70 | 71 | do 72 | { 73 | $q = array(); 74 | if(!is_null($prefix)) $q[] = 'prefix=' . $prefix; 75 | if(!is_null($marker)) $q[] = 'marker=' . $marker; 76 | if(!is_null($delimeter)) $q[] = 'delimeter=' . $delimeter; 77 | if(!is_null($max_keys)) $q[] = 'max-keys=' . $max_keys; 78 | $q = implode('&', $q); 79 | if(strlen($q) > 0) 80 | $q = '?' . $q; 81 | 82 | $request = array('verb' => 'GET', 'resource' => "/$name/$q"); 83 | $result = $this->sendRequest($request); 84 | $xml = simplexml_load_string($result); 85 | 86 | if($xml === false) 87 | return false; 88 | 89 | foreach($xml->Contents as $item) 90 | $contents[(string) $item->Key] = array('LastModified' => (string) $item->LastModified, 'ETag' => (string) $item->ETag, 'Size' => (string) $item->Size); 91 | 92 | $marker = (string) $xml->Marker; 93 | } 94 | while((string) $xml->IsTruncated == 'true' && is_null($max_keys)); 95 | 96 | return $contents; 97 | } 98 | 99 | public function uploadFile($bucket_name, $s3_path, $fs_path, $web_accessible = false, $headers = null) 100 | { 101 | // Some useful headers you can set manually by passing in an associative array... 102 | // Cache-Control 103 | // Content-Type 104 | // Content-Disposition (alternate filename to present during web download) 105 | // Content-Encoding 106 | // x-amz-meta-* 107 | // x-amz-acl (private, public-read, public-read-write, authenticated-read) 108 | 109 | $request = array('verb' => 'PUT', 110 | 'resource' => "/$bucket_name/$s3_path", 111 | 'content-md5' => $this->base64(md5_file($fs_path))); 112 | 113 | $fh = fopen($fs_path, 'r'); 114 | $curl_opts = array('CURLOPT_PUT' => true, 115 | 'CURLOPT_INFILE' => $fh, 116 | 'CURLOPT_INFILESIZE' => filesize($fs_path), 117 | 'CURLOPT_CUSTOMREQUEST' => 'PUT'); 118 | 119 | if(is_null($headers)) 120 | $headers = array(); 121 | 122 | $headers['Content-MD5'] = $request['content-md5']; 123 | 124 | if($web_accessible === true && !isset($headers['x-amz-acl'])) 125 | $headers['x-amz-acl'] = 'public-read'; 126 | 127 | if(!isset($headers['Content-Type'])) 128 | { 129 | $ext = strtolower(pathinfo($fs_path, PATHINFO_EXTENSION)); 130 | $headers['Content-Type'] = isset($this->mimeTypes[$ext]) ? $this->mimeTypes[$ext] : 'application/octet-stream'; 131 | } 132 | $request['content-type'] = $headers['Content-Type']; 133 | 134 | $result = $this->sendRequest($request, $headers, $curl_opts); 135 | fclose($fh); 136 | return $this->curlInfo['http_code'] == '200'; 137 | } 138 | 139 | public function deleteObject($bucket_name, $s3_path) 140 | { 141 | $request = array('verb' => 'DELETE', 'resource' => "/$bucket_name/$s3_path"); 142 | $result = $this->sendRequest($request); 143 | return $this->curlInfo['http_code'] == '204'; 144 | } 145 | 146 | public function copyObject($bucket_name, $s3_path, $dest_bucket_name, $dest_s3_path) 147 | { 148 | $request = array('verb' => 'PUT', 'resource' => "/$dest_bucket_name/$dest_s3_path"); 149 | $headers = array('x-amz-copy-source' => "/$bucket_name/$s3_path"); 150 | $result = $this->sendRequest($request, $headers); 151 | 152 | if($this->curlInfo['http_code'] != '200') 153 | return false; 154 | 155 | $xml = simplexml_load_string($result); 156 | if($xml === false) 157 | return false; 158 | 159 | return isset($xml->LastModified); 160 | } 161 | 162 | public function getObjectInfo($bucket_name, $s3_path) 163 | { 164 | $request = array('verb' => 'HEAD', 'resource' => "/$bucket_name/$s3_path"); 165 | $curl_opts = array('CURLOPT_HEADER' => true, 'CURLOPT_NOBODY' => true); 166 | $result = $this->sendRequest($request, null, $curl_opts); 167 | $xml = @simplexml_load_string($result); 168 | 169 | if($xml !== false) 170 | return false; 171 | 172 | preg_match_all('/^(\S*?): (.*?)$/ms', $result, $matches); 173 | $info = array(); 174 | for($i = 0; $i < count($matches[1]); $i++) 175 | $info[$matches[1][$i]] = $matches[2][$i]; 176 | 177 | if(!isset($info['Last-Modified'])) 178 | return false; 179 | 180 | return $info; 181 | } 182 | 183 | public function downloadFile($bucket_name, $s3_path, $fs_path) 184 | { 185 | $request = array('verb' => 'GET', 'resource' => "/$bucket_name/$s3_path"); 186 | 187 | $fh = fopen($fs_path, 'w'); 188 | $curl_opts = array('CURLOPT_FILE' => $fh); 189 | 190 | if(is_null($headers)) 191 | $headers = array(); 192 | 193 | $result = $this->sendRequest($request, $headers, $curl_opts); 194 | fclose($fh); 195 | return $this->curlInfo['http_code'] == '200'; 196 | 197 | } 198 | 199 | public function getAuthenticatedURLRelative($bucket_name, $s3_path, $seconds_till_expires = 3600) 200 | { 201 | return $this->getAuthenticatedURL($bucket_name, $s3_path, gmmktime() + $seconds_till_expires); 202 | } 203 | 204 | public function getAuthenticatedURL($bucket_name, $s3_path, $expires_on) 205 | { 206 | // $expires_on must be a GMT Unix timestamp 207 | 208 | $request = array('verb' => 'GET', 'resource' => "/$bucket_name/$s3_path", 'date' => $expires_on); 209 | $signature = urlencode($this->signature($request)); 210 | 211 | $url = sprintf("http://%s.s3.amazonaws.com/%s?AWSAccessKeyId=%s&Expires=%s&Signature=%s", 212 | $bucket_name, 213 | $s3_path, 214 | $this->key, 215 | $expires_on, 216 | $signature); 217 | return $url; 218 | } 219 | 220 | private function sendRequest($request, $headers = null, $curl_opts = null) 221 | { 222 | if(is_null($headers)) 223 | $headers = array(); 224 | 225 | $headers['Date'] = $this->date; 226 | $headers['Authorization'] = 'AWS ' . $this->key . ':' . $this->signature($request, $headers); 227 | foreach($headers as $k => $v) 228 | $headers[$k] = "$k: $v"; 229 | 230 | $uri = 'http://' . $this->host . $request['resource']; 231 | $ch = curl_init(); 232 | curl_setopt($ch, CURLOPT_URL, $uri); 233 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request['verb']); 234 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 235 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 236 | // curl_setopt($ch, CURLOPT_VERBOSE, true); 237 | 238 | if(is_array($curl_opts)) 239 | { 240 | foreach($curl_opts as $k => $v) 241 | curl_setopt($ch, constant($k), $v); 242 | } 243 | 244 | $result = curl_exec($ch); 245 | $this->curlInfo = curl_getinfo($ch); 246 | curl_close($ch); 247 | return $result; 248 | } 249 | 250 | private function signature($request, $headers = null) 251 | { 252 | if(is_null($headers)) 253 | $headers = array(); 254 | 255 | $CanonicalizedAmzHeadersArr = array(); 256 | $CanonicalizedAmzHeadersStr = ''; 257 | foreach($headers as $k => $v) 258 | { 259 | $k = strtolower($k); 260 | 261 | if(substr($k, 0, 5) != 'x-amz') continue; 262 | 263 | if(isset($CanonicalizedAmzHeadersArr[$k])) 264 | $CanonicalizedAmzHeadersArr[$k] .= ',' . trim($v); 265 | else 266 | $CanonicalizedAmzHeadersArr[$k] = trim($v); 267 | } 268 | ksort($CanonicalizedAmzHeadersArr); 269 | 270 | foreach($CanonicalizedAmzHeadersArr as $k => $v) 271 | $CanonicalizedAmzHeadersStr .= "$k:$v\n"; 272 | 273 | $str = $request['verb'] . "\n"; 274 | $str .= isset($request['content-md5']) ? $request['content-md5'] . "\n" : "\n"; 275 | $str .= isset($request['content-type']) ? $request['content-type'] . "\n" : "\n"; 276 | $str .= isset($request['date']) ? $request['date'] . "\n" : $this->date . "\n"; 277 | $str .= $CanonicalizedAmzHeadersStr . preg_replace('/\?.*/', '', $request['resource']); 278 | 279 | $sha1 = $this->hasher($str); 280 | return $this->base64($sha1); 281 | } 282 | 283 | // Algorithm adapted (stolen) from http://pear.php.net/package/Crypt_HMAC/) 284 | private function hasher($data) 285 | { 286 | $key = $this->privateKey; 287 | if(strlen($key) > 64) 288 | $key = pack('H40', sha1($key)); 289 | if(strlen($key) < 64) 290 | $key = str_pad($key, 64, chr(0)); 291 | $ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64)); 292 | $opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64)); 293 | return sha1($opad . pack('H40', sha1($ipad . $data))); 294 | } 295 | 296 | private function base64($str) 297 | { 298 | $ret = ''; 299 | for($i = 0; $i < strlen($str); $i += 2) 300 | $ret .= chr(hexdec(substr($str, $i, 2))); 301 | return base64_encode($ret); 302 | } 303 | 304 | private function match($regex, $str, $i = 0) 305 | { 306 | if(preg_match($regex, $str, $match) == 1) 307 | return $match[$i]; 308 | else 309 | return false; 310 | } 311 | 312 | private $mimeTypes = array("323" => "text/h323", "acx" => "application/internet-property-stream", "ai" => "application/postscript", "aif" => "audio/x-aiff", "aifc" => "audio/x-aiff", "aiff" => "audio/x-aiff", 313 | "asf" => "video/x-ms-asf", "asr" => "video/x-ms-asf", "asx" => "video/x-ms-asf", "au" => "audio/basic", "avi" => "video/quicktime", "axs" => "application/olescript", "bas" => "text/plain", "bcpio" => "application/x-bcpio", "bin" => "application/octet-stream", "bmp" => "image/bmp", 314 | "c" => "text/plain", "cat" => "application/vnd.ms-pkiseccat", "cdf" => "application/x-cdf", "cer" => "application/x-x509-ca-cert", "class" => "application/octet-stream", "clp" => "application/x-msclip", "cmx" => "image/x-cmx", "cod" => "image/cis-cod", "cpio" => "application/x-cpio", "crd" => "application/x-mscardfile", 315 | "crl" => "application/pkix-crl", "crt" => "application/x-x509-ca-cert", "csh" => "application/x-csh", "css" => "text/css", "dcr" => "application/x-director", "der" => "application/x-x509-ca-cert", "dir" => "application/x-director", "dll" => "application/x-msdownload", "dms" => "application/octet-stream", "doc" => "application/msword", 316 | "dot" => "application/msword", "dvi" => "application/x-dvi", "dxr" => "application/x-director", "eps" => "application/postscript", "etx" => "text/x-setext", "evy" => "application/envoy", "exe" => "application/octet-stream", "fif" => "application/fractals", "flr" => "x-world/x-vrml", "gif" => "image/gif", 317 | "gtar" => "application/x-gtar", "gz" => "application/x-gzip", "h" => "text/plain", "hdf" => "application/x-hdf", "hlp" => "application/winhlp", "hqx" => "application/mac-binhex40", "hta" => "application/hta", "htc" => "text/x-component", "htm" => "text/html", "html" => "text/html", 318 | "htt" => "text/webviewhtml", "ico" => "image/x-icon", "ief" => "image/ief", "iii" => "application/x-iphone", "ins" => "application/x-internet-signup", "isp" => "application/x-internet-signup", "jfif" => "image/pipeg", "jpe" => "image/jpeg", "jpeg" => "image/jpeg", "jpg" => "image/jpeg", 319 | "js" => "application/x-javascript", "latex" => "application/x-latex", "lha" => "application/octet-stream", "lsf" => "video/x-la-asf", "lsx" => "video/x-la-asf", "lzh" => "application/octet-stream", "m13" => "application/x-msmediaview", "m14" => "application/x-msmediaview", "m3u" => "audio/x-mpegurl", "man" => "application/x-troff-man", 320 | "mdb" => "application/x-msaccess", "me" => "application/x-troff-me", "mht" => "message/rfc822", "mhtml" => "message/rfc822", "mid" => "audio/mid", "mny" => "application/x-msmoney", "mov" => "video/quicktime", "movie" => "video/x-sgi-movie", "mp2" => "video/mpeg", "mp3" => "audio/mpeg", 321 | "mpa" => "video/mpeg", "mpe" => "video/mpeg", "mpeg" => "video/mpeg", "mpg" => "video/mpeg", "mpp" => "application/vnd.ms-project", "mpv2" => "video/mpeg", "ms" => "application/x-troff-ms", "mvb" => "application/x-msmediaview", "nws" => "message/rfc822", "oda" => "application/oda", 322 | "p10" => "application/pkcs10", "p12" => "application/x-pkcs12", "p7b" => "application/x-pkcs7-certificates", "p7c" => "application/x-pkcs7-mime", "p7m" => "application/x-pkcs7-mime", "p7r" => "application/x-pkcs7-certreqresp", "p7s" => "application/x-pkcs7-signature", "pbm" => "image/x-portable-bitmap", "pdf" => "application/pdf", "pfx" => "application/x-pkcs12", 323 | "pgm" => "image/x-portable-graymap", "pko" => "application/ynd.ms-pkipko", "pma" => "application/x-perfmon", "pmc" => "application/x-perfmon", "pml" => "application/x-perfmon", "pmr" => "application/x-perfmon", "pmw" => "application/x-perfmon", "png" => "image/png", "pnm" => "image/x-portable-anymap", "pot" => "application/vnd.ms-powerpoint", "ppm" => "image/x-portable-pixmap", 324 | "pps" => "application/vnd.ms-powerpoint", "ppt" => "application/vnd.ms-powerpoint", "prf" => "application/pics-rules", "ps" => "application/postscript", "pub" => "application/x-mspublisher", "qt" => "video/quicktime", "ra" => "audio/x-pn-realaudio", "ram" => "audio/x-pn-realaudio", "ras" => "image/x-cmu-raster", "rgb" => "image/x-rgb", 325 | "rmi" => "audio/mid", "roff" => "application/x-troff", "rtf" => "application/rtf", "rtx" => "text/richtext", "scd" => "application/x-msschedule", "sct" => "text/scriptlet", "setpay" => "application/set-payment-initiation", "setreg" => "application/set-registration-initiation", "sh" => "application/x-sh", "shar" => "application/x-shar", 326 | "sit" => "application/x-stuffit", "snd" => "audio/basic", "spc" => "application/x-pkcs7-certificates", "spl" => "application/futuresplash", "src" => "application/x-wais-source", "sst" => "application/vnd.ms-pkicertstore", "stl" => "application/vnd.ms-pkistl", "stm" => "text/html", "svg" => "image/svg+xml", "sv4cpio" => "application/x-sv4cpio", 327 | "sv4crc" => "application/x-sv4crc", "t" => "application/x-troff", "tar" => "application/x-tar", "tcl" => "application/x-tcl", "tex" => "application/x-tex", "texi" => "application/x-texinfo", "texinfo" => "application/x-texinfo", "tgz" => "application/x-compressed", "tif" => "image/tiff", "tiff" => "image/tiff", 328 | "tr" => "application/x-troff", "trm" => "application/x-msterminal", "tsv" => "text/tab-separated-values", "txt" => "text/plain", "uls" => "text/iuls", "ustar" => "application/x-ustar", "vcf" => "text/x-vcard", "vrml" => "x-world/x-vrml", "wav" => "audio/x-wav", "wcm" => "application/vnd.ms-works", 329 | "wdb" => "application/vnd.ms-works", "wks" => "application/vnd.ms-works", "wmf" => "application/x-msmetafile", "wps" => "application/vnd.ms-works", "wri" => "application/x-mswrite", "wrl" => "x-world/x-vrml", "wrz" => "x-world/x-vrml", "xaf" => "x-world/x-vrml", "xbm" => "image/x-xbitmap", "xla" => "application/vnd.ms-excel", 330 | "xlc" => "application/vnd.ms-excel", "xlm" => "application/vnd.ms-excel", "xls" => "application/vnd.ms-excel", "xlt" => "application/vnd.ms-excel", "xlw" => "application/vnd.ms-excel", "xof" => "x-world/x-vrml", "xpm" => "image/x-xpixmap", "xwd" => "image/x-xwindowdump", "z" => "application/x-compress", "zip" => "application/zip"); 331 | } 332 | -------------------------------------------------------------------------------- /class.sqs.php: -------------------------------------------------------------------------------- 1 | _key = $key; 14 | $this->_secret = $secret; 15 | $this->queue_url = $queue_url; 16 | } 17 | 18 | public function createQueue($queue_name, $default_timeout = 30) 19 | { 20 | if ($default_timeout < 30) { $default_timeout = 30; } 21 | $params = array("QueueName" => $queue_name, "DefaultVisibilityTimeout" => $default_timeout); 22 | $xml = $this->go("CreateQueue", $params); 23 | if($xml === false) return false; 24 | 25 | return strval($xml->CreateQueueResult->QueueUrl); 26 | } 27 | 28 | public function listQueues($queue_name_prefix = "") 29 | { 30 | $params = ($queue_name_prefix == "") ? array() : array("QueueNamePrefix" => $queue_name_prefix); 31 | $xml = $this->go("ListQueues", $params); 32 | if($xml === false) return false; 33 | $out = array(); 34 | foreach($xml->ListQueuesResult->QueueUrl as $url) 35 | $out[] = strval($url); 36 | return $out; 37 | } 38 | 39 | public function deleteQueue($queue_url = null) 40 | { 41 | if(!isset($queue_url)) $queue_url = $this->queue_url; 42 | $xml = $this->go("DeleteQueue", null, $queue_url); 43 | return $xml ? true : false; 44 | } 45 | 46 | public function sendMessage($message_body, $queue_url = null) 47 | { 48 | if(!isset($queue_url)) $queue_url = $this->queue_url; 49 | $params = array("MessageBody" => $message_body); 50 | $xml = $this->go("SendMessage", $params, $queue_url); 51 | 52 | if($xml === false) return false; 53 | 54 | return strval($xml->SendMessageResult->MessageId); 55 | } 56 | 57 | public function receiveMessage($number = 1, $timeout = null, $queue_url = null) 58 | { 59 | if(!isset($queue_url)) $queue_url = $this->queue_url; 60 | 61 | $number = intval($number); 62 | if($number < 1) $number = 1; 63 | if($number > 256) $number = 256; 64 | 65 | $params = array(); 66 | $params['MaxNumberOfMessages'] = $number; 67 | if(isset($timeout)) $params['VisibilityTimeout'] = intval($timeout); 68 | 69 | $xml = $this->go("ReceiveMessage", $params, $queue_url); 70 | 71 | if($xml === false) return false; 72 | 73 | $out = array(); 74 | foreach($xml->ReceiveMessageResult->Message as $m) 75 | $out[] = $m; 76 | return $out; 77 | } 78 | 79 | public function deleteMessage($receipt_handle, $queue_url = null) 80 | { 81 | if(!isset($queue_url)) $queue_url = $this->queue_url; 82 | $params = array("ReceiptHandle" => $receipt_handle); 83 | $xml = $this->go("DeleteMessage", $params, $queue_url); 84 | return ($xml === false) ? false : true; 85 | } 86 | 87 | public function clearQueue($limit = 100, $queue_url) 88 | { 89 | $m = $this->receiveMessage($limit, null, $queue_url); 90 | foreach($m as $n) 91 | $this->deleteMessage($n['MessageId'], $queue_url); 92 | } 93 | 94 | public function setTimeout($timeout, $queue_url = null) 95 | { 96 | $timeout = intval($timeout); 97 | if(!isset($queue_url)) $queue_url = $this->queue_url; 98 | if(!is_int($timeout)) $timeout = 30; 99 | $params = array("Attribute.Name" => "VisibilityTimeout", "Attribute.Value" => $timeout); 100 | $xml = $this->go("SetQueueAttributes", $params, $queue_url); 101 | return ($xml === false) ? false : true; 102 | } 103 | 104 | public function getTimeout($queue_url = null) 105 | { 106 | if(!isset($queue_url)) $queue_url = $this->queue_url; 107 | $params = array("AttributeName" => "VisibilityTimeout"); 108 | $xml = $this->go("GetQueueAttributes", $params, $queue_url); 109 | return ($xml === false) ? false : strval($xml->GetQueueAttributesResult->Attribute->Value); 110 | } 111 | public function getSize($queue_url = null) 112 | { 113 | if(!isset($queue_url)) $queue_url = $this->queue_url; 114 | $params = array("AttributeName" => "ApproximateNumberOfMessages"); 115 | $xml = $this->go("GetQueueAttributes", $params, $queue_url); 116 | return ($xml === false) ? false : strval($xml->GetQueueAttributesResult->Attribute->Value); 117 | } 118 | public function setQueue($queue_url) 119 | { 120 | $this->queue_url = $queue_url; 121 | } 122 | 123 | public function go($action, $params, $url = null) 124 | { 125 | $params['Action'] = $action; 126 | 127 | if(!$url) $url = $this->_server; 128 | 129 | $params['AWSAccessKeyId'] = $this->_key; 130 | $params['SignatureVersion'] = 1; 131 | $params['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z"); 132 | $params['Version'] = "2008-01-01"; 133 | uksort($params, "strnatcasecmp"); 134 | 135 | $toSign = ""; 136 | foreach($params as $key => $val) 137 | $toSign .= $key . $val; 138 | $sha1 = $this->hasher($toSign); 139 | $sig = $this->base64($sha1); 140 | $params['Signature'] = $sig; 141 | 142 | $url .= '?'; 143 | foreach($params as $key => $val) 144 | $url .= "$key=" . urlencode($val) . "&"; 145 | 146 | $ch = curl_init($url); 147 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 148 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 149 | $xmlstr = curl_exec($ch); 150 | 151 | $xml = new SimpleXMLElement($xmlstr); 152 | 153 | return (isset($xml->Errors) || isset($xml->Error)) ? false : $xml; 154 | } 155 | 156 | public function hasher($data) 157 | { 158 | // Algorithm adapted (stolen) from http://pear.php.net/package/Crypt_HMAC/) 159 | $key = $this->_secret; 160 | if(strlen($key) > 64) 161 | $key = pack("H40", sha1($key)); 162 | if(strlen($key) < 64) 163 | $key = str_pad($key, 64, chr(0)); 164 | $ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64)); 165 | $opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64)); 166 | return sha1($opad . pack("H40", sha1($ipad . $data))); 167 | } 168 | 169 | public function base64($str) 170 | { 171 | $ret = ""; 172 | for($i = 0; $i < strlen($str); $i += 2) 173 | $ret .= chr(hexdec(substr($str, $i, 2))); 174 | return base64_encode($ret); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /examples/awisexample.php: -------------------------------------------------------------------------------- 1 | "; 23 | echo "
"; 24 | echo "
"; 25 | echo ""; 26 | die(); 27 | } 28 | 29 | $awis = new AWIS($_SESSION['AMZ_KEY'], $_SESSION['AMZ_SECRET']); 30 | $me = $_SERVER['PHP_SELF']; 31 | $bucket = $_SESSION['BUCKET']; 32 | 33 | ?> 34 | 36 | 37 | 38 | 39 | 40 | AWIS Example 41 | 53 | 54 | 55 | 56 |
57 | Key:
58 | Secret:
59 | URL: "> 60 | 61 | Logout 62 |
63 |
64 | 		urlInfo($_GET["url"],"Rank");
66 | 			print_r($info);
67 | 		}
68 | 		?>
69 | 	
70 | 71 | --------------------------------------------------------------------------------