[英]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.