[英]PHP: constant as variable in function
我試圖使用常量作為函數參數,是否可以檢查此常量的類型。
我想要的例子:
class ApiError {
const INVALID_REQUEST = 200;
}
class Response {
public function status(ApiError $status) {
//function code here
}
}
使用:
$response = new Response();
$response->status(ApiError::INVALID_REQUEST);
這個給定$ status的shoud檢查是ApiError類的常量。 這樣的事情可能嗎?
正如其他人提到的那樣,沒有通用的解決方案。 但是如果你想以一種非常干凈的方式做到這一點,那就建模你正在處理的每個“對象”(=每個可能的狀態),例如:
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();
}
// ...
}
這會留下很多類,因為您封裝了簡單的數字,但也具有類型提示功能。
您可以使用in_array()
來測試列入白名單的值,這是您需要驗證特定值集的輸入時的推薦策略:
// 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
}
要將類的所有常量列入白名單,可以使用反射並通過ReflectionClass::getconstants()
從ApiError
檢索常量
$refl = new ReflectionClass('ApiError');
$valid_statuses = $refl->constants();
另一種方法是改變呼叫。 如果我們想檢查const是否存在,那么這條線就太晚了。 $response->status(ApiError::INVALID_REQUEST);
php解釋器還將檢查const是否存在並將死於致命錯誤。 這不是使用try()捕獲的。
所以我建議使用string作為參數來檢查使用defined()和constant()的存在性
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;
}
}
然后使用看起來像這樣:
$response = new Response();
$response->status('INVALID_REQUEST');
不好的是,這個解決方案沒有類型提示。
我最喜歡這種方法:
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);
}
}
使用非常簡單,你不得不自己搞砸了:
function test (NoticeType $n) {
echo ($n == NoticeType::INFO)."\n";
}
test (NoticeType::INFO());
SplEnum可以提供幫助。 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;
}
輸出:
6
Value not a const in enum Month
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.