2012-06-17 12 views
6

Próbuję użyć stałej jako parametru funkcji, czy można sprawdzić typ tej stałej.PHP: stała jako zmienna w funkcji

Przykład czego chcę:

class ApiError { 
    const INVALID_REQUEST = 200; 
} 

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

USE:

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

Ten Powinni sprawdzić, czy dany stan jest stały $ klasy ApiError. Czy coś takiego jest możliwe?

+0

status (ApiError $ status) spodziewa się instancją klasy ApiError nie wartość stały –

+0

wiem, dlatego pytam: „Jak to zrobić it " – m4recek

Odpowiedz

5

Można użyć in_array() przetestować przed wartościami białej listy, która jest zalecana strategia kiedy trzeba potwierdzić wejście do określonego zestawu wartości:

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

do białej listy wszystkich stałych o klasie, można użyć refleksji i odzyskać stałe z ApiErrorvia ReflectionClass::getconstants()

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

Jak inni wspomniano, nie ma rodzajowe rozwiązanie. Ale jeśli chcesz to zrobić w bardzo czysty sposób, modelu każdy „obiekt”, że masz do czynienia z (= każdego możliwego stanu), np:

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(); 
    } 
    // ... 
} 

To pozostawia nam wiele klas , ponieważ hermetyzujesz proste liczby, ale także z możliwością wpisywania podpowiedzi.

+2

Nienawidzę propozycji in_array(), ponieważ jest to programowanie zorientowane na tablicę, w przeciwieństwie do obiektowego. –

0

Lubię to podejście najlepiej:

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

Użycie jest bardzo prosta i trzeba by wychodzić z drogi do bałagan:

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

test (NoticeType::INFO()); 
1

Innym rozwiązaniem byłoby zmień połączenie. Jeśli chcemy sprawdzić, czy istnieje stała, to linia będzie za późno. $response->status(ApiError::INVALID_REQUEST);

Interpreter php sprawdzi także konst byt i umrze z błędem krytycznym. Nie można tego odczytać za pomocą metody try().

więc proponuję użyć ciąg jako parametr do sprawdzenia istnienia korzystając zdefiniowany() i stałej()

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

Zastosowanie będzie wtedy wyglądać tak:

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

Źle jest, że nie ma wskazówek dla tego rozwiązania.

+0

IMO to najlepsza odpowiedź, jeśli chcesz zachować stałe. –

0

SplEnum może pomóc. Przykład z PHP docs:

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

wyjściowa:

6 
Value not a const in enum Month