1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Core;
6:
7: /**
8: * This trait implements https://github.com/php/php-src/pull/7390 for lower PHP versions
9: * and also emit a warning when isset() is called on undefined variable.
10: */
11: trait WarnDynamicPropertyTrait
12: {
13: protected function warnPropertyDoesNotExist(string $name): void
14: {
15: // match native PHP behaviour as much as possible
16: // https://3v4l.org/2KR3m
17: $class = static::class;
18: try {
19: $propRefl = new \ReflectionProperty($class, $name);
20: if (!$propRefl->isPrivate() && !$propRefl->isPublic() && !$propRefl->isStatic()) {
21: throw new \Error('Cannot access protected property ' . $class . '::$' . $name);
22: }
23: } catch (\ReflectionException $e) {
24: }
25:
26: 'trigger_error'('Undefined property: ' . get_debug_type($this) . '::$' . $name, \E_USER_WARNING);
27: }
28:
29: public function __isset(string $name): bool
30: {
31: $this->warnPropertyDoesNotExist($name);
32:
33: return isset($this->{$name});
34: }
35:
36: /**
37: * @return mixed
38: */
39: public function &__get(string $name)
40: {
41: $this->warnPropertyDoesNotExist($name);
42:
43: return $this->{$name};
44: }
45:
46: /**
47: * @param mixed $value
48: */
49: public function __set(string $name, $value): void
50: {
51: $this->warnPropertyDoesNotExist($name);
52:
53: $this->{$name} = $value;
54: }
55:
56: public function __unset(string $name): void
57: {
58: $this->warnPropertyDoesNotExist($name);
59:
60: unset($this->{$name});
61: }
62: }
63: