我正在尝试使用常量作为函数参数,是否可以检查此常量的类型。
我想要的例子:
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类的常量。这样的事情可能吗?
答案 0 :(得分:11)
正如其他人所提到的,没有通用的解决方案。但是如果你想以一种非常干净的方式做到这一点,那就为你正在处理的每个“对象”(=每种可能的状态)建模,例如:
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();
}
// ...
}
这会给你留下很多类,因为你封装了简单的数字,但也具有类型提示的能力。
答案 1 :(得分:5)
您可以使用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
}
要将类的所有常量列入白名单,您可以使用反射并从ApiError
via ReflectionClass::getconstants()
$refl = new ReflectionClass('ApiError');
$valid_statuses = $refl->constants();
答案 2 :(得分:2)
另一种方法是更改通话。
如果我们想检查const是否存在,那么这条线就太晚了。
$response->status(ApiError::INVALID_REQUEST);
php解释器还将检查const是否存在,并将死于致命错误。 使用try()无法获取。
所以我建议使用字符串作为参数,使用 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');
不好的是,此解决方案没有类型提示。
答案 3 :(得分:0)
我最喜欢这种方法:
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());
答案 4 :(得分:0)
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