PHP 8.3 枚举用于视频分类管理

发布: (2026年3月8日 GMT+8 23:00)
4 分钟阅读
原文: Dev.to

抱歉,我需要您提供要翻译的具体文本内容(除代码块、URL 和标题之外的正文),才能为您进行翻译。请把文章的正文粘贴在这里,我会保持原有的 Markdown 格式并将其翻译成简体中文。

使用枚举进行分类

枚举之前(脆弱,缺乏类型安全)

// Before: fragile, no type safety
class Categories {
    const MUSIC = 'music';
    const GAMING = 'gaming';
    const ENTERTAINMENT = 'entertainment';
}

function getVideos(string $category): array { /* ... */ }

getVideos('musci'); // Typo compiles fine, fails silently

枚举之后(类型安全,IDE 支持,穷尽匹配)

// After: type-safe, IDE support, exhaustive matching
enum Category: string {
    case Music = 'music';
    case Gaming = 'gaming';
    case Entertainment = 'entertainment';
}

function getVideos(Category $category): array { /* ... */ }

getVideos(Category::Music); // Type-safe

映射 YouTube 类别 ID

enum VideoCategory: int {
    case FilmAnimation   = 1;
    case AutosVehicles   = 2;
    case Music           = 10;
    case PetsAnimals     = 15;
    case Sports          = 17;
    case ShortMovies     = 18;
    case TravelEvents    = 19;
    case Gaming          = 20;
    case Videoblogging   = 21;
    case PeopleBlogs     = 22;
    case Comedy          = 23;
    case Entertainment   = 24;
    case NewsPolitics    = 25;
    case HowtoStyle      = 26;
    case Education       = 27;
    case ScienceTech     = 28;
    case NonprofitsActivism = 29;
    case Movies          = 30;
    case AnimeAnimation  = 31;
    case ActionAdventure = 32;
    case Classics        = 33;
    case Documentary     = 35;
    case Shorts          = 42;

    public function label(): string {
        return match($this) {
            self::FilmAnimation   => 'Film & Animation',
            self::Music           => 'Music',
            self::Gaming          => 'Gaming',
            self::Entertainment   => 'Entertainment',
            self::NewsPolitics    => 'News & Politics',
            self::ScienceTech     => 'Science & Tech',
            self::HowtoStyle      => 'How-to & Style',
            self::Education       => 'Education',
            self::Comedy          => 'Comedy',
            self::Sports          => 'Sports',
            self::PeopleBlogs     => 'People & Blogs',
            default                => $this->name,
        };
    }

    public function slug(): string {
        return strtolower(preg_replace('/[^a-z0-9]+/i', '-', $this->label()));
    }

    public function icon(): string {
        return match($this) {
            self::Music           => 'music-note',
            self::Gaming          => 'gamepad',
            self::Entertainment   => 'star',
            self::NewsPolitics    => 'newspaper',
            self::ScienceTech     => 'flask',
            self::Sports          => 'trophy',
            default                => 'play-circle',
        };
    }

    /**
     * Categories displayed in the navigation bar.
     */
    public static function navCategories(): array {
        return [
            self::Music,
            self::Gaming,
            self::Entertainment,
            self::NewsPolitics,
            self::ScienceTech,
            self::Sports,
            self::HowtoStyle,
            self::Education,
            self::Comedy,
            self::PeopleBlogs,
        ];
    }
}

区域枚举

enum Region: string {
    case US = 'US';
    case GB = 'GB';
    case JP = 'JP';
    case KR = 'KR';
    case TW = 'TW';
    case SG = 'SG';
    case VN = 'VN';
    case TH = 'TH';
    case HK = 'HK';

    public function label(): string {
        return match($this) {
            self::US => 'United States',
            self::GB => 'United Kingdom',
            self::JP => 'Japan',
            self::KR => 'South Korea',
            self::TW => 'Taiwan',
            self::SG => 'Singapore',
            self::VN => 'Vietnam',
            self::TH => 'Thailand',
            self::HK => 'Hong Kong',
        };
    }

    public function flag(): string {
        // Convert country code to flag emoji
        $chars = str_split($this->value);
        return implode('', array_map(
            fn(string $c) => mb_chr(ord($c) - ord('A') + 0x1F1E6),
            $chars
        ));
    }

    public function hreflang(): string {
        return match($this) {
            self::JP => 'ja',
            self::KR => 'ko',
            self::TW => 'zh-TW',
            self::HK => 'zh-HK',
            self::VN => 'vi',
            self::TH => 'th',
            default  => 'en',
        };
    }
}

完全匹配示例

// 此匹配是完整的 — 添加一个新的 Region case
// 并且 PHP 会警告所有未处理的匹配
function cronInterval(Region $region): string {
    return match($region) {
        Region::US, Region::GB => '*/2 * * * *',
        Region::JP, Region::KR => '*/3 * * * *',
        Region::TW, Region::SG, Region::HK => '*/4 * * * *',
        Region::VN, Region::TH => '*/6 * * * *',
    };
}

缓存配置的类型化常量

class CacheConfig {
    const int    HOME_TTL     = 10800;
    const int    WATCH_TTL    = 21600;
    const int    SEARCH_TTL   = 600;
    const int    CATEGORY_TTL = 86400;
    const string CACHE_DIR    = 'data/pagecache';
}

类型化常量与枚举配合得很好,能够防止意外的类型不匹配,消除整类错误——例如地区代码的拼写错误、无效的分类 ID,以及错误配置的缓存策略。如果你使用的是 PHP 8.1 及以上版本,就没有理由不采用它们。

0 浏览
Back to Blog

相关文章

阅读更多 »