You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP如何在派生类常量中使用前缀?图标常量类优化方案咨询

解决方案

方案1:利用静态魔术方法(兼容PHP 7.0+)

将图标名称统一存放在父类数组中,通过__getStatic魔术方法动态拼接前缀,无需重复定义每个图标:

abstract class Heroicon
{
    protected const PREFIX = "";

    // 统一维护所有图标名称
    protected const ICONS = [
        'ACADEMIC_CAP' => 'academic-cap',
        'ADJUSTMENTS' => 'adjustments',
        // ... 其他200+图标
    ];

    public static function __getStatic(string $name): ?string
    {
        return isset(static::ICONS[$name])
            ? static::PREFIX . static::ICONS[$name]
            : null;
    }
}

class HeroiconSolid extends Heroicon
{
    protected const PREFIX = "heroicon-s-";
}

class HeroiconOutline extends Heroicon
{
    protected const PREFIX = "heroicon-o-";
}

// 使用方式(注意用$访问静态属性)
echo HeroiconSolid::$ACADEMIC_CAP; // 输出 "heroicon-s-academic-cap"
echo HeroiconOutline::$ADJUSTMENTS; // 输出 "heroicon-o-adjustments"

方案2:静态构造函数生成常量(PHP 8.0+)

通过PHP 8.0新增的静态构造函数,在子类加载时自动生成带前缀的常量,保持原有的常量访问方式:

abstract class Heroicon
{
    protected const PREFIX = "";

    // 统一维护所有图标名称
    protected const ICONS = [
        'ACADEMIC_CAP' => 'academic-cap',
        'ADJUSTMENTS' => 'adjustments',
        // ... 其他200+图标
    ];
}

class HeroiconSolid extends Heroicon
{
    protected const PREFIX = "heroicon-s-";

    public static function __constructStatic()
    {
        foreach (static::ICONS as $constName => $iconName) {
            // 动态定义子类常量
            define(__CLASS__ . "::{$constName}", static::PREFIX . $iconName);
        }
    }
}

class HeroiconOutline extends Heroicon
{
    protected const PREFIX = "heroicon-o-";

    public static function __constructStatic()
    {
        foreach (static::ICONS as $constName => $iconName) {
            define(__CLASS__ . "::{$constName}", static::PREFIX . $iconName);
        }
    }
}

// 使用方式(原常量访问方式不变)
echo HeroiconSolid::ACADEMIC_CAP; // 输出 "heroicon-s-academic-cap"
echo HeroiconOutline::ADJUSTMENTS; // 输出 "heroicon-o-adjustments"

方案3:枚举实现(PHP 8.1+)

利用PHP 8.1的枚举特性,每个枚举对应一种图标类型,通过方法统一添加前缀:

interface HeroiconInterface
{
    public function get(): string;
}

enum HeroiconSolid: string implements HeroiconInterface
{
    case ACADEMIC_CAP = 'academic-cap';
    case ADJUSTMENTS = 'adjustments';
    // ... 其他200+图标

    public function get(): string
    {
        return 'heroicon-s-' . $this->value;
    }
}

enum HeroiconOutline: string implements HeroiconInterface
{
    case ACADEMIC_CAP = 'academic-cap';
    case ADJUSTMENTS = 'adjustments';
    // ... 其他200+图标

    public function get(): string
    {
        return 'heroicon-o-' . $this->value;
    }
}

// 使用方式
echo HeroiconSolid::ACADEMIC_CAP->get(); // 输出 "heroicon-s-academic-cap"
echo HeroiconOutline::ADJUSTMENTS->get(); // 输出 "heroicon-o-adjustments"

注:方案3需要手动复制图标case,但枚举自带类型校验,适合对类型安全有要求的场景;方案1和2只需在父类维护一次图标列表,更符合你避免重复代码的需求。

内容的提问来源于stack exchange,提问作者Gabor Knyihar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:17