enumerations - ¿PHP tiene estructuras o enumeraciones y, de no ser así, cuál es la mejor implementación para ellos?
myclabs enum (6)
Esta pregunta ya tiene una respuesta aquí:
- PHP y enumeraciones 37 respuestas
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
¿Hay una palabra clave typedef
en PHP tal que pueda hacer algo como:
typedef struct {
} aStructure;
o
typedef enum {
aType1,
aType2,
} aType;
EDITAR
Finalmente respondí mi propia pregunta a continuación (omita la primera respuesta reciente). enum
función de enum
personalizada que cumple exactamente lo que estaba pidiendo, pero sin definición de tipo.
Aquí hay una biblioteca github para manejar enumeraciones seguras de tipos en php:
Esta biblioteca maneja la generación de clases, el almacenamiento en caché de clases e implementa el patrón de diseño de Type Safe Enumeration, con varios métodos de ayuda para tratar las enumeraciones, como recuperar un ordinal para ordenar las enumeraciones, o recuperar un valor binario, para combinaciones de enumeraciones.
El código generado utiliza un archivo de plantilla php antiguo, que también es configurable, para que pueda proporcionar su propia plantilla.
Es prueba completa cubierta con phpunit.
php-enums en github (no dude en bifurcar)
Uso: (@see use.php, o pruebas de unidad para más detalles)
<?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";
}
Salida:
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
De hecho, creé mi propio tipo de enumeración para PHP y funciona bien para lo que necesito hacer. no typedefs pero es agradable: D
Función 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
}
Uso (EJEMPLO):
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)
}
Es una extensión llamada SPL_Types , pero esta extensión casi no tiene alojamiento web disponible Y ya no se mantiene . Así que lo mejor sería usar clases para estructuras. y constantes para enumeraciones. Tal vez con la ayuda de la extensión SPL formato, que se encuentra en casi todas las instalaciones de php 5.X disponibles, podrías crear un "hack de enumeración sucio y malvado"
PHP tiene dos tipos de datos (cuéntelos - 2 ):
Un único valor escalar almacenado como un fragmento de texto que se convierte a un número o booleano en un contexto aritmético o lógico, cuando sea posible.
La segunda estructura es un hash (¡no un Array!) Que está codificado por texto escalar. Si la clave es un valor numérico, el hash se comporta de manera muy parecida a una matriz, pero si es un valor de texto, se comporta más como un hash de Perl clásico.
Puede "falsificar" una enumeración utilizando una estructura de matriz / matriz invertida:
$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";
}
Las "estructuras" generalmente se simulan teniendo un hash con miembros nombrados:
$ceedee = array(''title'' => "Making Movies", ''artist'' => "Dire Straights", ''tracks'' => 12);
echo "My favourite CD is " . $ceedee[''title''];
Puedes hacer algo similar con constantes, pero no es lo mismo que una enumeración dedicada.
Tendrá que ir con matrices o, si necesita algo que tenga un tipo personalizado, clases y objetos.