PHP 是否有结构、类型定义和/或枚举,如果没有,对它们来说最好的实现是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3836385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:16:52  来源:igfitidea点击:

Does PHP have structs, typedefs, and/or enums and if not what is the best implementation for them?

phpstructenumstypedef

提问by NoodleOfDeath

NOTICE!: This question is not a duplicate: I have provided below an alternative and highly useful enumeration method that accomplishes the desired effect - 11/13/2013

NOTICE!: This question is not a duplicate: I have provided below an alternative and highly useful enumeration method that accomplishes the desired effect - 11/13/2013

Is there a typedefkeyword in PHP such that I can do something like:

typedefPHP 中是否有一个关键字,以便我可以执行以下操作:

typedef struct {

} aStructure;

or

或者

typedef enum {
  aType1,
  aType2,
} aType;

EDIT

编辑

I eventually answered my own question below. I created a custom enumfunction that accomplishes exactly what I was asking for, but without type definition.

我最终在下面回答了我自己的问题。我创建了一个自定义enum函数,它完全满足我的要求,但没有类型定义。

采纳答案by NoodleOfDeath

I actually created my own kind of enum for PHP and it works just fine for what i need to do. no typedefs but its nice :D

我实际上为 PHP 创建了我自己的枚举类型,它可以很好地满足我的需求。没有typedef,但很好:D

Function enum($array, $asBitwise = false)

函数枚举($array,$asBitwise = false)



    /*
     * I formed another version that includes typedefs
     * but seeing how this hacky is not viewed as compliant
     * with programming standards I won't post it unless someone
     * wishes to request. I use this a lot to save me the hassle of manually
     * defining bitwise constants, but if you feel it is too pointless
     * for you I can understand. Not trying to reinvent the wheel here
     *
     */
    function enum(array $array, bool $asBitwise = false) {

        if(!is_array($array) || count($array) < 1)  return false;    // Error incorrect type

        $n = 0; // Counter variable
        foreach($array as $i) {
            if(!define($i, $n == 0 ? 0 : ($asBitwise ? 1 << ($n - 1) : $n))) return false;
            ++$n;
        } 
        return true; // Successfully defined all variables

    }



Usage (EXAMPLE):

用法(示例):



    enum([
        'BrowserTypeUnknown',       // 0
        'BrowserTypeIE',            // 1
        'BrowserTypeNetscape',      // 2
        'BrowserTypeOpera',         // 3
        'BrowserTypeSafari',        // 4
        'BrowserTypeFirefox',       // 5
        'BrowserTypeChrome',        // 6
    ]); // BrowserType as an Increment

    $browser_type = BrowserTypeChrome;

    if($browser_type == BrowserTypeOpera) {
        // Make Opera Adjustments (will not execute)
    } else
    if($browser_type == BrowserTypeChrome) {
        // Make Chrome Adjustments (will execute)
    }

    enum([
        'SearchTypeUnknown',            // 0
        'SearchTypeMostRecent',         // 1 << 0
        'SearchTypePastWeek',           // 1 << 1
        'SearchTypePastMonth',          // 1 << 2
        'SearchTypeUnanswered',         // 1 << 3
        'SearchTypeMostViews',          // 1 << 4
        'SearchTypeMostActive',         // 1 << 5
    ], true); // SearchType as BitWise

    $search_type = SearchTypeMostRecent | SearchTypeMostActive;

    if($search_type & SearchTypeMostRecent) {
        // Search most recent files (will execute)
    }
    if($search_type & SearchTypePastWeek) {
        // Search files from the past will (will not execute)
    }

    if($search_type & SearchTypeMostActive) {
        // Search most active files AS WELL (will execute as well)
    }



回答by deceze

Nope.

不。

You'll have to go with arrays or, if you require something that has a custom type, classes and objects.

您将不得不使用数组,或者,如果您需要具有自定义类型、类和对象的东西。

回答by staticsan

You can do something similar with constants, but it's not the same as a dedicated enum.

您可以对常量执行类似的操作,但它与专用枚举不同。

回答by Martin Holzhauer

Their is an Extension called SPL_Types, but this extension is nearly at no web hosting available AND its not maintained anymore. So the best would be using classes for structs. and constants for enums. maybe with the help of the plain SPLextension, which is nearly in every php 5.X installation available, you could build some "evil dirty enum hack"

他们是一个名为SPL_Types的扩展,但这个扩展几乎没有可用的网络托管,也不再维护。所以最好的方法是使用结构类。和枚举常量。也许在几乎每个可用的 php 5.X 安装中的普通SPL扩展的帮助下,您可以构建一些“邪恶的肮脏的枚举黑客”

回答by zanshine

Here is a github library for handling type-safe enumerations in php:

这是一个用于在 php 中处理类型安全枚举的 github 库:

This library handle classes generation, classes caching and it implements the Type Safe Enumeration design pattern, with several helper methods for dealing with enums, like retrieving an ordinal for enums sorting, or retrieving a binary value, for enums combinations.

这个库处理类生成、类缓存,它实现了类型安全枚举设计模式,有几个用于处理枚举的辅助方法,比如检索枚举排序的序数,或检索二进制值,用于枚举组合。

The generated code use a plain old php template file, which is also configurable, so you can provide your own template.

生成的代码使用一个普通的旧 php 模板文件,该文件也是可配置的,因此您可以提供自己的模板。

It is full test covered with phpunit.

它是用 phpunit 覆盖的完整测试。

php-enums on github (feel free to fork)

github 上的 php-enums(随意 fork)

Usage: (@see usage.php, or unit tests for more details)

用法:(@see usage.php,或单元测试了解更多详情)

<?php
//require the library
require_once __DIR__ . '/src/Enum.func.php';

//if you don't have a cache directory, create one
@mkdir(__DIR__ . '/cache');
EnumGenerator::setDefaultCachedClassesDir(__DIR__ . '/cache');

//Class definition is evaluated on the fly:
Enum('FruitsEnum', array('apple' , 'orange' , 'rasberry' , 'bannana'));

//Class definition is cached in the cache directory for later usage:
Enum('CachedFruitsEnum', array('apple' , 'orange' , 'rasberry' , 'bannana'), '\my\company\name\space', true);

echo 'FruitsEnum::APPLE() == FruitsEnum::APPLE(): ';
var_dump(FruitsEnum::APPLE() == FruitsEnum::APPLE()) . "\n";

echo 'FruitsEnum::APPLE() == FruitsEnum::ORANGE(): ';
var_dump(FruitsEnum::APPLE() == FruitsEnum::ORANGE()) . "\n";

echo 'FruitsEnum::APPLE() instanceof Enum: ';
var_dump(FruitsEnum::APPLE() instanceof Enum) . "\n";

echo 'FruitsEnum::APPLE() instanceof FruitsEnum: ';
var_dump(FruitsEnum::APPLE() instanceof FruitsEnum) . "\n";

echo "->getName()\n";
foreach (FruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getName() . "\n";
}

echo "->getValue()\n";
foreach (FruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getValue() . "\n";
}

echo "->getOrdinal()\n";
foreach (CachedFruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getOrdinal() . "\n";
}

echo "->getBinary()\n";
foreach (CachedFruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getBinary() . "\n";
}

Output:

输出:

FruitsEnum::APPLE() == FruitsEnum::APPLE(): bool(true)
FruitsEnum::APPLE() == FruitsEnum::ORANGE(): bool(false)
FruitsEnum::APPLE() instanceof Enum: bool(true)
FruitsEnum::APPLE() instanceof FruitsEnum: bool(true)
->getName()
  APPLE
  ORANGE
  RASBERRY
  BANNANA
->getValue()
  apple
  orange
  rasberry
  bannana
->getValue() when values have been specified
  pig
  dog
  cat
  bird
->getOrdinal()
  1
  2
  3
  4
->getBinary()
  1
  2
  4
  8

回答by James Anderson

PHP has two (count them – 2) datatypes:

PHP 有两种(算上它们 - 2)数据类型:

  1. A single scalar value stored as a piece of text which is be converted to a number or boolean in an arithmetic or logical context where possible.

  2. The second structure is a hash (not an Array!) which is keyed by scalar text. If the key is a numeric value then the hash behaves very much like an array, but if it's a text value it behaves more like a classic perl hash.

  1. 存储为一段文本的单个标量值,在可能的情况下,在算术或逻辑上下文中将其转换为数字或布尔值。

  2. 第二个结构是一个散列(不是数组!),它由标量文本键控。如果键是一个数值,那么散列的行为非常像一个数组,但如果它是一个文本值,它的行为更像一个经典的 perl 散列。

You can 'fake' an enum using an inverted hash/array structure:

您可以使用反向散列/数组结构“伪造”枚举:

   $pretend_enum = array ( 'cent' => 1, 'nickel' => 2, 'dime' => 3 );
       if ($pretend_enum[$value]) {
           $encoded = $pretend_enum[$value];
   }   else {
           echo "$value is not a valid coin";
   } 

"Structures" are usually faked by having a hash with named members:

“结构”通常是通过具有命名成员的散列来伪造的:

 $ceedee = array('title' => "Making Movies", 'artist' => "Dire Straights", 'tracks' => 12);
 echo "My favourite CD is " . $ceedee['title'];