PHP是否有结构或枚举,如果没有,最好的实现是什么?

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

本问题已经有最佳答案,请猛点这里访问。

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

PHP中是否有EDOCX1[1]关键字,以便我可以执行以下操作:

1
2
3
typedef struct {

} aStructure;

1
2
3
4
typedef enum {
  aType1,
  aType2,
} aType;

编辑

我最终在下面回答了我自己的问题(跳过最近的第一个答案)。我创建了一个自定义的enum函数,它可以完全实现我所要求的功能,但没有类型定义。


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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<wyn>

    /*
     * 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

    }

</wyn>

用法(示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<wyn>

    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)
    }

</wyn>


不。

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


它们是一个名为spl_-types的扩展,但是这个扩展几乎没有可用的Web宿主,并且不再维护。所以最好是为结构使用类。以及枚举的常量。也许在普通SPL扩展的帮助下,几乎在每一个可用的php5.x安装中,您都可以构建一些"邪恶肮脏的枚举黑客"。


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


下面是一个Github库,用于处理PHP中的类型安全枚举:

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

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

这是一个用phpunit覆盖的完整测试。

Github上的php枚举(可以自由使用fork)

用法:(@有关详细信息,请参阅usage.php或单元测试)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?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
ame\space'
, true);

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

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

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

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

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

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

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

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

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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


php有两个(count them&ndash;2)数据类型:

  • 存储为一段文本的单个标量值,可以在算术或逻辑上下文中转换为数字或布尔值。

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

  • 可以使用倒置的哈希/数组结构"假"枚举:

    1
    2
    3
    4
    5
    6
       $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"通常是通过具有命名成员的哈希来伪造的:

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