Есть ли у PHP структуры или перечисления, а если нет, то какая из них лучшая для них?
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 ключевое слово typedef
, так что я могу сделать что-то вроде:
typedef struct {
} aStructure;
или
typedef enum {
aType1,
aType2,
} aType;
ИЗМЕНИТЬ
В конце концов я ответил на свой вопрос ниже (пропустите первый недавний ответ). Я создал пользовательскую функцию enum
, которая выполняет именно то, что я просил, но без определения типа.
Ответы
Ответ 1
Я действительно создал свой собственный enum для PHP, и он отлично работает для того, что мне нужно делать. нет typedefs, но его приятно: D
Функция enum ($ 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, $asBitwise = false) {
if(!is_array($array) or count($array) < 1) return false; // Error incorrect type
$n = 0; // Counter variable
foreach($array as $i) {
if($i === null) {
if($n == 0) {
if(!define($i, 0)) return false;
} else
if(!define($i, $asBitwise ? 1 << ($n - 1) : $n)) return false;
} $n++;
} return true; // Successfully defined all variables
}
Использование (ПРИМЕР):
enum(array(
'BrowserTypeUnknown', // 0
'BrowserTypeIE', // 1
'BrowserTypeNetscape', // 2
'BrowserTypeOpera', // 3
'BrowserTypeSafari', // 4
'BrowserTypeFirefox', // 5
'BrowserTypeChrome', // 6
)); // BrowserType as 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(array(
'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)
}
Ответ 2
Нет.
Вам нужно будет использовать массивы или, если вам требуется что-то, у которого есть собственный тип, классы и объекты.
Ответ 3
Вы можете сделать что-то подобное с константами, но это не то же самое, что выделенное перечисление.
Ответ 4
Это расширение, называемое SPL_Types, но это расширение почти не имеет доступного веб-хостинга И его больше не поддерживается.
Поэтому лучше всего использовать классы для структур. и константы для перечислений.
возможно, с помощью простого расширения SPL, которое доступно почти в каждой установке php 5.X, вы можете создать несколько "злых грязных" enum hack "
Ответ 5
Вот библиотека github для обработки перечислимых типов в php:
Эта библиотека обрабатывает генерации классов, кэширует классы и реализует шаблон проектирования типа Safe Enumeration с несколькими вспомогательными методами для обработки перечислений, например, для получения ординала для сортировки перечислений или для получения двоичного значения для комбинаций перечислений.
Сгенерированный код использует простой старый файл шаблона php, который также настраивается, поэтому вы можете предоставить свой собственный шаблон.
Это полный тест, охватываемый phpunit.
php-enums на github (не стесняйтесь вилки)
Использование: (@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";
}
Вывод:
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
Ответ 6
PHP имеет два типа (count them – 2):
-
Единое скалярное значение, хранящееся как часть текста, которая, если возможно, преобразуется в число или логически в арифметическом или логическом контексте.
-
Вторая структура - это хеш (не массив), который определяется скалярным текстом. Если ключ представляет собой числовое значение, то хеш ведет себя очень похоже на массив, но если это текстовое значение, оно больше похоже на классический хэш-код perl.
Вы можете "подделать" перечисление, используя инвертированную структуру хэша/массива:
$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";
}
"Структуры" обычно подделываются с помощью хэша с именованными членами:
$ceedee = array('title' => "Making Movies", 'artist' => "Dire Straights", 'tracks' => 12);
echo "My favourite CD is " . $ceedee['title'];