<?php
#[Attribute]
class Getter{}
#[Attribute]
class Setter{}
class SetterGetterException extends Exception{}
trait SetterGetter
{
private function getFieldNameFromMethodName(string $methodName): string
{
$fieldName = mb_substr($methodName, 3);
$fieldNameFirstChar = mb_strtolower(mb_substr($fieldName, 0, 1));
$fieldNameLastChars = mb_substr($fieldName, 1);
$fieldName = $fieldNameFirstChar . $fieldNameLastChars;
return $fieldName;
}
private function methodAllowedToBeUsedOnProperty(string $methodName, object $object, string $fieldName): array
{
$methods = [];
$property = new ReflectionProperty(get_class($object), $fieldName);
$properties = $property->getAttributes();
foreach ($properties as $property) {
$methodName = $property->getName();
if ($methodName === 'Setter') {
$methods[] = 'set';
} elseif ($methodName === 'Getter') {
$methods[] = 'get';
}
}
return $methods;
}
public function __call(string $name, array $arguments)
{
$prefix = mb_substr($name, 0, 3);
if ($prefix !== 'get' && $prefix !== 'set') {
throw new SetterGetterException('Из необъявленных методов этого класса можно вызывать только геттер и сеттер.');
}
$fieldName = $this->getFieldNameFromMethodName($name);
if (!property_exists(get_class($this), $fieldName)) {
throw new SetterGetterException('В классе ' . get_class($object) . 'не существует свойства с именем' . $fieldName);
}
$methods = $this->methodAllowedToBeUsedOnProperty($name, $this, $fieldName);
if (!in_array($prefix, $methods)) {
throw new SetterGetterException('К этому полю нельзя обращаться через метод ' . $prefix);
}
if ($prefix === 'get') {
return $this->$fieldName;
} elseif ($prefix === 'set') {
if (count($arguments) !== 1) {
throw new SetterGetterException('В сеттер можно передавать только один аргумент.');
}
$fieldValue = $arguments[0];
$this->$fieldName = $fieldValue;
}
}
}
class Test
{
use SetterGetter;
#[Setter]
#[Getter]
private int $number;
}
$test = new Test();
$test->setNumber(5);
echo $test->getNumber();
- Output for 8.1.0 - 8.1.28, 8.2.0 - 8.2.19, 8.3.0 - 8.3.7
- 5
preferences:
86.41 ms | 402 KiB | 62 Q