文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PHP 中的枚举

2024-02-27 20:41

关注

本教程将教你如何在 PHP 8.1 之前和之后使用 PHP 中的枚举。

原因是在 PHP 8.1 之前,你只能使用抽象类来模拟枚举。但是,从 PHP 8.1 开始,PHP 提供了对枚举的原生支持。


在 PHP 中使用抽象类模拟枚举

在 PHP 8.1 之前,你可以使用抽象类来模拟枚举。由于枚举是将名称分配给整数常量,因此你可以创建一个包含常量值的抽象类。

你可以通过范围解析协议 :: 获取类外的每个常量值。

我们的下一个示例代码有一个包含类常量的抽象类。之后,我们通过范围解析协议调用其中一个常量。

这种方法有其局限性;我们将在下一节讨论它。


<?php
    abstract class CalenderMonths {
        const January 	= 1;
        const February 	= 2;
        const March 	= 3;
        const April 	= 4;
        const May 		= 5;
        const June 		= 6;
        const July		= 7;
        const August 	= 8;
        const September = 9;
        const October 	= 10;
        const November 	= 11;
        const December 	= 12;
    }

    $january = CalenderMonths::January;

    echo $january;
?>

输出:


1

在 PHP 中使用具有验证和更多常量值的抽象类来模拟枚举

这个例子建立在我们之前的例子之上。但是在这里,我们提出了一个改进的版本。

这个版本有验证,可以保存更多的常数值。此外,它还可以防止当你扩展类时,第一个扩展创建一个缓存,而另一个扩展仍然使用相同的缓存。

该代码块使用抽象类模拟枚举,并且它具有防止无效参数的验证。首先,我们定义抽象类。


<?php
    abstract class EmulatePHPEnum {
        private static $cache_array = NULL;

        private static function get_constants() {
            if (self::$cache_array == NULL) {
                self::$cache_array = [];
            }
            $called_class = get_called_class();
            if (!array_key_exists($called_class, self::$cache_array)) {
                $reflection_object = new ReflectionClass($called_class);
                self::$cache_array[$called_class] = $reflection_object->getConstants();
            }
            return self::$cache_array[$called_class];
        }

        public static function check_valid_name($name, $is_strict = false) {
            $constants = self::get_constants();

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

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

        public static function check_valid_value($value, $is_strict = true) {
            $values = array_values(self::get_constants());
            return in_array($value, $values, $is_strict);
        }
    }
?>

然后,我们扩展它并进行比较。


abstract class CalenderMonths extends EmulatePHPEnum {
	const January 	= 1;
	const February 	= 2;
	const March 	= 3;
	const April 	= 4;
	const May 		= 5;
	const June 		= 6;
	const July		= 7;
	const August 	= 8;
	const September = 9;
	const October 	= 10;
	const November 	= 11;
	const December 	= 12;
}

echo "<b>First check: </b> ";
if (CalenderMonths::check_valid_name("Nothing")) {
	echo "True";
} else {
	echo "False";
}

echo "<br />";

echo "<b>Second check: </b>";
if (CalenderMonths::check_valid_name("September")) {
	echo "True";
} else {
	echo "False";
}

echo "<br />";

echo "<b>Third check: </b>";
if (CalenderMonths::check_valid_name("september")) {
	echo "True";
} else {
	echo "False";
}

echo "<br />";

echo "<b>Fourth check: </b>";
if (CalenderMonths::check_valid_name("september", $is_strict = true)) {
	echo "True";
} else {
	echo "False";
}

echo "<br />";

echo "<b>Fifth check: </b>";
if (CalenderMonths::check_valid_name(23)) {
	echo "True";
} else {
	echo "False";
}

echo "<br />";

输出:


<b>First check</b>: False
<b>Second check</b>: True
<b>Third check</b>: True
<b>Fourth check</b>: False
<b>Fifth check</b>: False

使用 PHP enum 进行枚举

PHP 中枚举的定义是使用 enum 关键字后跟枚举名称和一组花括号。在这些大括号中,你可以定义案例。

我们在下一个代码块中提供一个示例。此外,我们在案例之间进行了一些比较检查。

请注意,你不能将枚举与小于或大于运算符进行比较。


<?php
    enum ProgrammingLanguages {
        case JavaScript;
        case PHP;
        case Ruby;
        case Erlang;
        case Elixir;
    }

    $javascript = ProgrammingLanguages::JavaScript;
    $js 		= ProgrammingLanguages::JavaScript;
    $erlang     = ProgrammingLanguages::Erlang;

    echo $javascript === $js;

    echo "<br/>";

    if ($javascript === $erlang) {
        echo "True";
    } else {
        echo "False";
    }

    echo "<br/>";

    if ($javascript instanceof ProgrammingLanguages) {
        echo "True";
    } else {
        echo "False";
    }

    echo "<br />";
    if ($javascript > $js || $javascript < $js) {
        echo "True";
    } else {
        echo "False";
    }
?>

输出:


1 <br />
False <br />
True <br />
False <br />

支持的 PHP 枚举

支持的枚举是枚举声明,后跟枚举中每种情况的数据类型。

在我们查看代码示例之前,请注意以下关于 PHP 中支持的枚举的以下内容。

  1. 为支持值定义值时,确保所有值都有支持值。
  2. 你应该在枚举名称之后声明支持值的类型。
  3. 枚举中的支持值是只读的。
  4. 如果你的枚举包含标量值,它们应该是唯一的。
  5. 支持的值应该是文字表达式或文字。
  6. 你可以使用语法 enum_name::backed_value 访问支持的值。其中 enum_name 是枚举名称,backed_value 是你要访问的值。
  7. 支持的枚举有一个称为 BackedEnum 的内部接口。这个接口有两个方法,fromtryFrom
  8. from 方法将抛出不存在值的异常。而 tryFrom 返回 null

以下代码显示了如何在 PHP 中使用支持的枚举。


<?php
    enum Age : int {
        case John 		= 23;
        case Martinez 	= 30;
        case Mary 		= 43;
        case Velasquez 	= 25;
    }

    $first_age = Age::tryFrom(23);

    if ($first_age) {
        echo "True";
    } else {
        echo "False";
    }

    echo "<br />";

    $second_age = Age::tryFrom(98);

    if ($second_age) {
        echo "True";
    } else {
        echo "False";
    }

    echo "<br />";

    $third_age = Age::from(42);
?>

输出:


True
False

<b>Fatal error</b>: Uncaught ValueError: 42 is not a valid backing value for enum "Age"

使用 PHP 中的方法支持枚举

支持的枚举可以有方法。结果,他们可以实现一个接口。

你将在下一个示例代码中找到一个示例。


<?php

    interface isTravel {
        public function calculate_travel_cost (int $distance_covered): int;
        public function isRequireFuel(): bool;
    }

    enum CarTypes: int implements isTravel {
        case Bughatti 		= 300;
        case Lamborghini 	= 500;
        case Ferrari 		= 450;
        case Audi 			= 350;

        public function calculate_travel_cost(int $distance_covered): int {
            return $this->value * $distance_covered;
        }

        public function isRequireFuel(): bool {
            return match($this) {
                CarTypes::Bughatti, CarTypes::Lamborghini, CarTypes::Ferrari => true,
            };
        }
    }

    $car = CarTypes::Bughatti;

    $does_it_require_fuel = $car->isRequireFuel();

    if ($does_it_require_fuel) {
        echo "True";
    } else {
        echo "False";
    }

    echo "<br />";

    $car_travel_cost = $car ->calculate_travel_cost(250);

    echo $car_travel_cost;
?>

输出:


True
75000

列出 PHP 中支持枚举的案例

如果你希望列出支持枚举的情况,可以通过名为 UnitEnum 的内部接口来完成。这个接口有一个定义为 UnitEnum::cases 的静态方法。

使用此接口,你可以检索枚举中的案例。你将在下面找到示例代码。


<?php
    interface isTravel {
        public function calculate_travel_cost (int $distance_covered): int;
        public function isRequireFuel(): bool;
    }

    enum CarTypes: int implements isTravel {
        case Bughatti 		= 300;
        case Lamborghini 	= 500;
        case Ferrari 		= 450;
        case Audi 			= 350;

        public function calculate_travel_cost(int $distance_covered): int {
            return $this->value * $distance_covered;
        }

        public function isRequireFuel(): bool {
            return match($this) {
                CarTypes::Bughatti, CarTypes::Lamborghini, CarTypes::Ferrari => true,
            };
        }
    }

    $car_names = CarTypes::cases();
    echo "<pre>";
    var_dump($car_names);
    echo "</pre>";
?>

输出:


<pre>
array(4) {
  [0]=>
  enum(CarTypes::Bughatti)
  [1]=>
  enum(CarTypes::Lamborghini)
  [2]=>
  enum(CarTypes::Ferrari)
  [3]=>
  enum(CarTypes::Audi)
}
</pre>
阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯