本篇文章给人人带来的内容是关于如何运用PHP来完成罗列?有一定的参考价值,有须要的朋侪能够参考一下,愿望对你有所协助。
罗列
在数学和计算机科学理论中,一个集的 罗列是列出某些有穷序列集的一切成员的顺序,或许是一种特定范例对象的计数。这两种范例常常(但不老是)堆叠。罗列是一个被定名的整型常数的鸠合,罗列在一样平常生活中很罕见,比方示意礼拜的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个罗列。—— 维基百科
营业场景
在现实开辟过程当中我们异常轻易接触到罗列范例,然则又由于 PHP 原生对罗列的支撑不是太好,所以许多时刻 开辟人员并没有注重罗列的运用,而是运用全局常量或许类常量替代,而这两个数据原则上照样 字符串
并不能用来做范例推断。
营业
- 定单状况 待付出/待发货/待收货/待评价
- 会员状况 激活/未激活
- ....
等等 ,许多时刻我们都会用简朴的 1/2/3/4 或许0/1 如许的体式格局去代表,然后在文档或许解释中划定这些东西。
更高等一点儿的就是定义成常量,然后轻易一致存取,然则常量的值照样是字符串,没法举行范例推断。
这里就要看一下 PHP 对罗列的支撑,虽然 PHP 对罗列没有圆满的支撑,然则在 SPL 中照样有一个基本的罗列类
SPL 罗列
SplEnum extends SplType {/ Constants / const NULL __default = NULL ; / 要领 / public getConstList ([ bool $include_default = FALSE ] ) : array / 继承的要领 / SplType::__construct ( [mixed $initial_value [, bool $strict ]] ) }
然则!这个须要分外的装置 PECL 用 PECL 装置 Spl_Types
,无意间增加了运用本钱,那有无其他解决方案?答案是一定的。
直接手写一个。
最先预备
起首定一个罗列
class Enum { // 默认值 const __default = self::WAIT_PAYMENT; // 待付款 const WAIT_PAYMENT = 0; // 待发货 const WAIT_SHIP = 1; // 待收货 const WAIT_RECEIPT = 2; // 待评价 const WAIT_COMMENT = 3; }
如许好像就完成了,我们直接运用 Enum::WAIT_PAYMENT
就能够拿到内里的值了,然则传参的处所我们并没法校验他。
function setStatus(Enum $status){ // TODO } setStatus(Enum::WAIT_PAYMENT); // Error 明显这是不可的 由于上面常量的值时一个 int 并非 Enum 范例。
这里我们就须要用到 PHP 面向对象中的一个把戏要领 __toString()
public __toString ( void ) : string
__toString() 要领用于一个类被当做字符串时应如何回应。比方 echo $obj; 应当显现些什么。此要领必需返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR 级别的致命毛病。
如今我们来完美一下这个要领。
class OrderStatus extends Enum { // 默认值 const __default = self::WAIT_PAYMENT; // 待付款 const WAIT_PAYMENT = 0; // 待发货 const WAIT_SHIP = 1; // 待收货 const WAIT_RECEIPT = 2; // 待评价 const WAIT_COMMENT = 3; public function __toString() { return '233'; } } // object echo gettype($orderStatus) . PHP_EOL; // boolean true var_dump($orderStatus instanceof Enum); // 233 echo $orderStatus;
初具模子
这里好像完成了一部分,那我们应当如何让他做的更好?再来革新一下。
class OrderStatus extends Enum { // 默认值 const __default = self::WAIT_PAYMENT; // 待付款 const WAIT_PAYMENT = 0; // 待发货 const WAIT_SHIP = 1; // 待收货 const WAIT_RECEIPT = 2; // 待评价 const WAIT_COMMENT = 3; /** * @var string */ protected $value; public function __construct($value = null) { $this->value = is_null($value) ? self::__default : $value; } public function __toString() { return (string)$this->value; } } // 1️⃣ $orderStatus = new OrderStatus(OrderStatus::WAIT_SHIP); // object echo gettype($orderStatus) . PHP_EOL; // boolean true var_dump($orderStatus instanceof Enum); // 1 echo $orderStatus . PHP_EOL; // 2️⃣ $orderStatus = new OrderStatus(); // object echo gettype($orderStatus) . PHP_EOL; // boolean true var_dump($orderStatus instanceof Enum); // 0 echo $orderStatus; // 3️⃣ $orderStatus = new OrderStatus('不测的参数'); // object echo gettype($orderStatus) . PHP_EOL; // boolean true var_dump($orderStatus instanceof Enum); // 不测的参数 echo $orderStatus;
在这一次,我们加入了 组织函数
而且许可他传入一个可选的值,然后来作为 __toString
要领的输出值,此次看起来不错,功用都已完成了,假如传入的参数否和我们的预期的话。然则 万一不符合呢?看看,第 3️⃣ 个那边,就已成了不测了,哪另有无方法弥补?答案固然是 有的
,在这里我们会用到 PHP 另一个好东西 反射类 ,固然这个不是 PHP 特有的,其他言语也有。
固然,除了反射,我们还会用到别的一个东西 要领重载
内里的 __callStatic
要领。
更进一步
public static __callStatic ( string $name , array $arguments ) : mixed
在静态高低文中挪用一个不可接见要领时,__callStatic() 会被挪用。$name 参数是要挪用的要领称号。$arguments 参数是一个罗列数组,包含着要传递给要领 $name 的参数。
继承革新。
class Enum { const __default = null; /** * @var string */ protected static $value; // 注重这里 将组织函数的 修饰符改成了 受庇护的 即 外部没法直接 new protected function __construct($value = null) { // 很通例 self::$value = is_null($value) ? static::__default : $value; } /** * @param $name * @param $arguments * @return mixed * @throws ReflectionException */ public static function __callStatic($name, $arguments) { // 实例化一个反射类 static::class 示意挪用者 $reflectionClass = new ReflectionClass(static::class); // 这里我们要有一个商定, 就是类常量成员的名字必需的大写。 // 这里就是取出来挪用的静态要领名对应的常量值 虽然这里有个 getValue 要领 // 然则由于其返回值不可靠 我们就依赖于他底本的隐式的 __toString 要领来帮我们输出字符串即可。 $constant = $reflectionClass->getConstant(strtoupper($name)); // 猎取挪用者的 组织要领 $construct = $reflectionClass->getConstructor(); // 设置成可接见 由于我们把修饰符设置成了受庇护的 这里须要接见到,所以就须要设置成可接见的。 $construct->setAccessible(true); // 由于如今类已是能够接见的了所以我们直接实例化即可,实例化以后 PHP 会自动挪用 __toString 要领 使得返回预期的值。 $static = new static($constant); return $static; } public function __toString() { return (string)self::$value; } } class OrderStatus extends Enum { // 默认值 const __default = self::WAIT_PAYMENT; // 待付款 const WAIT_PAYMENT = 0; // 待发货 const WAIT_SHIP = 1; // 待收货 const WAIT_RECEIPT = 2; // 待评价 const WAIT_COMMENT = 3; } $WAIT_SHIP = OrderStatus::WAIT_SHIP(); var_dump($WAIT_SHIP . ''); var_dump($WAIT_SHIP instanceof Enum);
到这里 一个简朴的罗列类就完成了。
结束
那假如我们另有其他需求、比方 推断一个值是不是是在罗列范围内?猎取一切的罗列值?猎取一切的罗列键,推断罗列键是不是有用?自动花样化「由于 __toString 要领只许可返回字符串 ,然则有的时刻我们强迫须要整形、bool 等范例」
class Enum { const __default = null; /** * @var string */ protected static $value; /** * @var ReflectionClass */ protected static $reflectionClass; // 注重这里 将组织函数的 修饰符改成了 受庇护的 即 外部没法直接 new protected function __construct($value = null) { // 很通例 self::$value = is_null($value) ? static::__default : $value; } /** * @param $name * @param $arguments * @return mixed */ public static function __callStatic($name, $arguments) { // 实例化一个反射类 static::class 示意挪用者 $reflectionClass = self::getReflectionClass(); // 这里我们要有一个商定, 就是类常量成员的名字必需的大写。 // 这里就是取出来挪用的静态要领名对应的常量值 虽然这里有个 getValue 要领 // 然则由于其返回值不可靠 我们就依赖于他底本的隐式的 __toString 要领来帮我们输出字符串即可。 $constant = $reflectionClass->getConstant(strtoupper($name)); // 猎取挪用者的 组织要领 $construct = $reflectionClass->getConstructor(); // 设置成可接见 由于我们把修饰符设置成了受庇护的 这里须要接见到,所以就须要设置成可接见的。 $construct->setAccessible(true); // 由于如今类已是能够接见的了所以我们直接实例化即可,实例化以后 PHP 会自动挪用 __toString 要领 使得返回预期的值。 $static = new static($constant); return $static; } /** * 实例化一个反射类 * @return ReflectionClass * @throws ReflectionException */ protected static function getReflectionClass() { if (!self::$reflectionClass instanceof ReflectionClass) { self::$reflectionClass = new ReflectionClass(static::class); } return self::$reflectionClass; } /** * @return string */ public function __toString() { return (string)self::$value; } /** * 推断一个值是不是有用 即是不是为罗列成员的值 * @param $val * @return bool * @throws ReflectionException */ public static function isValid($val) { return in_array($val, self::toArray()); } /** * 转换罗列成员为键值对输出 * @return array * @throws ReflectionException */ public static function toArray() { return self::getEnumMembers(); } /** * 猎取罗列的常量成员数组 * @return array * @throws ReflectionException */ public static function getEnumMembers() { return self::getReflectionClass() ->getConstants(); } /** * 猎取罗列成员值数组 * @return array * @throws ReflectionException */ public static function values() { return array_values(self::toArray()); } /** * 猎取罗列成员键数组 * @return array * @throws ReflectionException */ public static function keys() { return array_keys(self::getEnumMembers()); } /** * 推断 Key 是不是有用 即存在 * @param $key * @return bool * @throws ReflectionException */ public static function isKey($key) { return in_array($key, array_keys(self::getEnumMembers())); } /** * 依据 Key 去猎取罗列成员值 * @param $key * @return static */ public static function getKey($key) { return self::$key(); } /** * 花样罗列效果范例 * @param null|bool|int $type 当此处的值时什么类时 花样化输出的即为此范例 * @return bool|int|string|null */ public function format($type = null) { switch (true) { // 当为纯数字 或许范例处传入的为 int 值时 转为 int case ctype_digit(self::$value) || is_int($type): return (int)self::$value; break; // 当 type 传入 true 时 返回 bool 范例 case $type === true: return (bool)filter_var(self::$value, FILTER_VALIDATE_BOOLEAN); break; default: return self::$value; break; } } } class OrderStatus extends Enum { // 默认值 const __default = self::WAIT_PAYMENT; // 待付款 const WAIT_PAYMENT = 0; // 待发货 const WAIT_SHIP = 1; // 待收货 const WAIT_RECEIPT = 2; // 待评价 const WAIT_COMMENT = 3; } $WAIT_SHIP = OrderStatus::WAIT_SHIP(); // 直接输出是字符串 echo $WAIT_SHIP; // 推断范例是不是存在 var_dump($WAIT_SHIP instanceof OrderStatus); // 花样化输出一下 是要 字符串 、照样 bool 照样整形 // 自动 var_dump($WAIT_SHIP->format()); // 整形 var_dump($WAIT_SHIP->format(1)); // bool var_dump($WAIT_SHIP->format(true)); // 推断这个值是不是有用的罗列值 var_dump(OrderStatus::isValid(2)); // 推断这个值是不是有用的罗列值 var_dump(OrderStatus::isValid(8)); // 猎取一切罗列成员的 Key var_dump(OrderStatus::keys()); // 猎取一切罗列成员的值 var_dump(OrderStatus::values()); // 猎取罗列成员的键值对 var_dump(OrderStatus::toArray()); // 推断罗列 Key 是不是有用 var_dump(OrderStatus::isKey('WAIT_PAYMENT')); // 推断罗列 Key 是不是有用 var_dump(OrderStatus::isKey('WAIT_PAYMENT_TMP')); // 依据 Key 取去 值 注重 这里取出来的已不带有范例了 // 越发发起直接运用 取类常量的体式格局去取 或许在高版本的 直接运用类常量修饰符 // 将类常量不可见最好,然则须要分外处理了 var_dump(OrderStatus::getKey('WAIT_PAYMENT') ->format(1));
停止现在 一个完全的罗列就完成了~
以上就是如何运用PHP来完成罗列?的细致内容,更多请关注ki4网别的相干文章!