21. oktober 2008 - 10:30Der er
11 kommentarer og 1 løsning
Ny eller gammel constructor?
Jeg hører hele tiden at man helst skal holde sig fra magic i PHP, hvilket naturligvis inkluderer __constructor - Derfor har jeg efter overgangen til PHP5, stadig brugt PHP4s constructor, men er i tvivl om den rent faktisk *er* hurtigere, og om der vil være problemer med den i PHP6.
Så, en gang for alle, hvad er bedst, både performance- og kompatibilitetsmæssigt? Er der andre grunde til at vælge den nye?
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
Ikke at man skal holde sig fra det, men at det er langsomt. Naturligvis er det fint at bruge hvis der ikke er alternativer, men stort set alle benchmarks jeg læser, siger at magic er langsomt. Derfor, når der er et direkte alternativ, er jeg interesseret i om der egentlig er en forskel.
Hvorfor tester du ikke bare begge metoder i nogle realistiske loops? Så _ved_ du, hvad der er hurtigst. Der bliver skrevet floder af vrøvl på WWW, så det er altid en rigtig god idé at lave sine egne tests ;o)
Iterations: 1000000 1 (old): 2.7070028781891 s 2 (new): 2.6952679157257 s Difference: 0.011734962463379 s Winner: 2
Mit benchmark viser at der absolut ingen forskel er på de to, så nu er der kun spørgsmålet tilbage: Er der nogen ANDEN grund til at vælge den nye, eller er det 100% en smagssag + den praktiske ting, at den gamle metode også virker på PHP4-servere?
Hvis du ikke behøver at sikre bagudkompatibilitet med php4 bør du helt klart bruge __constructer. Se for eksempel på den nedenstående stump kode:
------ class A { function A() { echo "Dette er klassens constructer"; }
function B() { echo "Dette er en komplet urelateret funktion, der ikke bør være en constructer"; } }
class B extends A { }
$a = new A(); //skriver "Dette er klassens constructer" $b = new B(); //skriver "Dette er en komplet urelateret funktion, der ikke bør være en constructer"
------
hvis du derimod havde brugt __construct ville et problem som dette aldrig opstå - selv hvis class A ikke har en funktion B vil du stadig blive nødt til at sige: ----- class B extends A { function B() { parent::A(); } } -----
Alt i alt er det en stor fordel at bruge php5 modellen. Selv sidder jeg og kæmper med netop problemer som de ovenstående, da jeg udvikler kode der skal være php4 kompatibelt.
class PHP4Compat { function __construct() { // Code ... } function __destruct() { // Code ... } function PHP4Compat() { $this->__construct(); register_shutdown_function(array($this, "__destruct")); } }
- men er man nødt til at gøre koden PHP4 kompatibel, mister man jo en hel del af PHP5's fordele. Så heller installere to forskellige koder. Det giver et større arbejde nu, men sparer arbejdet med at skrive koden om, når de sidste PHP4-servere udfases =)
Den løsning er også den jeg pt anvender, men det bliver besværligt når constructeren skal acceptere et variabelt antal argumenter, da php4 ikke kan udføre objektmetoder via call_user_func_array(). Så er man nødt til noget i stil med:
class A { function A() { $this->constructargs = func_get_args(); $this->__construct(); }
function __construct() { $args = $this->constructargs ? $this->constructargs : func_get_args(); // kode ... } }
Igen meget besværligt, så php5 måden er langt at foretrække.
Det er selvfølgelig en forskel, men jeg må indrømme aldrig selv at have været i en situation, hvor en klasse forlængede en anden klasse, der havde en constructor af samme navn som den deriverede klasse.
Jeg har nu heller ikke stødt på lige præcis det problem, men det ville da være fjollet at udsætte sig for sandsynligheden for at skulle kæmpe med den slags bugs, når det kan undgås uden større besvær. :)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.