迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > PHP >

PHP 中的枚举

作者:迹忆客 最近更新:2023/03/29 浏览次数:

本教程将教你如何在 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>

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

如何在 PHP 中获取时间差的分钟数

发布时间:2023/03/29 浏览次数:183 分类:PHP

本文介绍了如何在 PHP 中获取时间差的分钟数,包括 date_diff()函数和数学公式。它包括 date_diff()函数和数学公式。

PHP 中的重定向

发布时间:2023/03/29 浏览次数:136 分类:PHP

本教程演示了如何将用户从页面重定向到 PHP 中的其他页面

PHP 分页

发布时间:2023/03/29 浏览次数:66 分类:PHP

本教程介绍如何在 PHP 中对数据库行进行分页

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便