diff --git a/sample/selectObjectContent.php b/sample/selectObjectContent.php new file mode 100644 index 00000000..61fd4e94 --- /dev/null +++ b/sample/selectObjectContent.php @@ -0,0 +1,54 @@ + $region, + 'schema' => 'https', //协议头部,默认为http + 'credentials'=> array( + 'secretId' => $secretId , + 'secretKey' => $secretKey + ) +)); +try { + $result = $cosClient->selectObjectContent(array( + 'Bucket' => $bucket, //格式:BucketName-APPID + 'Key' => $key, + 'Expression' => 'Select * from COSObject s', + 'ExpressionType' => 'SQL', + 'InputSerialization' => array( + 'CompressionType' => 'None', + 'CSV' => array( + 'FileHeaderInfo' => 'NONE', + 'RecordDelimiter' => '\n', + 'FieldDelimiter' => ',', + 'QuoteEscapeCharacter' => '"', + 'Comments' => '#', + 'AllowQuotedRecordDelimiter' => 'FALSE' + ) + ), + 'OutputSerialization' => array( + 'CSV' => array( + 'QuoteField' => 'ASNEEDED', + 'RecordDelimiter' => '\n', + 'FieldDelimiter' => ',', + 'QuoteCharacter' => '"', + 'QuoteEscapeCharacter' => '"' + ) + ), + 'RequestProgress' => array( + 'Enabled' => 'FALSE' + ) + )); + // 请求成功 + foreach ($result['Data'] as $data) { + // 迭代遍历select结果 + print_r($data); + } +} catch (\Exception $e) { + // 请求失败 + echo($e); +} diff --git a/src/Qcloud/Cos/Client.php b/src/Qcloud/Cos/Client.php index b698ab0b..c8ac51ef 100644 --- a/src/Qcloud/Cos/Client.php +++ b/src/Qcloud/Cos/Client.php @@ -21,12 +21,14 @@ class Client extends GuzzleClient { - const VERSION = '2.0.6'; + const VERSION = '2.0.7'; public $httpClient; private $api; private $desc; + private $action; + private $operation; private $cosConfig; private $signature; private $rawCosConfig; @@ -81,9 +83,9 @@ public function __construct($cosConfig) { public function commandToRequestTransformer(CommandInterface $command) { - $action = $command->GetName(); - $opreation = $this->api[$action]; - $transformer = new CosTransformer($this->cosConfig, $opreation); + $this->action = $command->GetName(); + $this->operation = $this->api[$this->action]; + $transformer = new CommandToRequestTransformer($this->cosConfig, $this->operation); $seri = new Serializer($this->desc); $request = $seri($command); $request = $transformer->bucketStyleTransformer($command, $request); @@ -96,36 +98,17 @@ public function commandToRequestTransformer(CommandInterface $command) public function responseToResultTransformer(ResponseInterface $response, RequestInterface $request, CommandInterface $command) { - $action = $command->getName(); - if ($action == "GetObject") { - if (isset($command['SaveAs'])) { - $fp = fopen($command['SaveAs'], "wb"); - fwrite($fp, $response->getBody()); - fclose($fp); - } - } + $transformer = new ResultTransformer($this->cosConfig, $this->operation); + $transformer->writeDataToLocal($command, $request, $response); $deseri = new Deserializer($this->desc, true); - $rsp = $deseri($response, $request, $command); + $result = $deseri($response, $request, $command); - $headers = $response->getHeaders(); - $metadata = array(); - foreach ($headers as $key => $value) { - if (strpos($key, "x-cos-meta-") === 0) { - $metadata[substr($key, 11)] = $value[0]; - } - } - if (!empty($metadata)) { - $rsp['Metadata'] = $metadata; - } - if ($command['Key'] != null && $rsp['Key'] == null) { - $rsp['Key'] = $command['Key']; - } - if ($command['Bucket'] != null && $rsp['Bucket'] == null) { - $rsp['Bucket'] = $command['Bucket']; - } - $rsp['Location'] = $request->getHeader("Host")[0] . $request->getUri()->getPath(); - return $rsp; + $result = $transformer->metaDataTransformer($command, $response, $result); + $result = $transformer->extraHeadersTransformer($command, $request, $result); + $result = $transformer->selectContentTransformer($command, $result); + return $result; } + public function __destruct() { } @@ -264,7 +247,7 @@ public function doesObjectExist($bucket, $key, array $options = array()) return False; } } - + public static function explodeKey($key) { // Remove a leading slash if one is found $split_key = explode('/', $key && $key[0] == '/' ? substr($key, 1) : $key); diff --git a/src/Qcloud/Cos/CommandToRequestTransformer.php b/src/Qcloud/Cos/CommandToRequestTransformer.php new file mode 100644 index 00000000..e39b7a0c --- /dev/null +++ b/src/Qcloud/Cos/CommandToRequestTransformer.php @@ -0,0 +1,162 @@ +config = $config; + $this->operation = $operation; + } + + // format bucket style + public function bucketStyleTransformer(CommandInterface $command, RequestInterface $request) { + $action = $command->getName(); + if ($action == 'ListBuckets') { + return $request->withUri(new Uri($this->config['schema']."://service.cos.myqcloud.com/")); + } + $operation = $this->operation; + $bucketname = $command['Bucket']; + + $appId = $this->config['appId']; + if ($appId != null && endWith($bucketname, '-'.$appId) == False) + { + $bucketname = $bucketname.'-'.$appId; + } + $command['Bucket'] = $bucketname; + $path = ''; + $http_method = $operation['httpMethod']; + $uri = $operation['uri']; + + // Hoststyle is used by default + // Pathstyle + if ($this->config['pathStyle'] != true) { + if (isset($operation['parameters']['Bucket']) && $command->hasParam('Bucket')) { + $uri = str_replace("{Bucket}", '', $uri); + } + if (isset($operation['parameters']['Key']) && $command->hasParam('Key')) { + $uri = str_replace("{/Key*}", encodeKey($command['Key']), $uri); + } + } + $origin_host = $bucketname. '.cos.' . $this->config['region'] . '.' . $this->config['endpoint']; + // domain + if ($this->config['domain'] != null) { + $origin_host = $this->config['domain']; + } + $host = $origin_host; + if ($this->config['ip'] != null) { + $host = $this->config['ip']; + if ($this->config['port'] != null) { + $host = $this->config['ip'] . ":" . $this->config['port']; + } + } + + + $path = $this->config['schema'].'://'. $host . $uri; + $uri = new Uri($path); + $query = $request->getUri()->getQuery(); + if ($uri->getQuery() != $query && $uri->getQuery() != "") { + $query = $uri->getQuery() . "&" . $request->getUri()->getQuery(); + } + $uri = $uri->withQuery($query); + $request = $request->withUri($uri); + $request = $request->withHeader('Host', $origin_host); + return $request; + } + + // format upload body + public function uploadBodyTransformer(CommandInterface $command, $request, $bodyParameter = 'Body', $sourceParameter = 'SourceFile') { + + $operation = $this->operation; + if (!isset($operation['parameters']['Body'])) { + return $request; + } + $source = isset($command[$sourceParameter]) ? $command[$sourceParameter] : null; + $body = isset($command[$bodyParameter]) ? $command[$bodyParameter] : null; + // If a file path is passed in then get the file handle + if (is_string($source) && file_exists($source)) { + $body = fopen($source, 'rb'); + } + // Prepare the body parameter and remove the source file parameter + if (null !== $body) { + return $request; + } else { + throw new InvalidArgumentException( + "You must specify a non-null value for the {$bodyParameter} or {$sourceParameter} parameters."); + } + } + + // update md5 + public function md5Transformer(CommandInterface $command, $request) { + $operation = $this->operation; + if (isset($operation['data']['contentMd5'])) { + $request = $this->addMd5($request); + } + if (isset($operation['parameters']['ContentMD5']) && + isset($command['ContentMD5'])) { + $value = $command['ContentMD5']; + if ($value === true) { + $request = $this->addMd5($request); + } + } + + return $request; + } + + // add meta + public function metadataTransformer(CommandInterface $command, $request) { + $operation = $this->operation; + if (isset($command['Metadata'])) { + $meta = $command['Metadata']; + foreach ($meta as $key => $value) { + $request = $request->withHeader('x-cos-meta-' . $key, $value); + } + } + return $request; + } + + // count md5 + private function addMd5($request) { + $body = $request->getBody(); + if ($body && $body->getSize() > 0) { + $md5 = base64_encode(md5($body, true)); + return $request->withHeader('Content-MD5', $md5); + } + return $request; + } + + // inventoryId + public function specialParamTransformer(CommandInterface $command, $request) { + $action = $command->getName(); + if ($action == 'PutBucketInventory') { + $id = $command['Id']; + $uri = $request->getUri(); + $query = $uri->getQuery(); + $uri = $uri->withQuery($query . "&Id=".$id); + return $request->withUri($uri); + } + return $request; + } + + public function __destruct() { + } + +} diff --git a/src/Qcloud/Cos/ResultTransformer.php b/src/Qcloud/Cos/ResultTransformer.php new file mode 100644 index 00000000..02afc84c --- /dev/null +++ b/src/Qcloud/Cos/ResultTransformer.php @@ -0,0 +1,119 @@ +config = $config; + $this->operation = $operation; + } + + public function writeDataToLocal(CommandInterface $command, RequestInterface $request, ResponseInterface $response) { + $action = $command->getName(); + if ($action == "GetObject") { + if (isset($command['SaveAs'])) { + $fp = fopen($command['SaveAs'], "wb"); + fwrite($fp, $response->getBody()); + fclose($fp); + } + } + } + + public function metaDataTransformer(CommandInterface $command, ResponseInterface $response, Result $result) { + $headers = $response->getHeaders(); + $metadata = array(); + foreach ($headers as $key => $value) { + if (strpos($key, "x-cos-meta-") === 0) { + $metadata[substr($key, 11)] = $value[0]; + } + } + if (!empty($metadata)) { + $result['Metadata'] = $metadata; + } + return $result; + } + + public function extraHeadersTransformer(CommandInterface $command, RequestInterface $request, Result $result) { + if ($command['Key'] != null && $result['Key'] == null) { + $result['Key'] = $command['Key']; + } + if ($command['Bucket'] != null && $result['Bucket'] == null) { + $result['Bucket'] = $command['Bucket']; + } + $result['Location'] = $request->getHeader("Host")[0] . $request->getUri()->getPath(); + return $result; + } + + public function selectContentTransformer(CommandInterface $command, Result $result) { + $action = $command->getName(); + if ($action == "SelectObjectContent") { + $result['Data'] = $this->getSelectContents($result); + } + return $result; + } + + public function getSelectContents($result) { + $f = $result['RawData']; + while (!$f->eof()) { + $data = array(); + $tmp = $f->read(4); + if (empty($tmp)) { + break; + } + $totol_length = (int)(unpack("N", $tmp)[1]); + $headers_length = (int)(unpack("N", $f->read(4))[1]); + $body_length = $totol_length - $headers_length - 16; + $predule_crc = (int)(unpack("N", $f->read(4))[1]); + $headers = array(); + for ($offset = 0; $offset < $headers_length;) { + $key_length = (int)(unpack("C", $f->read(1))[1]); + $key = $f->read($key_length); + + $head_value_type = (int)(unpack("C", $f->read(1))[1]); + + $value_length = (int)(unpack("n", $f->read(2))[1]); + $value = $f->read($value_length); + $offset += 4 + $key_length + $value_length; + if ($key == ":message-type") { + $data['MessageType'] = $value; + } + if ($key == ":event-type") { + $data['EventType'] = $value; + } + if ($key == ":error-code") { + $data['ErrorCode'] = $value; + } + if ($key == ":error-message") { + $data['ErrorMessage'] = $value; + } + } + $body = $f->read($body_length); + $message_crc = (int)(unpack("N", $f->read(4))[1]); + $data['Body'] = $body; + yield $data; + } + } + public function __destruct() { + } + +} diff --git a/src/Qcloud/Cos/Service.php b/src/Qcloud/Cos/Service.php index 69adbf4e..ffd3a3e0 100644 --- a/src/Qcloud/Cos/Service.php +++ b/src/Qcloud/Cos/Service.php @@ -4243,7 +4243,7 @@ public static function getService() { 'Parts' => array( 'type' => 'array', 'location' => 'xml', - 'sentAs' => 'Parts', + 'sentAs' => 'Part', 'data' => array( 'xmlFlattened' => true ), @@ -4827,7 +4827,7 @@ public static function getService() { 'type' => 'object', 'additionalProperties' => true, 'properties' => array( - 'Data' => array( + 'RawData' => array( 'type' => 'string', 'instanceOf' => 'GuzzleHttp\\Psr7\\Stream', 'location' => 'body',