PHPを使用して列挙を実装するにはどうすればよいですか?
この記事では、PHP を使用して列挙を実装する方法について説明します。一定の参考値があるので、困っている友人は参考にしていただければ幸いです。
列挙
数学とコンピュータ サイエンスの理論では、集合の 列挙とは、ある有限の数列セットのすべてのメンバーをリストするプログラム、または数列の数をリストするプログラムです。特定のタイプのオブジェクト。この 2 つのタイプは、多くの場合 (常にではありませんが) 重複します。列挙型は、整定定数の名前付きコレクションです。列挙型は日常生活で非常に一般的です。たとえば、週を表す SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、および SATURDAY は列挙型です。 ——Wikipedia
ビジネス シナリオ
実際の開発プロセスでは、列挙型に触れるのは非常に簡単ですが、PHP の列挙型のネイティブ サポートはあまり充実していないためです。多くの場合、開発者は列挙型の使用に注意を払わず、代わりにグローバル定数またはクラス定数を使用しますが、原則として、これら 2 つのデータは依然として 文字列
であり、型の判定には使用できません。
ビジネス
- 注文ステータス支払い保留中/出荷保留中/受領保留中/評価保留中
- メンバーステータス有効化/非アクティブ
- . ...
待ってください。多くの場合、単純な 1/2/3/4 または 0/1 を使用してそれを表し、ドキュメントまたはコメントでこれらを指定します。
より高度な方法としては、定数として定義して統一アクセスを容易にすることですが、定数の値は文字列のままであり、型を判断することはできません。
ここで、PHP の列挙のサポートについて見てみる必要があります。PHP は列挙を完全にはサポートしていませんが、SPL
SPL Enumeration
SplEnum extends SplType {/ Constants / const NULL __default = NULL ; / 方法 / public getConstList ([ bool $include_default = FALSE ] ) : array / 继承的方法 / SplType::__construct ( [mixed $initial_value [, bool $strict ]] ) }
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 类型。
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 メソッドの出力値として使用されます。 time 渡されたパラメータが期待したものと異なっていても、機能は実装されているようです。しかし、一致しない場合はどうすればよいでしょうか?ほら、3️⃣の時点ですでに事故になっていますが、何か改善方法はありますか?答えはもちろん
Yes です。ここでは、PHP のもう 1 つの優れた点であるリフレクション クラスを使用します。もちろん、これは 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);
End
値が列挙範囲内にあるかどうかを判断するなど、他のニーズがある場合はどうすればよいでしょうか?すべての列挙値を取得しますか?すべての列挙キーを取得し、列挙キーが有効かどうかを判断しますか?自動フォーマット "__toString メソッドでは文字列のみを返すことができるため、場合によっては整数、ブール値、およびその他の型の必要性を強制する場合があります。"
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を使用して列挙を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。
