PHP 8 ile gelen yeni özellik property promotion ilk başta kullanımlarda biraz tuhaf gelse de:) Zaman içinde gereksiz kod kalabalığından kurtulduğum için çok çok hoşuma gitti diyebilirim. Bu yazıda property promotion özelliğini detaylıca ele almak istiyorum.
Şöyle ki önceden misal bir DTO class ı yazacak olduğumuzda. Şöyle birşey çıkıyordu ortaya. Tabii gerçek uygulamalarda çok daha büyük DTO lar göz korkutucu olabiliyordu.
class UserDTO
{
/**
* @var string
*/
public string $name;
/**
* @var string
*/
public string $email;
/**
* @var int
*/
public int $status;
/**
* @param string $name
* @param string $email
* @param int $status
*/
public function __construct(
string $name,
string $email,
int $status
) {
$this->name = $name;
$this->email = $email;
$this->status = $status;
}
//..
}
Bu uzun kod buloğunun yerine artık property promotion ile şöyle kullanabiliyoruz.
class UserDTO
{
public function __construct(
public string $name,
public string $email,
public int $status,
) {}
}
Peki nasıl bir yapısı olduğuna gelecek olursak kod çalıştırılmadan önce property promotion özelliği ile yazılmış kod eski haline dönüştürülüyor tıpkı Js transpiler işleminde olduğu gibi.
Önceki kullanımla property promotion özelliğini beraber kullan kullanabiliyoruz ama bence kodun okunabiliritesi düşüyor.
class User
{
public string $name;
public function __construct(
public string $email,
string $name,
) {
$this->name = $name;
}
}
Ama aynı tanımlamayı her iki tarafta da yapamıyoruz.
class User
{
public string $name; //syntax error
public function __construct(
public string $name, //syntax error
) {}
}
Php 7.4 ile gelen type cast özelliği olmadan kullanabiliyoruz. Önemli gibi değil hatta gerekiz gibi gözükebilir ama özellikle generic başı işlemlerde ve DTO larda kullanılabiliritesi yüksek gibi.
class User
{
public function __construct(
public $untypedProperty,
) {}
}
Tabii bazı yasaklarıyla beraber geliyor ki bence de gerekli kısıtlar bunlar.
“new” keyword ünü constructor içerisinde kullanamıyoruz.
class User
{
public function __construct(
public string $name = 'Recai',
public Status $status = new Status(), // Thrown Exception
) {}
}
Value object kullanımı için kullanımı ise.
class EmailValueObject
{
/**
* @throws Exception
*/
public function __construct(
public string $email
) {
if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Email is not correct");
}
//..
}
}
Yine php 8 ile gelen attribte özelliyle beraber kullanımı ise daha bir güzel diyebilirim.
class EmailValueObject
{
/**
* @throws Exception
*/
public function __construct(
#[LogAttribute]
public string $email
) {
if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
throw new Exception("Email is not correct");
}
//..
}
}
Abstarction constructor da kullanılmadığı gibi ki benim şu ana kadar hiç ihtiyacım olmadı diyebilirim. Trait içersine gömülen __constructor methodu içerisinde de kullanılamıyor. “var” keywordu ve vairadic pamatere ile de kullanılamıyor.
Aslına bakarsanız kullanılamayan durumlar ya çok gerekiz durumlar ya da dilin yapısallığı korumak adına alınmış karar bence. Nihai olarak çok kullanışlı ve okunabilirliği arttıran bir özellik. Diğer yazılarda görüşmek üzere. Sevgilerle 🙂
İlk Yorumu Siz Yapın