Skip to content

Commit ab9e312

Browse files
committed
Added support for magic static methods
1 parent 60b8fdc commit ab9e312

File tree

3 files changed

+87
-18
lines changed

3 files changed

+87
-18
lines changed

README.md

+50-18
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,21 @@ class Action extends Enum
2727
{
2828
const VIEW = 'view';
2929
const EDIT = 'edit';
30-
31-
/**
32-
* @return Action
33-
*/
34-
public static function VIEW() {
35-
return new Action(self::VIEW);
36-
}
37-
38-
/**
39-
* @return Action
40-
*/
41-
public static function EDIT() {
42-
return new Action(self::EDIT);
43-
}
4430
}
4531
```
4632

47-
Implementing the static methods `VIEW()` and `EDIT()` is optional, it only serves as shortcut to `new Action(Action::VIEW)`.
48-
4933

5034
## Usage
5135

5236
```php
53-
$action = Action::VIEW();
37+
$action = new Action(Action::VIEW);
5438

5539
// or
56-
$action = new Action(Action::VIEW);
40+
$action = Action::VIEW();
5741
```
5842

43+
As you can see, static methods are automatically implemented to provide quick access to an enum value.
44+
5945
One advantage over using class constants is to be able to type-hint enum values:
6046

6147
```php
@@ -70,3 +56,49 @@ function setAction(Action $action) {
7056
- `__toString()` You can `echo $myValue`, it will display the enum value (value of the constant)
7157
- `getValue()` Returns the current value of the enum
7258
- `toArray()` (static) Returns an array of all possible values (constant name in key, constant value in value)
59+
60+
### Static methods
61+
62+
```php
63+
class Action extends Enum
64+
{
65+
const VIEW = 'view';
66+
const EDIT = 'edit';
67+
}
68+
69+
// Static method:
70+
$action = Action::VIEW();
71+
$action = Action::EDIT();
72+
```
73+
74+
Static method helpers are implemented using [`__callStatic()`](http://www.php.net/manual/en/language.oop5.overloading.php#object.callstatic).
75+
76+
If you care about IDE autocompletion, you can either implement the static methods yourself:
77+
78+
```php
79+
class Action extends Enum
80+
{
81+
const VIEW = 'view';
82+
83+
/**
84+
* @return Action
85+
*/
86+
public static function VIEW() {
87+
return new Action(self::VIEW);
88+
}
89+
}
90+
```
91+
92+
or you can use phpdoc (this is supported in PhpStorm for example):
93+
94+
```php
95+
/**
96+
* @method static Action VIEW()
97+
* @method static Action EDIT()
98+
*/
99+
class Action extends Enum
100+
{
101+
const VIEW = 'view';
102+
const EDIT = 'edit';
103+
}
104+
```

src/MyCLabs/Enum/Enum.php

+15
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,19 @@ public static function toArray()
6161
return $reflection->getConstants();
6262
}
6363

64+
/**
65+
* Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a class constant
66+
* @param string $name
67+
* @param array $arguments
68+
* @return static
69+
* @throws \BadMethodCallException
70+
*/
71+
public static function __callStatic($name, $arguments)
72+
{
73+
if (defined("static::$name")) {
74+
return new static(constant("static::$name"));
75+
}
76+
throw new \BadMethodCallException("No static method or enum constant '$name' in class " . get_called_class());
77+
}
78+
6479
}

tests/UnitTest/MyCLabs/Enum/EnumTest.php

+22
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,32 @@ public function testToArray()
8484
$this->assertEquals($expectedValues, $values);
8585
}
8686

87+
/**
88+
* __callStatic()
89+
*/
90+
public function testStaticAccess()
91+
{
92+
$this->assertEquals(new EnumFixture(EnumFixture::FOO), EnumFixture::FOO());
93+
$this->assertEquals(new EnumFixture(EnumFixture::BAR), EnumFixture::BAR());
94+
$this->assertEquals(new EnumFixture(EnumFixture::NUMBER), EnumFixture::NUMBER());
95+
}
96+
97+
/**
98+
* @expectedException \BadMethodCallException
99+
* @expectedExceptionMessage No static method or enum constant 'UNKNOWN' in class UnitTest\MyCLabs\Enum\Enum\EnumFixture
100+
*/
101+
public function testBadStaticAccess()
102+
{
103+
EnumFixture::UNKNOWN();
104+
}
105+
87106
}
88107

89108
/**
90109
* Fixture class
110+
* @method static EnumFixture FOO()
111+
* @method static EnumFixture BAR()
112+
* @method static EnumFixture NUMBER()
91113
*/
92114
class EnumFixture extends Enum
93115
{

0 commit comments

Comments
 (0)