PHP5 中枚举类型的替代方案?

发布于 2024-07-29 07:34:02 字数 1058 浏览 5 评论 0原文

我有一个 PHP5 对象将消息传递给另一个对象,并且想为每条消息附加一个类型。 例如,MSG_HOTMSG_WARMMSG_COLD。 如果 PHP5 有枚举类型,我可能会用它来定义消息类型,但是(除非我弄错了)没有这样的动物。 我研究了几个选项:

字符串('MSG_HOT''MSG_WARM''MSG_COLD')很糟糕,因为我会不可避免地要输入像 'MSG_WRAM' 这样的东西,事情就会崩溃。 数字也面临着同样的问题,而且也不太清晰。

定义工作:

define('MSG_HOT', 1);
define('MSG_WARM', 2);
define('MSG_COLD', 3);

但会污染全局命名空间,因此需要更详细的名称来确保唯一性。 我不希望我的代码中充满诸如 APPLICATIONNAME_MESSAGES_TYPE_HOT 之类的内容。

最后,我可以使用类名来区分类型,如下所示:

class MessageHot extends Message {}
class MessageWarm extends Message {}
class MessageCold extends Message {}
class Message
{
    public function Type()
    {
        return get_class($this);
    }
    public function Data()
    {
        return $this->data;
    }
    public function __construct($data)
    {
        $this->data = $data;
    }
    private $data;
}

我认为这很好,但对于看起来应该是一个简单的概念来说,这也需要做很多工作。

我错过了更好的选择吗?

I have one PHP5 object passing messages to another, and would like to attach a type to each message. For example, MSG_HOT, MSG_WARM, and MSG_COLD. If PHP5 had an enum type, I would probably use that to define the message types, but (unless I'm mistaken) there is no such animal. I've looked at a few options:

Strings ('MSG_HOT', 'MSG_WARM', and 'MSG_COLD') are bad because I would inevitably type something like 'MSG_WRAM' and things would break. Numbers suffer the same problem and are also less clear.

Defines work:

define('MSG_HOT', 1);
define('MSG_WARM', 2);
define('MSG_COLD', 3);

but pollute the global namespace, and thus would require more verbose names to ensure uniqueness. I'd prefer not to have my code littered with things like APPLICATIONNAME_MESSAGES_TYPE_HOT.

Finally, I could use class names to distinguish types, like so:

class MessageHot extends Message {}
class MessageWarm extends Message {}
class MessageCold extends Message {}
class Message
{
    public function Type()
    {
        return get_class($this);
    }
    public function Data()
    {
        return $this->data;
    }
    public function __construct($data)
    {
        $this->data = $data;
    }
    private $data;
}

This is good, I think, but is also a lot of work for what seems like it ought to be a simple concept.

Am I missing a better alternative?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

能否归途做我良人 2024-08-05 07:34:02

一个非常常见的约定是在 PHP 中使用类常量。

例如

class Message
{
    const HOT  = 0;
    const WARM = 1;
    const COLD = 2;
}

A very common convention is to use class constants in PHP.

e.g.

class Message
{
    const HOT  = 0;
    const WARM = 1;
    const COLD = 2;
}
蘑菇王子 2024-08-05 07:34:02

我还为此使用了带有常量的类。 我添加以下内容

  • 使类抽象,以确保没有人尝试实例化它,
  • 添加一个静态数组,将常量映射到字符串以打印友好消息
  • 实现静态 __toString() 方法来执行前面的操作

    抽象类消息{ 
          常量热= 0; 
          常量温暖 = 1; 
          常量冷= 2; 
    
          公共静态$枚举=数组( 
              自我::热=>   “热的”, 
              自我::温暖=>   “温暖的”, 
              自我::冷=>   “寒冷的” 
          ); 
    
          公共静态 __toString($enum) { 
              返回自我::$enums[$enum]; 
          } 
      } 
      

我还可以使用 Message::$enums 来测试变量:

if (!array_key_exists($is_it_valid, Message::$enums)

I also use a class with consts for this. I add the following

  • make the class abstract, to make sure no one tries to instantiate it
  • add a static array that maps the consts to strings for printing friendly messages
  • implement a static __toString() method to do the previous

    abstract class Message {
        const HOT = 0;
        const WARM = 1;
        const COLD = 2;
    
        public static $enums= array(
            self::HOT => "hot",
            self::WARM => "warm",
            self::COLD => "cold"
        );
    
        public static __toString($enum) {
            return self::$enums[$enum];
        }
    }
    

I can also use the Message::$enums to test variables:

if (!array_key_exists($is_it_valid, Message::$enums)
仅一夜美梦 2024-08-05 07:34:02

您可以使用类常量

class Message
{
    const hot = 0;
    const warm = 1;
    const cold = 2;
}

foo(Message::hot);
foo(Message::warm);
foo(Message::cold);

You could use class constants:

class Message
{
    const hot = 0;
    const warm = 1;
    const cold = 2;
}

foo(Message::hot);
foo(Message::warm);
foo(Message::cold);
深居我梦 2024-08-05 07:34:02

您可能想查看 stackoverflow 上这个问题的前两个答案
提到了

You might want to look at the two first answers to this question on stackoverflow
mentionning both

七分※倦醒 2024-08-05 07:34:02

创建抽象类 Enumerator:

abstract class Enumerator {
  static function enumerate() {
    return (new ReflectionClass(get_called_class()))->getConstants();
  }
  static function exists($enum) {
    return in_array($enum, self::enumerate());
  }
}

声明您的枚举:

abstract class Message extends Enumerator {
  const HOT  = 0;
  const WARM = 1;
  const COLD = 2;
}

使用:

var_dump(Message::HOT);
var_dump(Message::WARM);
var_dump(Message::COLD);

var_dump(Message::exists(0));
var_dump(Message::exists(6));

var_dump(Message::enumerate());

输出:

int(0)
int(1)
int(2)

bool(true)
bool(false)

array(3) {
  ["HOT"]  => int(0)
  ["WARM"] => int(1)
  ["COLD"] => int(2)
}

Make abstract class Enumerator:

abstract class Enumerator {
  static function enumerate() {
    return (new ReflectionClass(get_called_class()))->getConstants();
  }
  static function exists($enum) {
    return in_array($enum, self::enumerate());
  }
}

Declare your enumerations:

abstract class Message extends Enumerator {
  const HOT  = 0;
  const WARM = 1;
  const COLD = 2;
}

Use:

var_dump(Message::HOT);
var_dump(Message::WARM);
var_dump(Message::COLD);

var_dump(Message::exists(0));
var_dump(Message::exists(6));

var_dump(Message::enumerate());

Output:

int(0)
int(1)
int(2)

bool(true)
bool(false)

array(3) {
  ["HOT"]  => int(0)
  ["WARM"] => int(1)
  ["COLD"] => int(2)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文