乐趣区

关于php:php阿里云osssdk上传失败情况处理

景象

oss 上传没有胜利,然而拿到了地址,导致拜访时返回 404 状态码

思路

咱们先看本人写的上传 oss 局部代码

public function oss(string $file, string $object)
{$ossClient = new OssClient($this->config['accessKeyId'], $this->config['accessKeySecret'], $this->config['endpoint']);
    $result    = $ossClient->uploadFile($this->config['bucket'], ltrim($object, '/'), $file);
    return $result['oss-request-url'];
}

按理说是由 sdk 返回的 result 中拿到的地址,上传失败应该会间接抛出异样
再看其中 uploadFile 代码局部

public function uploadFile($bucket, $object, $file, $options = NULL)
{
    // ... 省略代码
    $response = $this->auth($options);
    $result = new PutSetDeleteResult($response);
    return $result->getData();}

其中次要办法是$this->auth($options),再进去看

private function auth($options)
{
    // ... 省略代码

    try {$request->send_request();
    } catch (RequestCore_Exception $e) {throw(new OssException('RequestCoreException:' . $e->getMessage()));
    }
    $response_header = $request->get_response_header();
    $response_header['oss-request-url'] = $requestUrl;
    $response_header['oss-redirects'] = $this->redirects;
    $response_header['oss-stringtosign'] = $string_to_sign;
    $response_header['oss-requestheaders'] = $request->request_headers;

    $data = new ResponseCore($response_header, $request->get_response_body(), $request->get_response_code());
    //retry if OSS Internal Error
    if ((integer)$request->get_response_code() === 500) {if ($this->redirects <= $this->maxRetries) {
            //Sets the sleep time betwen each retry.
            $delay = (integer)(pow(4, $this->redirects) * 100000);
            usleep($delay);
            $this->redirects++;
            $data = $this->auth($options);
        }
    }
    
    $this->redirects = 0;
    return $data;
}

能够看到抛异常情况只在 send_request 办法,而外面只在 curl 自身无奈申请(比方 host 无奈解析)才会抛出 RequestCore_Exception 异样
也就是说如果是业务类的谬误是会失常走上来的
尽管 response_code 为 500 时会有重试,然而在这之前曾经创立了 response 对象
如果非 500 谬误,或者超过重试次数都会返回这个对象,最终状况就是不论怎么样都会返回 result 构造体

解决

在拿到 result 构造体后先进行 response_code 判断,代码如下

public function oss(string $file, string $object)
{$ossClient = new OssClient($this->config['accessKeyId'], $this->config['accessKeySecret'], $this->config['endpoint']);
    $result    = $ossClient->uploadFile($this->config['bucket'], ltrim($object, '/'), $file);
    if ($result['info']['http_code'] !== 200) {throw new OssException('上传失败');
    }
    return $result['oss-request-url'];
}

补充

查阅了官网示例也没有对这些状况进行解决,示例如下:
地址:https://help.aliyun.com/docum…

// ... 省略代码
try{$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

    $ossClient->uploadFile($bucket, $object, $filePath);
} catch(OssException $e) {printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . "OK" . "\n");

附上文档中其余错误码阐明,文档链接:https://help.aliyun.com/docum…

错误码 HTTP 状态码 形容
MissingContentLength 411 申请头没有采纳 chunked encoding 编码方式,或没有设置 Content-Length 参数。
InvalidEncryptionAlgorithmError 400 指定 x -oss-server-side-encryption 的值有效。取值:AES256、KMS 或 SM4。
AccessDenied 403 增加 Object 时,用户对设置的 Bucket 没有拜访权限。
NoSuchBucket 404 增加 Object 时,设置的 Bucket 不存在。
InvalidObjectName 400 传入的 Object key 长度大于 1023 字节。
InvalidArgument 400 返回该谬误的可能起因如下:增加的 Object 大小超过 5 GB。x-oss-storage-class等参数的值有效。
RequestTimeout 400 指定了Content-Length,但没有发送音讯体,或者发送的音讯体小于指定的大小。此种状况下服务器会始终期待,直至申请超时。
Bad Request 400 在申请中指定 Content-MD5 后,OSS 会计算所发送数据的 MD5 值,并与申请中 Conent-MD5 的值进行比拟。如果二者不统一,则返回该谬误。
KmsServiceNotEnabled 403 x-oss-server-side-encryption 指定为 KMS,但没有事后购买 KMS 套件。
FileAlreadyExists 409 当申请的 Header 中携带 x-oss-forbid-overwrite=true 时,示意禁止笼罩同名文件。如果同名文件已存在,则返回该谬误。
FileImmutable 409 Bucket 中的数据处于被爱护状态时,如果尝试删除或批改相应数据,则返回该谬误。
退出移动版