Nette PHP Generator přináší sílu PHP 8.4
Property hooks a asymetrická viditelnost v PHP 8.4 představují velký skok v objektově orientovaném programování – konečně můžeme zapomenout na neohrabané gettery a settery. Nette PHP Generator přichází s podporou těchto novinek zároveň s vydáním PHP 8.4. A nabízí intuitivní způsob, jak tyto moderní features využít ve vašem kódu.
Zbavte se getterů a setterů
Představte si, že vytváříte třídu Person
a chcete
validovat věk. Dříve by váš kód musel vypadat nějak takto:
class Person
{
private int $age;
public function setAge(int $age): void
{
if ($age < 0) {
throw new \InvalidArgumentException;
}
$this->age = $age;
}
public function getAge(): int
{
return $this->age;
}
}
S property hooks je kód elegantnější a přehlednější:
class Person
{
public int $age {
set {
if ($value < 0) {
throw new \InvalidArgumentException;
}
$this->age = $value;
}
}
}
Vygenerovat tento kód je s Nette PhpGenerator snadné. Stačí využít
novou metodu addHook()
:
$class = new ClassType('Person');
$class->addProperty('age')
->setType('int')
->addHook('set')
->setBody(<<<'PHP'
if ($value < 0) {
throw new InvalidArgumentException;
}
$this->age = $value;
PHP);
Nabízí se také použít zkrácenou syntaxi:
$class = new ClassType('Person');
$class->addProperty('age')
->setType('int')
->addHook('set', '$value >= 0 ? $value : throw new \\InvalidArgumentException');
Která vygeneruje „short-setter“:
class Person
{
public int $age {
set => $value >= 0 ? $value : throw new \InvalidArgumentException;
}
}
Property v rozhraních a abstraktních třídách
Ano, konečně lze v PHP používat properties v rozhraních a abstraktních třídách. Nejprve vytvoříme vlastnost v rozhraní:
$interface = new Nette\PhpGenerator\InterfaceType('Named');
$interface->addProperty('name')
->setType('string')
->addHook('get'); // Vyžaduje pouze čtení
Vygeneruje:
interface Named
{
public string $name { get; }
}
Toto je příklad abstraktní třídy, která kombinuje abstraktní setter a konkrétní getter:
$abstract = new Nette\PhpGenerator\ClassType('Person')
->setAbstract();
$prop = $abstract->addProperty('email')
->setType('string')
->setAbstract(); // Abstraktní property
$prop->addHook('set') // Abstraktní setter
->setAbstract();
$prop->addHook('get', '$this->email'); // Konkrétní getter
Vygeneruje:
abstract class Person
{
public string $email {
set;
get => $this->email;
}
}
A nakonec implementující třída. Tady nám pomůže
ClassManipulator
:
$class = new ClassType('Employee');
// Pomocí manipulátoru implementujeme Person a Named
$manipulator = new Nette\PhpGenerator\ClassManipulator($class);
$manipulator->implement('Person'); // přidá property email
$manipulator->implement('Named'); // přidá property name
// Dodáme implementaci abstraktní property z Person
$class->getProperty('email')
->addHook('set')
->setBody(<<<'PHP'
if (!Nette\Utils\Validators::isEmail($value)) {
throw new InvalidArgumentException;
}
$this->email = $value;
PHP);
echo $class;
Vygeneruje:
class Employee extends Person implements Named
{
public string $email {
set {
if (!Nette\Utils\Validators::isEmail($value)) {
throw new InvalidArgumentException;
}
$this->email = $value;
}
}
public string $name;
}
Asymetrická viditelnost: přesná kontrola přístupu
Asymetrická viditelnost přináší do PHP jemnější kontrolu nad tím, kdo může číst a kdo zapisovat do vlastností objektu.
Viditelnost lze nastavit buď pomocí metody setVisibility()
se
dvěma parametry, nebo pomocí setPublic()
,
setProtected()
nebo setPrivate()
s parametrem
mode
, který určuje, zda se viditelnost vztahuje ke čtení nebo
zápisu vlastnosti. Výchozí režim je 'get'
.
$class = new Nette\PhpGenerator\ClassType('Demo');
$class->addProperty('name')
->setType('string')
->setVisibility('public', 'private'); // public pro čtení, private pro zápis
$class->addProperty('id')
->setType('int')
->setProtected('set'); // protected pro zápis
Vygeneruje:
class Demo
{
public private(set) string $name;
protected(set) int $id;
}
Asymetrickou viditelnost můžete efektivně kombinovat s property hooks a využít v hierarchii tříd.
Všechny tyto novinky jsou plně podporovány v metodách ClassLike::from()
pro generování z existujících tříd a ClassLike::fromCode()
pro načítání ze zdrojových souborů. Pro správnou funkci
fromCode()
je vyžadován balíček nikic/php-parser minimálně ve
verzi 5.3.1.
Podpora těchto revolučních features přichází s verzí Nette PHP Generator 4.1.7.
Chcete-li odeslat komentář, přihlaste se