Skip to content

Commit

Permalink
加上 isXxx 实例方法
Browse files Browse the repository at this point in the history
  • Loading branch information
lip8up committed Mar 24, 2022
1 parent 97d962f commit 5316791
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
30 changes: 28 additions & 2 deletions src/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,25 @@ public static function isValidLabel(string $label): bool
return in_array($label, self::allLabels());
}

/**
* 自定义 __call,实现子类 isXxx() 调用,Xxx 为枚举 key。
*
* @link https://www.php.net/manual/zh/language.oop5.overloading.php#object.call
*/
public function __call(string $name, array $arguments)
{
// 支持 isXxx() 调用
if (substr($name, 0, 2) === 'is' && count($arguments) == 0) {
$key = substr($name, 2);
$enum = self::fromKey($key);
if ($enum !== null) {
return $enum->value() === $this->value;
} else {
static::throwBadMethod($key);
}
}
}

/**
* 自定义 __callStatic,实现子类 Key 值作为方法调用。
*
Expand All @@ -346,22 +365,29 @@ public static function __callStatic(string $name, array $arguments)
if ($enum !== null) {
$value = $arguments[0];
return $enum->value() === $value;
} else {
static::throwBadMethod($key);
}
}

$class = static::class;
if (!isset(self::$instances[$class][$name])) {
$allConstants = self::allConstants();
if (!isset($allConstants[$name]) && !\array_key_exists($name, $allConstants)) {
$message = "No static method or enum constant '$name' in class " . $class;
throw new \BadMethodCallException($message);
static::throwBadMethod($name);
}
[$value, $label] = $allConstants[$name];
self::$instances[$class][$name] = new static($name, $value, $label);
}
return self::$instances[$class][$name];
}

private static function throwBadMethod(string $name)
{
$message = "No enum constant '$name' in class " . static::class;
throw new \BadMethodCallException($message);
}

/**
* 当被 json_encode 时的实际对象。
*
Expand Down
11 changes: 10 additions & 1 deletion tests/EnumTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public function testIsValidLabel()
$this->assertSame(Other::isValidLabel('bi'), false);
}

public function testIsXxxCall()
public function testIsXxxStaticCall()
{
$this->assertTrue(Some::isOne(1));
$this->assertFalse(Some::isOne('1'));
Expand All @@ -256,6 +256,15 @@ public function testIsXxxCall()
$this->assertFalse(Some::isXxx(1));
}

public function testIsXxxCall()
{
$this->assertTrue(Some::One()->isOne());
$this->assertTrue(Some::Two()->isTwo());
$this->assertFalse(Some::Two()->isOne());
$this->expectException(\BadMethodCallException::class);
$this->assertFalse(Some::One()->isXxx());
}

public function testJsonEncode()
{
$this->assertSame(json_encode(Some::One()), '{"key":"One","value":1,"label":"\u4e00"}');
Expand Down

0 comments on commit 5316791

Please sign in to comment.