Files
lgp-admin-plus-api/app/Service/common/upload/ObjectKeyNormalizeTrait.php
2026-08-19 08:16:49 +08:00

76 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;
/**
* 对象键规整
*
* 上传用 normalizeObjectKey(可补 path_prefix),
* 列举 / 删除用 normalizeListedKey(只压斜杠,用服务端真实 key)。
* 使用方需要有 $this->config(由 OssRuntimeConfigService 注入,含 path_prefix / domain)。
*/
trait ObjectKeyNormalizeTrait
{
/**
* 压平重复斜杠,不补 path_prefix
*
* 列举结果必须走这里:OSS 回的 key 就是对象真实路径。
* 若再套一层 path_prefix,根目录的历史文件(如 b_xxx.jpg)会被改写成
* uploads/b_xxx.jpg,素材库入库地址全 404。
*/
protected function normalizeListedKey(string $key): string
{
return ltrim((string) preg_replace('#/{2,}#', '/', trim($key)), '/');
}
/**
* 上传 / 删除用:缺 path_prefix 时补上,并压平重复斜杠
*
* 为什么必须压平:uploads//spa/a.jpg 与 uploads/spa/a.jpg 在 OSS 上是两个对象,
* 但拼出来的访问地址会被 CDN 归一成同一个。素材库按 path 建索引,
* 不统一就会落成两条记录,回收删掉其中一条后另一条变成指向已删对象的幽灵。
*/
protected function normalizeObjectKey(string $key): string
{
$key = $this->normalizeListedKey($key);
if ($key === '') {
return '';
}
$prefix = trim((string) ($this->config['path_prefix'] ?? ''), '/');
if ($prefix !== '' && $key !== $prefix && !str_starts_with($key, $prefix . '/')) {
$key = $prefix . '/' . $key;
}
return $key;
}
/**
* 列举前缀:只认调用方传入的值,留空 = 扫整个 Bucket
*
* 以前空前缀会偷偷套配置里的 path_prefix。种子数据把七牛写成 uploads,
* 而本站历史文件都在根目录(b_*.jpg),一拉就是空列表。
* 素材库文案也是「留空表示整个 Bucket」,这里必须跟文案一致;
* 要收窄范围请在同步抽屉里显式填前缀。
*/
protected function scopedListPrefix(string $prefix): string
{
return $this->normalizeListedKey($prefix);
}
/**
* 拼公开访问地址;未配置 domain 时回落到调用方给的默认地址
*/
protected function publicUrlOf(string $key, string $fallback = ''): string
{
$domain = rtrim((string) ($this->config['domain'] ?? ''), '/');
return $domain !== '' ? $domain . '/' . $key : $fallback;
}
/**
* 单页列举条数收口,避免上游把 limit 传成 0 或者十万
*/
protected function boundedLimit(int $limit): int
{
return max(1, min($limit, 1000));
}
}