Wstęp
Cześć moi mili 🐻
Wstrzykiwanie kodu nie od dzisiaj się wykonuje. Z resztą czasami się słyszy o atakach hackerskich, które wykorzystują taki mechanizm. Dzisiaj jednak nie do końca będzie o tym, bo i może pokaże jak zrobić code injection, ale to nie będzie nic ponad to co się robi w swoim kodzie. Zatem dzisiaj przedstawię i wyjaśnię wam jak działa Trait w PHP oraz co to jest code injection.
Code injection
Co by tu dużo mówić? 😅 Jest to wstrzykiwanie kodu do już istniejącego. Taki mechanizm można użyć do hackowania, ale i też do ułatwienia sobie tworzenia kodu. Ale tak w ogóle, po co sobie ten kod wstrzykiwać? Nie można dziedziczyć czy po prostu go napisać tam gdzie ma być? No można, ale jednak dziedziczenie nie zawsze załatwi sprawę, a pisanie tego samego kodu w wielu klasach to zalicza się pod powtarzanie się.
Załóżmy, że mamy wiele ORM-owych encji…… no, a bardziej po ludzku to wiele klas, które są obiektowym odbiciem bazy danych….. Czy da się to prościej opisać? 🤔 i jesteśmy ograniczonym liniowym dziedziczeniem czyli każda klasa może dziedziczyć maksymalnie tylko po jednej klasie. Aby stworzyć dobrze działającą orm-ową encję załóżmy, że ona dziedziczy po abstrakcyjnej klasie, która ma swoje mechaniki, dzięki którym dziedziczone po niej klasy mają ułatwione zadanie bycia obiektami bazy danych. Teraz, możemy zauważyć, że w wielu, ale nie każdej, z naszej encji powtarzają się własności id, uuid, create_date, update_date, których nie możemy załatwić dziedziczeniem z prostego powodu: nie każda encja posiada te pola i nie powinna ich posiadać (nawet id nie zawsze występuje).
Zatem jesteśmy skazani na przepisywanie tych własności w kółko i w kółko? Otóż nie! Dzięki code injection możemy zrobić osobne zasoby do wstrzykiwania tych własności, dzięki czemu wystarczy ich tylko użyć, aby mieć oczekiwane własności, ale i nie tylko. Pamiętajcie, że gettery i settery też możemy tak dodać, a w zasadzie każdą metodę i własność.
Trait
Dla języka PHP z takim jednym z ładniejszych sposobów wstrzykiwania jest utworzenie Trait. Generalnie to wygląda jak pisanie klasy, więc jeśli umiesz stworzyć klasę to trait nie przysporzy Tobie problemów.
Przykład
trait IdTrait
{
private int $id;
public function id() : int
{
return $this->id;
}
}
trait UuidTrait
{
private string $uuid;
public function uuid() : string
{
return $this->uuid;
}
}
trait DateTrait
{
private \DateTime $createAt;
private \DateTime $updateAt;
public function createAt() : \DateTime
{
return $this->createAt;
}
public function updateAt() : \DateTime
{
return $this->updateAt;
}
}
i tak oto w prosty sposób utworzyliśmy trzy Trait-y. Jeden pod id, drugi pod uuid i trzeci pod daty.
Teraz w każdej klasie gdzie musielibyśmy pisać z osobna ten kod z Trait-ów wystarczy tylko użyć słowa kluczowego use w ciele klasy:
class User
{
use IdTrait, UuidTrait, DateTrait;
// ... reszta kodu
}
class Role
{
use IdTrait;
// ... reszta kodu
}
class Product
{
use IdTrait, DateTrait;
// ... reszta kodu
}
i to wystarczy, aby wykorzystywać to co posiadają dane Trait-y
Co do poszerzenia wiedzy na ich temat polecam dokumentację: https://www.php.net/manual/en/language.oop5.traits.php z niej dowiecie m.in. co robić gdy np. oba Trait-y mają takie same nazewnictwo własności i metod.
Podsumowanie
I to już na dzisiaj. Bardzo liczę na to, że pokazałem coś ciekawego. Dajcie feedback i znać o tym co byście chcieli jeszcze przeczytać – jestem otwarty na propozycje.
Dziękuję że jesteście ze mną i trzymajcie się cieplusio 🫂
Planuje coś enterek o unit testach robić?
🐢
[…] (do nazw) oraz kilka innych do przećwiczenia temat. Do implementacji interfejsu IMob wykorzystam Trait (o którym pisałem tutaj), aby część kodu nie pisać dwa […]