2012-06-17 15 views
6

Estoy tratando de usar constante como un parámetro de función, ¿es posible verificar el tipo de esta constante.PHP: constante como variable en la función

ejemplo de lo que quiero:

class ApiError { 
    const INVALID_REQUEST = 200; 
} 

class Response { 
    public function status(ApiError $status) { 
    //function code here 
    } 
} 

USO:

$response = new Response(); 
$response->status(ApiError::INVALID_REQUEST); 

Este SHAUD comprobar que el estado de $ dada es constante de ApiError clase. Es algo como esto posible?

+0

estado (ApiError estado $) espera instancia de la clase ApiError no es el valor constante –

+0

que sé, es por eso que estoy pidiendo "¿Cómo hacer es " – m4recek

Respuesta

5

Puede utilizar in_array() para poner a prueba contra los valores de la lista blanca, que es una estrategia recomendada siempre que lo necesite validar la entrada a un conjunto de valores específicos:

// Test if it is in an array of valid status constants... 
$valid_statuses = array(
    ApiError::INVALID_REQUEST, 
    ApiError::INVALID_SOMETHINGELSE, 
    ApiError::STATUS_OK 
); 
if (in_array($status, $valid_statuses)) { 
    // it's an acceptable value 
} 

a la lista blanca todas las constantes de una clase, se podría utilizar la reflexión y recuperar las constantes de ApiErrorvia ReflectionClass::getconstants()

$refl = new ReflectionClass('ApiError'); 
$valid_statuses = $refl->constants(); 
10

Como los otros mencionados, no hay una solución genérica. Pero si desea hacerlo de una manera muy limpia, cada modelo de "objeto" que se está tratando con (= todos los estados posibles), por ejemplo:

interface ApiError { // make it an abstract class if you need to add logic 
    public function getCode(); 
} 

class InvalidRequestApiError implements ApiError { 
    public function getCode() { 
     return 200; 
    } 
} 

// Usage: 
$response = new Response(); 
$response->status(new InvalidRequestApiError()); 

class Response { 
    public function status(ApiError $status) { 
     echo "API status: " . $status->getCode(); 
    } 
    // ... 
} 

Esto le deja con un montón de clases , porque encapsulas números simples, pero también con la habilidad de escribir-insinuar.

+2

Odio la propuesta in_array() porque es una programación orientada a arreglos en lugar de orientada a objetos. –

0

me gusta este enfoque mejor:

class NoticeType { 
    const INFO = 'neutral'; 
    const WARN = 'alert'; 
    const FAIL = 'critical'; 
    const PASS = 'success'; 
    const LITE = 'brand'; 

    private $_type; 

    function __construct($NOTICE_constant) 
    { 
     if (!preg_match('/neutral|alert|critical|success|brand/', $NOTICE_constant)) 
      throw new \Exception('Invalid parameter for '.__CLASS__.' constructor'); 
     $this->_type = $NOTICE_constant; 
    } 
    function getType() { 
     return $this->_type; 
    } 
    function __toString() { 
     return $this->_type; 
    } 
    static function INFO() { 
     return new NoticeType(self::INFO); 
    } 
    static function WARN() { 
     return new NoticeType(self::WARN); 
    } 
    static function FAIL() { 
     return new NoticeType(self::FAIL); 
    } 
    static function PASS() { 
     return new NoticeType(self::PASS); 
    } 
    static function LITE() { 
     return new NoticeType(self::LITE); 
    } 
} 

Su uso es muy sencillo y que tendría que salir de su manera de estropear:

function test (NoticeType $n) { 
    echo ($n == NoticeType::INFO)."\n"; 
} 

test (NoticeType::INFO()); 
1

Otra posibilidad sería cambiar la llamada. Si queremos verificar si el const existe, esta línea sería demasiado tarde. $response->status(ApiError::INVALID_REQUEST);

El intérprete php también comprobará la const para la existencia y morirá con un error fatal. Eso no es atrapable con try().

Así que le sugiero utilizar cadena como parámetro para comprobar la existencia usando definido() y constante()

class ApiError { 
    const INVALID_REQUEST = 200; 
} 

class Response { 
    public function status($status) { 
    if (!defined('ApiError::'.$status)) { 
     return false; // Or throw Exception/other error handling 
    } 

    $errorCode = constant('ApiError::'.$status); 

    //function code here 
    return true; 
    } 
} 

El uso podría tener el siguiente aspecto:

$response = new Response(); 
$response->status('INVALID_REQUEST'); 

Lo malo es que no hay indicaciones de tipo para esta solución.

+0

IMO esta es la mejor respuesta si necesita mantener constantes. –

0

SplEnum podría ayudar. Ejemplo de documentación de PHP:

class Month extends SplEnum { 
    const __default = self::January; 

    const January = 1; 
    const February = 2; 
    const March = 3; 
    const April = 4; 
    const May = 5; 
    const June = 6; 
    const July = 7; 
    const August = 8; 
    const September = 9; 
    const October = 10; 
    const November = 11; 
    const December = 12; 
} 

echo new Month(Month::June) . PHP_EOL; 

try { 
    new Month(13); 
} catch (UnexpectedValueException $uve) { 
    echo $uve->getMessage() . PHP_EOL; 
} 

Salida:

6 
Value not a const in enum Month 
Cuestiones relacionadas