本人近期在使用天翼云部署一个 PHP 开发的系统时,在使用 aws-sdk-php 向天翼云对象存储发起STS临时凭证请求时,遇到了如下报错:
Fatal error: Uncaught Aws\Api\Parser\Exception\ParserException: Invalid timestamp value passed to DateTimeResult::fromTimestamp in /data/htdocs/myapp/vendor/aws/aws-sdk-php/src/Api/DateTimeResult.php:100
经过对 aws-sdk-php 源代码进行分析后,决定自己动手进行一些改造,让 aws-sdk-php 兼容天翼云,具体方法如下:
第一步,在 /vendor/aws/aws-sdk-php/src/Api/DateTimeResult.php 中新增一个方法,代码如下:
public static function rectificationTimestamp($timestamp) { if (strpos($timestamp, ".") > 0 && strpos($timestamp, "Z") > 0) { $startIndex = strpos($timestamp, ".") + 1; $endIndex = strpos($timestamp, "Z") + 1; if ($endIndex - $startIndex - 1 > 6) { $timestamp = substr($timestamp, 0, $startIndex + 6) . 'Z'; } } return $timestamp; }
第二步,在 fromTimestamp 方法中调用,例如:
public static function fromTimestamp($timestamp, $expectedFormat = null) { if (empty($timestamp)) { return self::fromEpoch(0); } // 这里调用 rectificationTimestamp 方法 $timestamp = self::rectificationTimestamp($timestamp); if (!(is_string($timestamp) || is_numeric($timestamp))) { throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp'); } try { if ($expectedFormat == 'iso8601') { try { return self::fromISO8601($timestamp); } catch (Exception $exception) { return self::fromEpoch($timestamp); } } else if ($expectedFormat == 'unixTimestamp') { try { return self::fromEpoch($timestamp); } catch (Exception $exception) { return self::fromISO8601($timestamp); } } else if (\Aws\is_valid_epoch($timestamp)) { return self::fromEpoch($timestamp); } return self::fromISO8601($timestamp); } catch (Exception $exception) { throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp'); } }
通过上述改造,经过反复测试,已经可以正常向天翼云请求获取到 STS 临时凭证的信息。通过分析,应该是天翼云的对象存储返回的时间格式有些问题,导致 aws-sdk-php 无法正常解析,相关问题已经反馈给天翼云,但尚未解决,只好自己动手修改 aws-sdk-php 的源代码来做个兼容。
阳光部落原创,更多内容请访问http://www.sunbloger.com/