'integer', 'oss_config_id' => 'integer', 'folder_id' => 'integer', 'type' => 'integer', 'size' => 'integer', 'width' => 'integer', 'height' => 'integer', 'ref_count' => 'integer', 'last_scan_at' => 'integer', 'source' => 'integer', ]; /** * 从对象键取出能落库的扩展名(小写、不带点、最长 20) * * 七牛历史上会把处理参数写进文件名: * b_xxx.jpeg~tplv-a9rns2rl98-downsize_watermark_1_5 * pathinfo 会把整段 ~ 后面都当成扩展名,varchar(20) 直接截断报错, * 整批 insert 跟着失败。这里先剥查询串和 ~ 后缀,再取真正的后缀。 * 微信保存的 .pic / .pic_hd 按 jpg 认,否则会被打成「其他」。 */ public static function extOfKey(string $key): string { $name = basename(str_replace('\\', '/', $key)); $cut = strpbrk($name, '?~#'); if ($cut !== false) { $name = substr($name, 0, strlen($name) - strlen($cut)); } $ext = strtolower(trim((string) pathinfo($name, PATHINFO_EXTENSION), " \t\n\r\0\x0B.")); if ($ext === 'pic' || $ext === 'pic_hd') { return 'jpg'; } return $ext === '' ? '' : substr($ext, 0, 20); } /** * 扩展名归类到 type * * 从 OSS 反向同步时手上只有对象键,没有上传时的 MIME,只能按扩展名判断 */ public static function typeOfExt(string $ext): int { return match (strtolower(trim($ext, " \t\n\r\0\x0B."))) { 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'ico', 'avif', 'heic', 'pic', 'pic_hd' => self::TYPE_IMAGE, 'mp4', 'mov', 'avi', 'mkv', 'flv', 'wmv', 'webm', 'm3u8', 'ts' => self::TYPE_VIDEO, 'mp3', 'wav', 'aac', 'flac', 'ogg', 'm4a', 'amr' => self::TYPE_AUDIO, 'xls', 'xlsx', 'csv' => self::TYPE_EXCEL, 'zip', 'rar', '7z', 'tar', 'gz', 'bz2' => self::TYPE_ARCHIVE, 'pdf', 'doc', 'docx', 'ppt', 'pptx', 'txt', 'md' => self::TYPE_DOCUMENT, default => self::TYPE_OTHER, }; } }