Created
September 24, 2018 13:52
-
-
Save koohq/b39e22f3ee68ad0bdaff0c9a88ff092a to your computer and use it in GitHub Desktop.
Provides mechanism for read-only property that relieves __get implementation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* PropertyReadable.php | |
* | |
* (c) 2018 koohq. Licensed under CC0. | |
* https://creativecommons.org/publicdomain/zero/1.0/legalcode | |
*/ | |
trait PropertyReadable | |
{ | |
/** @var array [string => string|callable] */ | |
protected $accessors = []; | |
public function __get($name) | |
{ | |
if (isset($this->accessors[$name])) { | |
$accessor = $this->accessors[$name]; | |
if (is_string($accessor) && property_exists($this, $accessor)) { | |
return $this->$accessor; | |
} | |
if (is_callable($accessor)) { | |
return call_user_func($accessor); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @property-read string $name | |
* @property-read string $altName | |
* @property-read bool $isNameEmpty | |
* @property-read bool $isNameNull | |
* @property-read int $count | |
* @property-read int $randomInt | |
*/ | |
class Sample | |
{ | |
use PropertyReadable; | |
/** @var string $name */ | |
private $name; | |
/** @var int $time Unix timestamp when $this is created */ | |
private $time; | |
public function __construct($name) | |
{ | |
$this->name = (string)$name; | |
$this->time = time(); | |
// Register accessors | |
$this->accessors = [ | |
// propertyName => propertyName [this returns $this->name] | |
'name' => 'name', | |
// propertyName => otherPropertyName [Alias] | |
'altName' => 'name', | |
// propertyName => propertyName(also globalFunction) [this returns $this->time, not time()] | |
'time' => 'time', | |
// propertyName => closure | |
'isNameEmpty' => function () { return empty($this->name); }, | |
// propertyName => instanceMethod | |
'isNameNull' => [$this, 'isNameNull'], | |
// propertyName => staticMethod | |
'count' => 'self::countUp', | |
// propertyName => globalFunction [this returns rand()] | |
'randomInt' => 'rand', | |
]; | |
} | |
/** @return bool indicates $this->name is null */ | |
private function isNameNull() | |
{ | |
return $this->name === null; | |
} | |
/** @return int number that is incremented on each call */ | |
private static function countUp() | |
{ | |
static $counter = 0; | |
return $counter++; | |
} | |
} | |
/** | |
* Sample (No use PropertyReadable) | |
* | |
* @property-read string $name | |
* @property-read string $altName | |
* @property-read bool $isNameEmpty | |
* @property-read bool $isNameNull | |
* @property-read int $count | |
* @property-read int $randomInt | |
*/ | |
class Sample2 | |
{ | |
/** @var string $name */ | |
private $name; | |
/** @var int $time Unix timestamp when $this is created */ | |
private $time; | |
public function __construct($name) | |
{ | |
$this->name = (string)$name; | |
$this->time = time(); | |
} | |
// Define __get manually... | |
public function __get($name) | |
{ | |
switch ($name) { | |
case 'name': | |
return $this->name; | |
case 'altName': | |
return $this->name; | |
case 'time': | |
return $this->time; | |
case 'isNameEmpty': | |
return empty($this->name); | |
case 'isNameNull': | |
return $this->isNameNull(); | |
case 'count': | |
return self::countUp(); | |
case 'randomInt': | |
return rand(); | |
default: | |
break; | |
} | |
} | |
/** @return bool indicates $this->name is null */ | |
private function isNameNull() | |
{ | |
return $this->name === null; | |
} | |
/** @return int number that is incremented on each call */ | |
private static function countUp() | |
{ | |
static $counter = 0; | |
return $counter++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment