Skip to content

Instantly share code, notes, and snippets.

@koohq
Created September 24, 2018 13:52
Show Gist options
  • Save koohq/b39e22f3ee68ad0bdaff0c9a88ff092a to your computer and use it in GitHub Desktop.
Save koohq/b39e22f3ee68ad0bdaff0c9a88ff092a to your computer and use it in GitHub Desktop.
Provides mechanism for read-only property that relieves __get implementation.
<?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);
}
}
}
}
<?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