Et klassisk problem i min verden, er procesering af store filer i PHP. Det kunne f.eks. være læsning af en logfil eller importering fra en CVS fil…
Jeg ved snart ikke hvormange gange jeg er begyndt at indlæse en fil uden at tænkt over filens størrelse først – det varer som regel ikke længe inden ens computer begynder at “blæse” og et simpelt check af rammene viser at de hurtigt er ved at blive fyldt op .
Kan du nikke genkendende til dette scenarie, så vil du sikkert kunne bruge følgende metode til noget.
Step by step…
Løsningen virker meget logisk, men som med alt PHP-kodning, kræver det lige at du har fundet ud af hvilke funktioner der findes til at håndterer dette. Tricket er selvfølgelig kun at læse lidt ad gangen.
Her har jeg taget udgangspunkt i importering af en “;”-separeret CSV-fil, og jeg er interesseret i at læse én linie ad gangen. Om filen er 10, 50, eller 100 MB stor har kun betydning for tiden det vil tage at proceserer den.
En linie i CVS-filen kunne se ud som følgende: ID ; navn ; email
Tilbage i april fandt jeg frem til hijax princippet, og i den forbindelse lovede jeg at der ville komme en mere praktisk gennemgang – det vil jeg så forsøge mig med nu.
Mens sidste post om hijax kort fortalte princippet bag hijax, og snakken mere gik på “hvorfor” man burde bruge det, har jeg nu haft mulighed for rent faktisk at lege lidt med hijax, og mener nu der skulle være basis for at skrive endnu en post herom.
Hijax super kort
Jeg har taget udgangspunkt i et simpelt eksempel, som jeg selv synes forklare det praktiske bag princippet. Super kort fortalt, så går hijax ud på at “hijacke” (overtage) funktionalitet på din hjemmeside og udføre denne via AJAX, men SAMTIDIG skal det være muligt at afvikle samme funktionalitet UDEN brug af Javascript – grundtanken i graceful degradation.
Jeg sidder i skrivende stund og forsøger at forbedre mine evner med OOP i PHP5. Og har man første sagt OOP, kommer man vel ikke uden om at sige constructor og overloading af samme … eller hvad?!
Da PHP5 udkom, var der en del hype om forbedringer i henhold til at kode objekt orienteret heri, der er bl.a. introduceret en ny måde at lave constructors på samt mulighed for at bestemme public/private/protected identifyers til funktioner.
Hvor man i PHP4 blot skulle defineret constructors som en funktion med samme navn som klassen, kan man nu bruge __construct() og evt. __destruct() – men hvad med overloading af constructors?
I sprog som f.eks. C# og Java overloader du constructors blot ved at tilføje endnu en funktion med klassens navn, og med et unikt antal parametre:
class Test {
public Test() {
//Default constructor
}
public Test(int foo) {
//Constructor using 1 parameter
}
public Test(int foo, int bar) {
//Constructor using 2 parameters
}
}
Det skulle være forholdsvis let at komme til at tro, at man kunne udføre noget lignende i PHP5, nu det jo er kommet med på noderne - men sådan forholder det sig ikke helt. Jeg forsøgte f.eks. til at starte med, at lave en overloading ved noget ligende:
public function __construct($foo) {
//Constructor using 1 parameter
}
Men da jeg samtidig havde defineret en standard constructor, fik jeg en fejlmelding:
Fatal error: Cannot redeclare Test::__construct()
Underligt tænkte jeg, og begyndte at Google overloading af constructors lidt. Og det lader åbenbart til at være et generelt problem/irritationsmoment.
Constructor overloading work-around
Jeg fandt dog frem til følgende work-around, hvilket virker udemærket – men ærlig talt, hvorfor har man dog lader et så basal ting udeblive i et sprog nu man alligevel var igang med at forbedre dets muligheder for OOP?!
public function __construct() {
$num = func_num_args();
$args = func_get_args();
switch($num) {
case 1:
$this->__call(__construct1, $args);
break;
case 2:
$this->__call(__construct2, $args);
default:
//Do default stuff
}
}
Ved at "switche" på antallet af input parametre til constructoren (også selvom man ikke skal definere dem i selve constructoren – WTF?), og benytte en interne function __call, som meget simpelt kalder en anden funktion med de sendte input paramtre, kan man få sin kode til at "se ud til" man overloader constructoren.
I virkeligheden kalder vi bare nogle andre funktioner, her meget søgt kaldet __construct1/2/3, alt efter antallet af parametre.
public function __construct1($param) {
//do stuff with your one parameter
}
public function __construct2($param1, $param2) {
//do stuff with 2 parameters!
}
Funktionen til at kalde vores "overloadede constructors" ser ud således:
private function __call($name, $arg) {
return call_user_func_array(array($this, $name), $arg);
}
Løsningen fungere udemærket, om ikke andet er det da rimelig transparent for den der efterfølgende skal bruger klassen… Ved ikke helt hvad jeg synes om det, men indtil andet er på plads (i PHP), så vil jeg tro dette er måden at gøre det på.
Er der nogen der er kommet frem til andre måder at overloade constructors på i PHP?
Lige siden min kæreste, for nu snart 3 år siden, købte sig en iBook, har jeg haft et misundeligt blik i øjnene hver gang den blev hevet frem. Lad mig bare sige det med det samme … jeg har svaghed for eye-candy, funky features og design
Nu kom dagen så, hvor jeg stod i en situation, hvor jeg (igen) skulle ud og erhverve mig en ny computer – og denne gang tog jeg springt til Mac!
Det er ikke fordi jeg, ligesom visse andre, nødvendigvis synes PC og Windows har været noget være lort! Faktisk har jeg været riigtig glad for den sidste PC jeg havde (Dell XPS M1330), og har ikke oplevet nogle bemærkelsesværdige problemer med Windows Vista – nu var jeg bare klar til at prøve en Mac.
Seneste kommentarer