本人近期在使用天翼云部署一个 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/