Does PHP have structs or enums and if not what is the best implementation for them?
PHP中是否有EDOCX1[1]关键字,以便我可以执行以下操作:
1 2 3 | typedef struct { } aStructure; |
或
1 2 3 4 | typedef enum { aType1, aType2, } aType; |
编辑
我最终在下面回答了我自己的问题(跳过最近的第一个答案)。我创建了一个自定义的
实际上,我为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']; |