SmartObject
SmartObject je leta izboljševal obnašanje objektov v PHP-ju. Od različice PHP 8.4 so vse njegove funkcije del samega PHP-ja, s čimer je zaključil svoje zgodovinsko poslanstvo biti pionir modernega objektno usmerjenega pristopa v PHP-ju.
Namestitev:
SmartObject je nastal leta 2007 kot revolucionarna rešitev pomanjkljivosti tedanjega objektnega modela PHP. V času, ko je PHP trpel zaradi številnih težav z objektno usmerjenim načrtovanjem, je prinesel pomembne izboljšave in poenostavil delo razvijalcem. Postal je legendarna komponenta ogrodja Nette. Ponujal je funkcionalnost, ki jo je PHP dobil šele mnogo let pozneje – od validacije dostopa do lastnosti objektov do naprednega ravnanja z napakami. S prihodom PHP 8.4 je zaključil svoje zgodovinsko poslanstvo, saj so vse njegove funkcije postale sestavni del jezika. Prehitel je razvoj PHP za izjemnih 17 let.
SmartObject je doživel zanimiv tehnični razvoj. Prvotno je bil implementiran kot razred Nette\Object
, od
katerega so drugi razredi podedovali potrebno funkcionalnost. Pomembna sprememba je prišla s PHP 5.4, ki je uvedel podporo za
trait-e. To je omogočilo preoblikovanje v trait Nette\SmartObject
, kar je prineslo večjo prilagodljivost –
razvijalci so lahko uporabljali funkcionalnost tudi v razredih, ki so že podedovali od drugega razreda. Medtem ko je prvotni
razred Nette\Object
prenehal obstajati s PHP 7.2 (ki je prepovedal poimenovanje razredov z besedo ‚Object‘),
trait Nette\SmartObject
živi naprej.
Poglejmo si funkcije, ki sta jih nekoč ponujala Nette\Object
in kasneje Nette\SmartObject
. Vsaka od
teh funkcij je v svojem času predstavljala pomemben korak naprej na področju objektno usmerjenega programiranja v PHP-ju.
Konsistentna obravnava napak
Ena najbolj perečih težav zgodnjega PHP-ja je bilo nedosledno obnašanje pri delu z objekti. Nette\Object
je
v ta kaos prinesel red in predvidljivost. Poglejmo si, kako se je PHP prvotno obnašal:
Fatal error je prekinil aplikacijo brez možnosti odziva. Tiho pisanje v neobstoječe člane brez opozorila je lahko vodilo do
resnih napak, ki jih je bilo težko odkriti. Nette\Object
je vse te primere prestregel in vrgel izjemo
MemberAccessException
, kar je programerjem omogočilo odzivanje na napake in njihovo reševanje:
Od PHP 7.0 jezik ne povzroča več neulovljivih fatal error-jev, od PHP 8.2 pa se dostop do nedeklariranih članov šteje za napako.
Pomoč „Did you mean?“
Nette\Object
je prišel z zelo priročno funkcijo: inteligentnimi predlogi pri napakah v črkovanju. Ko je
razvijalec naredil napako v imenu metode ali spremenljivke, ni le sporočil napake, ampak je tudi ponudil pomoč v obliki
predloga pravilnega imena. To ikonično sporočilo, znano kot „did you mean?“, je programerjem prihranilo ure iskanja napak
v črkovanju:
Današnji PHP sicer nima nobene oblike „did you mean?“, vendar to funkcionalnost v sporočila o napakah dodaja Tracy. In celo samodejno popravlja take napake.
Properties s kontroliranim dostopom
Pomembna inovacija, ki jo je SmartObject prinesel v PHP, so bile properties s kontroliranim dostopom. Ta koncept, običajen v jezikih kot sta C# in Python, je razvijalcem omogočil eleganten nadzor nad dostopom do podatkov objekta in zagotavljanje njihove konsistentnosti. Properties so močno orodje objektno usmerjenega programiranja. Delujejo kot spremenljivke, vendar so v resnici predstavljene z metodami (getterji in setterji). To omogoča validacijo vhodnih podatkov ali generiranje vrednosti šele ob branju.
Za uporabo properties morate:
- Dodati razredu anotacijo v obliki
@property <type> $xyz
- Ustvariti getter z imenom
getXyz()
aliisXyz()
, setter z imenomsetXyz()
- Zagotoviti, da sta getter in setter public ali protected. Sta opcijska – lahko torej obstajata kot read-only ali write-only property
Poglejmo si praktičen primer na razredu Circle, kjer bomo properties uporabili za zagotavljanje, da je polmer vedno
nenegativno število. Nadomestili bomo prvotni public $radius
s property:
Od PHP 8.4 lahko isto funkcionalnost dosežemo s property hooks, ki ponujajo veliko bolj elegantno in jedrnato sintakso:
Extension methods
Nette\Object
je v PHP prinesel še en zanimiv koncept, navdihnjen s sodobnimi programskimi jeziki – extension
methods. Ta funkcionalnost, prevzeta iz C#, je razvijalcem omogočila elegantno razširjanje obstoječih razredov z novimi
metodami brez potrebe po spreminjanju ali dedovanju. Na primer, obrazcu ste lahko dodali metodo addDateTime()
, ki
doda lasten DateTimePicker:
Extension metode so se izkazale za nepraktične, ker njihovih imen urejevalniki niso predlagali, nasprotno, javljali so, da metoda ne obstaja. Zato je bila njihova podpora ukinjena. Danes je običajneje uporabljati kompozicijo ali dedovanje za razširitev funkcionalnosti razredov.
Pridobivanje imena razreda
Za pridobivanje imena razreda je SmartObject ponujal preprosto metodo:
Dostop do refleksije in anotacij
Nette\Object
je ponujal dostop do refleksije in anotacij preko metod getReflection()
in
getAnnotation()
. Ta pristop je pomembno poenostavil delo z metainformacijami razredov:
Od PHP 8.0 je mogoče dostopati do metainformacij v obliki atributov, ki ponujajo še več možnosti in boljšo tipsko preverjanje:
Method getterji
Nette\Object
je ponujal eleganten način za predajanje metod, kot da bi šlo za spremenljivke:
Od PHP 8.1 je mogoče uporabiti t.i. first-class callable syntax, ki ta koncept pelje še dlje:
Dogodki
SmartObject ponuja poenostavljeno sintakso za delo z dogodki. Dogodki omogočajo objektom, da obvestijo druge dele aplikacije o spremembah svojega stanja:
Koda $this->onChange($this, $radius)
je enakovredna naslednji zanki:
Zaradi jasnosti priporočamo, da se izognete magični metodi $this->onChange()
. Praktična zamenjava je
funkcija Nette\Utils\Arrays::invoke: