Files
lgp-admin-plus-api/app/Service/common/upload/ObjectListXmlTrait.php
LQ bcf54c2727 初始化
缺陷:主题配色需要优化整体的同风格
2026-08-14 23:21:21 +08:00

65 lines
2.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Service\common\upload;
use App\Service\common\UtilsService;
/**
* ListBucketResult 解析
*
* 阿里云 GET Bucket、腾讯云 GET Bucket、S3 ListObjectsV2 回的都是同一套
* <ListBucketResult><Contents>… 结构只有续拉游标的节点名不同NextMarker /
* NextContinuationToken。三个驱动共用本 trait避免同一段 XML 遍历写三遍。
* 使用方需要有 $this->config 以及 ObjectKeyNormalizeTrait 提供的 key 规整方法。
*/
trait ObjectListXmlTrait
{
/**
* @param string $xml 响应体
* @param string $urlBase 未配置 domain 时兜底拼地址用的主机前缀(不带尾斜杠)
* @param string $tokenNode 续拉游标节点名
* @return array{items: array<int, array{key:string,size:int,hash:string,last_modified:int,url:string}>, next_marker: string, finished: bool}
*/
protected function parseObjectListXml(string $xml, string $urlBase, string $tokenNode = 'NextMarker'): array
{
$doc = @simplexml_load_string($xml);
if ($doc === false) {
UtilsService::getInstance()->errorThrow('列举结果解析失败,返回内容不是合法 XML');
}
$items = [];
$lastRawKey = '';
$contents = isset($doc->Contents) ? $doc->Contents : [];
foreach ($contents as $node) {
$rawKey = (string) $node->Key;
// 续拉游标必须用服务端原样返回的 key不能用补过 prefix 的规整值
$lastRawKey = $rawKey;
$key = $this->normalizeObjectKey($rawKey);
if ($key === '' || str_ends_with($key, '/')) {
// 以 / 结尾的是控制台建目录留下的占位对象,不是素材
continue;
}
$items[] = [
'key' => $key,
'size' => (int) $node->Size,
'hash' => strtolower(trim((string) $node->ETag, '"')),
'last_modified' => (int) strtotime((string) $node->LastModified),
'url' => $this->publicUrlOf($key, $urlBase . '/' . $key),
];
}
$truncated = filter_var((string) ($doc->IsTruncated ?? 'false'), FILTER_VALIDATE_BOOLEAN);
$next = isset($doc->{$tokenNode}) ? (string) $doc->{$tokenNode} : '';
if ($truncated && $next === '' && $tokenNode === 'NextMarker') {
// 部分兼容实现只给 IsTruncated 不给 NextMarker按协议可用本页最后一个 key 续拉
$next = $lastRawKey;
}
return [
'items' => $items,
'next_marker' => $truncated ? $next : '',
'finished' => !$truncated || $next === '',
];
}
}