PHP 中的枚举

2023-12-03

我知道 PHP 还没有原生枚举。但我已经习惯了 Java 世界中的它们。我很乐意使用枚举来提供 IDE 的自动完成功能可以理解的预定义值。

常量可以解决问题,但是存在命名空间冲突问题(或者实际上because)它们是全球性的。数组不存在命名空间问题,但它们太模糊,它们可能在运行时被覆盖,并且 IDE 很少知道如何在没有额外的静态分析注释或属性的情况下自动填充它们的键。

有没有您常用的解决方案/解决方法?有人记得 PHP 人员是否对枚举有过任何想法或决定吗?


从 PHP 8.1 开始,支持枚举:

https://www.php.net/manual/en/language.types.enumerations.php

enum DaysOfWeek: int
{
    case Sunday = 0;
    case Monday = 1;
    // etc.
}
$today = DaysOfWeek::Sunday;
var_dump($today->value); // 0
var_dump($today->name); // "Sunday"

PHP 8.0 及更早版本

根据用例,我通常会使用一些东西simple像下面这样:

abstract class DaysOfWeek
{
    const Sunday = 0;
    const Monday = 1;
    // etc.
}

$today = DaysOfWeek::Sunday;

但是,其他用例可能需要对常量和值进行更多验证。基于以下有关反思的评论,以及其他一些注释,这是一个扩展示例,可以更好地服务于更广泛的情况:

abstract class BasicEnum {
    private static $constCacheArray = NULL;

    private static function getConstants() {
        if (self::$constCacheArray == NULL) {
            self::$constCacheArray = [];
        }
        $calledClass = get_called_class();
        if (!array_key_exists($calledClass, self::$constCacheArray)) {
            $reflect = new ReflectionClass($calledClass);
            self::$constCacheArray[$calledClass] = $reflect->getConstants();
        }
        return self::$constCacheArray[$calledClass];
    }

    public static function isValidName($name, $strict = false) {
        $constants = self::getConstants();

        if ($strict) {
            return array_key_exists($name, $constants);
        }

        $keys = array_map('strtolower', array_keys($constants));
        return in_array(strtolower($name), $keys);
    }

    public static function isValidValue($value, $strict = true) {
        $values = array_values(self::getConstants());
        return in_array($value, $values, $strict);
    }
}

通过创建一个扩展 BasicEnum 的简单枚举类,您现在可以使用方法来进行简单的输入验证:

abstract class DaysOfWeek extends BasicEnum {
    const Sunday = 0;
    const Monday = 1;
    const Tuesday = 2;
    const Wednesday = 3;
    const Thursday = 4;
    const Friday = 5;
    const Saturday = 6;
}

DaysOfWeek::isValidName('Humpday');                  // false
DaysOfWeek::isValidName('Monday');                   // true
DaysOfWeek::isValidName('monday');                   // true
DaysOfWeek::isValidName('monday', $strict = true);   // false
DaysOfWeek::isValidName(0);                          // false

DaysOfWeek::isValidValue(0);                         // true
DaysOfWeek::isValidValue(5);                         // true
DaysOfWeek::isValidValue(7);                         // false
DaysOfWeek::isValidValue('Friday');                  // false

作为旁注,任何时候我至少使用一次反射在数据不会改变的静态/常量类上(例如在枚举中),我缓存这些反射调用的结果,因为每次使用新的反射对象最终都会产生明显的性能影响(存储在多个枚举的关联数组中)。

现在大多数人都已经finally至少升级到 5.3,并且SplEnum可用,这当然也是一个可行的选择——只要您不介意传统上不直观的实际枚举概念实例化整个代码库。在上面的例子中,BasicEnum and DaysOfWeek它们根本不能被实例化,也不应该被实例化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP 中的枚举 的相关文章

  • 通过jquery ajax()和serialize()提交html表单

    我想通过 jquery ajax 提交此表单 这是我所做的 但它不起作用 即表单正在提交并刷新页面 但我没有看到响应 即在同一页面上打印数组 HTML
  • 如何使用 Facebook API 发布到我自己的页面

    我想使用 API 将更新发布到我拥有的 Facebook 页面 我按照中的说明进行操作这个答案 https stackoverflow com a 28418469 517371获得 a 短期访问令牌对于我的用户 确保授予publish s
  • 更改管理仪表板 WooCommerce 小部件标题

    我想将 WooCommerce 仪表板小部件标题从 WooCommerce 状态 更改为其他内容 我知道我需要在 Functions php 中使用钩子 但我正在努力使这项工作正常进行 我在 WooCommerce 中找到了生成仪表板小部件
  • 如何使用用户代理标头以不同方式检测 Android 手机和 Android 平板电脑?

    对于我的网站 我需要能够区分 Android 平板电脑访问和 Android 手机访问的区别 在将页面发送给用户之前需要对其进行检测 因此不能使用 JavaScript 检查屏幕分辨率 目前我用它来检测 Android 设备 stripos
  • 如何在使用 Piwik 进行分析的页面上显示点击/访问计数器

    我想在主页上显示当天的访问量 该页面由 Piwik 跟踪 如何将 API 与 PHP 结合使用来获取今天的 唯一 访问量和点击量 以便我可以将它们显示在页面上的某个位置 result file get contents http mysit
  • PHP 数组转换为 Javascript 数组

    下午都 下面的代码工作完美 但是 我需要将 php sql 数组的每一行拉出并放入脚本 var 中 关于如何编写可以做到这一点的 while 循环有什么想法吗 谢谢你的帮助 var enableDays enableDays push 附加
  • 如何在javascript中显示目录中的所有图像?

    我想在 javascript 的帮助下动态显示目录中的所有图像 我怎样才能做到这一点 我不认为这是可能的 但如果您向 ASP NET 或 PHP 或类似 页面发出 AJAX 请求 它们可以列出文件夹中的文件并将其返回以供 Javascrip
  • 使用 Poedit 创建 POT 文件

    我正在拼命地尝试为我的 php 新应用程序创建一个目录 in 1 我创建了一个文件 trans php 其中放置了所有要翻译的值 例如 这是我的文件 2 我打开Poedit 在 路径 中这是我输入的内容 见图 然后我保存文件 php 的相同
  • 有什么办法可以打破 PHP 中的 if 语句吗?

    PHP中是否有任何命令可以停止执行当前或父进程if声明 与break or break 1 for switch loop 例如 arr array a b foreach arr as val break echo test echo f
  • 为什么 Stripe Checkout 不将客户姓名添加到客户记录中?

    我正在尝试从 Stripe Checkout 表单提交中检索各种数据 我只是使用 Stripe 仪表板中提供的 Stripe Checkout 代码 In my checkout submission completed我有一个正在尝试检索
  • 在 PHP 中扩展单例

    我正在使用一个 Web 应用程序框架 其中一部分由许多服务组成 所有服务均以单例形式实现 它们都扩展了一个 Service 类 其中实现了单例行为 如下所示 class Service protected static instance p
  • JWT 中的注销不起作用

    我是 Laravel 的新手 我安装了 JWT 并登录 所以它工作并生成了一个令牌 当我在邮递员中注销时它返回 true 但一次又一次它返回 true 和 auth gt 用户 注销后始终返回用户 这是我的代码 public functio
  • php 发送带有图像的电子邮件

    我正在尝试发送一封带有图片的电子邮件 我的电子邮件正文是 当我收到电子邮件时 我看不到图片 相反 我 看 img src http planet earth bogus us icons secret pictures gif 我知道这是因
  • rewrite_mod 已启用,但 .htaccess 不起作用

    我在 Amazon EC2 的 ubuntu 12 04 中使用 apache 2 2 我使用启用了 mod rewrite sudo a2enmod rewrite 并能够看到 apache2ctl M 现在我编写了以下 htaccess
  • 使用 PHP 上传、调整图像大小并裁剪图像中心

    我想要创建一个非常非常基本的上传 调整大小和裁剪 PHP 脚本 其功能与 Twitter 用于上传头像图片的方法相同 无论如何我最后检查过 我希望脚本拍摄任何尺寸的图像 将最短边的大小调整为 116 像素 然后裁剪顶部和底部 如果是横向 则
  • PHP:在执行 php 脚本时显示“正在加载”页面

    这就是我现在所拥有的 我有一个网页 当访问该网页时 它会通过开放 API 连接到 Surveygizmo com 检索大量数据 然后将这些数据返回给我进行处理 此过程大约需要 10 12 秒 在执行时 页面只是处于 正在加载 状态 并且我会
  • PHP随机输出数组元素

    我如何从大约 20 个元素的数组中随机回显 5 个元素 Thanks 这有效吗 values array rand input 5 或者 作为更灵活的功能 function randomValues input num 5 return a
  • Drupal 模板/主题资源或建议?

    我有兴趣为我正在开发的 Drupal 网站创建自定义主题 我是 Drupal 的新手 但是我在处理构建主题 CSS PHP HTML 所需的基本概念方面拥有相当多的经验 所以 我的问题是 我从哪里开始 有创建 Drupal 主题的规范指南吗
  • SplFileObject + LimitIterator + 偏移量

    我有两行数据文件 两行仅用于我的示例 实际上 该文件可以包含数百万行 并且我使用 SplFileObject 和 LimitIterator 进行偏移 但这种组合在某些情况下会有奇怪的行为 offset 0 file new SplFile
  • 将文件附加到 PHPMailer

    我目前正在开发一个项目 该项目将文件作为 blob 存储在数据库中 我需要将文件附加到电子邮件并通过 PHPMailer 发送出去 我熟悉 mail gt addAttachment 但是 这个函数似乎只接受文件路径 而我没有 我想知道是否

随机推荐

  • Windows 系统托盘图标 - 控制位置

    我有一些我编写的旧应用程序 在 Delphi 中 由于各种原因 它们使用系统托盘图标 大多数都使用 AppControls TacTrayIcon 或其他一些类似的组件 这是我的问题 如何控制position托盘图标 即相对于系统时间的位置
  • R:使用 rollapply 和 ddply 进行分组滚动窗口线性回归

    我有一个包含多个分组变量的数据集 我想在其上运行滚动窗口线性回归 最终目标是提取斜率最低的 10 个线性回归 并将它们一起平均以提供平均最小变化率 我找到了使用 rollapply 来计算滚动窗口线性回归的示例 但我有一个额外的复杂性 我想
  • Facebook API / Android:墙贴发布时图像附件不起作用

    我有以下代码 它可以工作并发布消息部分 但附件部分不起作用 我怀疑这与将 JSON 作为字符串传递有关 脸书回归 id 23522646737635675 所以这不是一个错误 Bundle params new Bundle params
  • ggplot 中的双点

    我找不到密度周围双点的文档 set seed 1234 df lt data frame cond factor rep c A B each 200 rating c rnorm 200 rnorm 200 mean 8 print he
  • 设计“find_first_by_auth_conditions”方法说明

    我使用的两种方法Devise Method1 def self find first by auth conditions warden conditions conditions warden conditions dup where c
  • 计算两个地址之间的距离时出现错误

    我有以下脚本 用于电子表格中计算两个城市或一个城市与另一个城市的邮政编码之间的行驶距离 它正在大约 25 个地点同时运行 为了更好地解释 我有一个单元格 B3 每次我都会进入一个新城市 然后 该脚本在与我的 25 个工厂位置相邻的单元格中使
  • 在您的路径上找不到 Git 或 Cordova (Windows/Netbeans),在 AppData/Local 下找不到 GitHub,FIX 2015

    Error NetBeans 在您的路径上找不到 git 或 cordova When尝试在 Netbeans 中创建新的 Cordova 应用程序 怎么修 gt 答案可以在下面找到 如果有人想知道如何让 Cordova 在 Netbean
  • Java多线程仅用于2台计算机,如何在main中执行

    我正在尝试让至少两台计算机连接到我的服务器 我将如何启动第二个线程 public static void main String args throws InterruptedException Create the server whic
  • [MASM]另一个“无法使用具有 32 位地址的 16 位寄存器”错误

    我正在使用 MASM 汇编器学习汇编语言 当我尝试使用以下命令汇编一个简单文件时 我遇到了困难 ml c test asm和test asm文件看起来像 386 model flat code MOV BP WORD PTR BP 4 EN
  • 如何在Android中定义回调?

    在最近的 Google IO 期间 有一个关于实现 Restful 客户端应用程序的演示 不幸的是 这只是一个高层讨论 没有实现的源代码 在此图中 在返回路径上有对其他方法的各种不同的回调 我如何声明这些方法是什么 我理解回调的想法 在发生
  • E0513 “const char *”类型的值无法分配给“LPCWSTR”类型的实体

    你好 我试图在屏幕上绘制一个窗口 我两周前写了这个 它有效 但现在我重写了它 完全相同 我收到错误 有人可以帮忙吗 错误是 E0167 const char 类型的参数与 LPCWSTR 类型的参数不兼容 和 E0513 const cha
  • 如何附加两个音频文件?

    我想在 iPhone 中附加两个音频文件 请帮助我做到这一点 我得到了解决方案 以下是执行此操作的示例代码 AVMutableComposition composition AVMutableComposition composition
  • 使用添加按钮在 React 中添加输入

    我正在尝试制作一组 可以复制或删除的输入 我发现并使用了以下组合 https jsfiddle net 69z2wepo 36745 这是 因为上面的代码不处理删除 https codepen io lichin lin pen MKMez
  • Android:如何使用画布/绘制位图缩放位图以适合屏幕尺寸?

    我正在拍摄图像并使用画布将其绘制到屏幕上 我想根据屏幕尺寸缩放它 这是我尝试过的 但它切断了图像的一大块 DisplayMetrics metrics context getResources getDisplayMetrics int w
  • Sendkeys 在 android appium 驱动程序上失败

    我正在使用 appium 来自动化 Android 应用程序 在这种情况下 无法在以下情况下对文本字段执行 sendkeys 单击添加客户选项 新页面打开 我正在尝试在文本字段中输入值 我能够使用 xpath 找到页面上的文本字段 我可以单
  • spinner If Strings** == 不工作

    为什么这不起作用 if itemx Test number item 0 Log i Dropdown inside if us lo ans hold setText 0x 如果 itemx 是字符串并且它具有字符串 测试编号项目 0 我
  • 在 FSharp 中查找两个数组之间的差异

    我有两个数组 我想在第二个数组中查找不在第一个数组中的元素 我写了以下代码 let array0 A B C let array1 B D E let inZero letter array0 gt Array tryFind fun l
  • 使用 jsoup 解析 JavaScript

    In an HTML页面 我想选择 a 的值javascript多变的 下面是片段HTML page
  • AutoMapper 将 2 个表中的记录连接到单个 IEnumerable 视图模型中

    我有 2 张桌子 比如说T1 and T2 T1包含oID CID 日期 状态 and T2包含cID cName cURL 我为上面两个表设计了类 如下所示 T1 cs public class T1 public int oID get
  • PHP 中的枚举

    我知道 PHP 还没有原生枚举 但我已经习惯了 Java 世界中的它们 我很乐意使用枚举来提供 IDE 的自动完成功能可以理解的预定义值 常量可以解决问题 但是存在命名空间冲突问题 或者实际上because 它们是全球性的 数组不存在命名空