Novinky v PhpGenerator v3.5

před 11 měsíci od David Grudl  

PhpGenerator se naučil všechny vymoženosti PHP 8. Pojďme se podívat, jak je můžete hned začít používat.

Constructor Property Promotion

Velmi sympatickou novinkou PHP 8 je constructor property promotion, tedy syntaktický cukr, který ušetří dvojí psaní typu a čtyřnásobné psaní proměnné. „Promoted“ parametry přidáme pomocí addPromotedParameter() a lze je kombinovat s klasickými parametry přidávanými metodou addParameter():

use Nette\PhpGenerator\ClassType;

$class = new ClassType('Facade');
$method = $class->addMethod('__construct');

$method->addPromotedParameter('db')
	->setPrivate()
	->setType(Nette\Database\Connection::class);

$method->addPromotedParameter('mailer')
	->setPrivate()
	->setType(Nette\Mail\Mailer::class);

$method->addParameter('foo');

echo $class;

Výsledek:

class Facade
{
	public function __construct(
		private Nette\Database\Connection $db,
		private Nette\Mail\Mailer $mailer,
		$foo,
	) {
	}
}

Můžete si všimnout další novinky, že PhpGenerator vypisuje koncovou čárku v definici parametrů, když je použita PHP 8 syntax.

Atributy

PHP 8 atributy přinášejí zcela nový způsob, jak zapisovat strukturovaná metadata ke třídám a všem jejím členům, taktéž funkcím, closurám a jejich parametrům. Tohle vše podporuje také PhpGenerator a každý prvek disponuje nově metodami addAttribute(string $name, array $args = []), setAttributes(Attribute[] $attrs) a getAttributes(): Attribute[].

use Nette\PhpGenerator\PhpNamespace;
use Nette\PhpGenerator\Literal;

$namespace = new PhpNamespace('');
$namespace->addUse(Nette\Application\Attributes::class);

$class = $namespace->addClass('SomePresenter');

$class->addAttribute('FooBar', [
	'foo' => new Literal('Foo::BAR'),
	'bar' => [1, 2, 3]
]);

$class->addProperty('page')
	->setType('int')
	->addAttribute(Nette\Application\Attributes\Persistent::class);

echo $class;

Vygeneruje:

#[FooBar(foo: Foo::BAR, bar: [1, 2, 3])]
class SomePresenter
{
	#[Attributes\Persistent]
	public int $page;
}

Jak vidíte, pro atributy se využívají use statements. A dokonce je lze kombinovat i s promoted parametry.

Typy

Na místech všech typehintů lze nově uvádět union typy a to v podobě řetězce se svislítky. Řetězec si můžete nechat vygenerovat také pomocí Type::union().

use Nette\PhpGenerator\Type;
use Nette\PhpGenerator\GlobalFunction;

$function = (new GlobalFunction('twice'))
	->setReturnType('int|float')
	->setBody('return $a * 2;');

$function->addParameter('a')
	->setType(Type::union(Type::INT, Type::FLOAT));

echo $function;

Vypíše:

function twice(int|float $a): int|float
{
	return $a * 2;
}

Pokud parametru nastavíme setNullable(), vygeneruje se korektně int|float|null.

Podporovány jsou i všechny další datové typy, jako například mixed atd.

Pojmenované parametry

Při generování PHP kódu pomocí addBody(), setBody() nebo Dumper::format() lze používat i pojmenované parametry. Klasické poziční parametry vložíme přes placeholder ...?

$items = [1, 2, 3];
$function->setBody('myfunc(...?);', [$items]);
// myfunc(1, 2, 3);

Pro pojemnované parametry se používá ...?:

$items = ['foo' => 1, 'bar' => true];
$function->setBody('myfunc(...?:);', [$items]);
// myfunc(foo: 1, bar: true);

Další čtení