Gå til innhold

PHP·pub - Programming With Attitude - and beer


Anbefalte innlegg

Jeg ser ikke noe som helst problem i å opprette objekter i en constructor så lenge de også blir slettet i destructor.

Stiller saken seg annerledes om man ikke oppretter objektene via en constructor, men på annet vis?

Vel, det er jo endel ting iallfall jeg vil si det er naturlig å opprette i en constructor. At man i praksis skal pålegge andre i bunn og grunn å initialisere variablene i klassen blir helt feil for min del. Nå er jeg driver jeg riktignok ikke like mye med PHP som før, men «best practice» er fort relativt universalt. Så hvorfor skal f.eks. et objekt for caching av data for sending opprettes utenfor constructor når ingen andre har bruk for dette objektet?

 

Redigering:

Altså, påstanden er at «Det regnes dog som dårlig praksis å initialisere objekter i konstruktøren.». Det må altså bety at det er en ulempe med dette. Det jeg er ute etter er hva denne ulempen skulle være. Hvorfor skal man dytte inn objekter inn i objekter utenfra i stedet for å opprette de i constructor?

Endret av Ernie
Lenke til kommentar
Videoannonse
Annonse

Ahh ... sånn sett ja. Da misforsto jeg deg :) Vel, når et objekt dyttes inn i et annet objekt så er det litt udefinert hva som faktisk er smart å gjøre i lengden. Det vil også være veldig avhengig av språket man jobber i. Generelt sett så bør det nok slettes utenfor, og ikke i destructor.

Lenke til kommentar

Er bare å la medlemmene være objekter, ikke noe hokus pokus. Det regnes dog som dårlig praksis å initialisere objekter i konstruktøren. Bedre å «injecte» objektene via konstruktørparametere eller setter-metoder.

 

Kunne du/noen andre vist dette med pseudokode? Har problemer med å forstå "la medlemmene være objekter". Eventuelt link til noen gode artikler om dette.

Lenke til kommentar

Der kom du med et meget godt eksempel på hvorfor man i de fleste tilfeller ikke bør instantiere objektene inni konstruktøren. La oss si at vi har en databaseklasse hvor cache-objektet lages i konstruktøren:

 

<?php

class Database extends \PDO {

protected $cache;

public function __construct() {
	$this->cache = new FileCacheAdapter();
}
}

 

Fungerer bra i dette spesifikke tilfellet, men hva om jeg plutselig å endre cache-mekanisme? Kanskje bruke APC eller Memcache, eller bare et enkelt array i utviklingsøyemed? Da må jeg inn i databaseklassen og endre dette internt i klassen istedenfor å bare injecte det ønskede cache-objektet i database-objektet. En bedre løsning vil være følgende.

 

<?php

class Database extends \PDO {

protected $cache;

public function __construct(CacheInterface $cache) {
	$this->cache = $cache;
}
}

 

På denne måten vil jeg få et mer modulært system hvor det blir enklere å skrive enhetstester og objektene ikke er tight coupled. Hvis jeg nå ønsker å endre mekanisme kan jeg enkelt injecte et nytt objekt.

 

$cache = new MemcacheAdapter();
$database = new Database($cache);

 

Stikkord: Dependency injection

Endret av Dr. Awesome
Lenke til kommentar

Nå var akkurat det der hentet fra en applikasjon som kommuniserer med en COM-port. Selve cachingen gjøres i RAM med en slags array (det hele er skrevet i C++ og såvidt jeg vel en queue e.l. som er benyttet). Det er og vil heller aldri være noe poeng å styre med dette, siden det bare caches for å kunne dytte ut kommandoer med godt nok mellomrom. Å mellomlagre det i en fil eller database blir poengløst siden dataene allikevel skal ut innen få sekunder. Kanskje et bedre eksempel hadde vært bufferet for dataene som kommer inn. De må også mellomlagres et sted inntil man har en hel pakke, også dette foregår i RAM siden man snakker om under et sekund fra dataene kommer til de blir behandlet. Det gir altså ingen praktisk gevinst å lagre det noe annet sted, og dataene blir heller ikke så store at RAM blir fylt opp (en hel overføring kommer på <50kB).

 

At det kan være et poeng å dytte ting inn utenfra for å få det mer modulært kan jeg være enig i, men det ikke alltid det er nødvendig eller nyttig. Derfor blir det også litt feil å kalle det konsekvent for dårlig praksis. I PHP er det veldig lett å gå i den fellen siden man har veldig mye innebygget som ikke er eller ser ut som objekter. Objekter og klasser blir i PHP mye fortere ting man kan implementere på forskjellige måter med forskjellige fordeler. I andre språk vil derimot en slik uttalelse si at hver bidige array må sendes inn utenfra, og jeg håper du skjønner at det ikke er spesielt nyttig, men heller å lage et stort problem ut av ingenting.

Lenke til kommentar
  • 1 måned senere...
Jonas, hva mener du med "kraften det egentlig er i objekter", hva er det og hvordan utnytter man den? :)

Satt sammen et lite eksempel for å vise hvordan man kan bruke objekter til å implementere MVC, noe som er ganske fiffi.

 

function user_path (\ Models \ User $user) {

Hva er det du gjør her egentlig? (\ Models \ User)

 

class User extends \ ActiveRecord {

Samme her, hvilken nytte har dette? :)

Endret av Thomas.
Lenke til kommentar

Der kom du med et meget godt eksempel på hvorfor man i de fleste tilfeller ikke bør instantiere objektene inni konstruktøren. La oss si at vi har en databaseklasse hvor cache-objektet lages i konstruktøren:

 

<?php

class Database extends \PDO {

protected $cache;

public function __construct() {
	$this->cache = new FileCacheAdapter();
}
}

 

Fungerer bra i dette spesifikke tilfellet, men hva om jeg plutselig å endre cache-mekanisme? Kanskje bruke APC eller Memcache, eller bare et enkelt array i utviklingsøyemed? Da må jeg inn i databaseklassen og endre dette internt i klassen istedenfor å bare injecte det ønskede cache-objektet i database-objektet. En bedre løsning vil være følgende.

 

<?php

class Database extends \PDO {

protected $cache;

public function __construct(CacheInterface $cache) {
	$this->cache = $cache;
}
}

 

På denne måten vil jeg få et mer modulært system hvor det blir enklere å skrive enhetstester og objektene ikke er tight coupled. Hvis jeg nå ønsker å endre mekanisme kan jeg enkelt injecte et nytt objekt.

 

$cache = new MemcacheAdapter();
$database = new Database($cache);

 

Stikkord: Dependency injection

Eller man kan bruke factory pattern.

 

Blir lettere å vite hva som skal brukes som parameter for å initialisere objektet når man skal ta i bruk klasse man ikke selv har skrevet tenker jeg. :)

Lenke til kommentar
function user_path (\ Models \ User $user) {

Hva er det du gjør her egentlig? (\ Models \ User)

Jeg bestemmer typen av argument funksjonen krever. Dvs. at du må kalle funksjonen med en instans av klassen User, som ligger i namespaces Models.

 

class User extends \ ActiveRecord {

Samme her, hvilken nytte har dette? :)

Det betyr at klassen User arver av klassen ActiveRecord, som gir den abstraherte database-egenskaper.

Lenke til kommentar

$x = '%' . $x2 . ', ' . substr(DATO_TID, 3, 6) . ' '  . date('Y') . '%';
$sql = Database::query('SELECT * FROM `tabell1` JOIN tabell2 ON tabell1.ssd = tabell2.nk WHERE dato LIKE \'%12, Mar - 2011%\' ORDER BY tabell2.r2 DESC');

Spørringen over her fungerer fint både i PHP og i phpMyAdmin.

 

Hvorfor kan jeg ikke bruke variabel i SQL spørringen? Spørringen returnerer ingen ting om jeg endrer til

$sql = Database::query('SELECT * FROM `tabell1` JOIN tabell2 ON  tabell1.ssd = tabell2.nk WHERE dato LIKE \'' . $x . '\' ORDER BY  tabell2.r2 DESC');

 

Og $x inneholder nøyaktig det som står i første kodesnutt (datoen igår).

 

:ermm:

Lenke til kommentar

Selvfølgelig kan spørringer være variable og det vet du. Tenkt etter - hvordan må du gå frem for å finne ut av hvor problemet ligger?

 

Jepp, klar over det. Derfor jeg stusset litt på hvorfor det ikke fungerte.

 

Nei, det var det da. Hvordan gå frem.

Datatypene er de samme, prøvd og legge alt i en variabel for så å kjøre query på denne variabelen. Prøvd prepare og execute. Fortsatt ingen resultater.

 

Jeg bruker variabler direkte i andre query() spørringer jeg kjører, og de kjører helt fint. Merkelig at det skulle bli noe krøll med akkurat denne.

Har du noen forslag?

Lenke til kommentar

Har skrevet PHP litt av og på i rundt fire år nå, og har et par PHP-bøker som tar for seg basic PHP-programmering, samt PHP5 OOP. Trenger nå en bok som går på "best practice", strukturering av f.eks filhiarki i større prosjekter, samt mer OOP-materiale med større, gode kodeeksempler som ikke er helt abstrakte (alá alle "class dog extends animal"-eksemplene). Rett og slett hvordan bruke PHP best mulig i større prosjekter. Minst mulig kode, størst mulig fleksibilitet, strukturering, flyt og slikt :)

 

Har kommet frem til at boka PHP Objects, Patterns, and Practice, Second Edition muligens kan passe bra. Noen andre bøker som kan anbefales i samme segment?

Endret av clvn
Lenke til kommentar

Selvfølgelig kan spørringer være variable og det vet du. Tenkt etter - hvordan må du gå frem for å finne ut av hvor problemet ligger?

 

Jepp, klar over det. Derfor jeg stusset litt på hvorfor det ikke fungerte.

 

Nei, det var det da. Hvordan gå frem.

Datatypene er de samme, prøvd og legge alt i en variabel for så å kjøre query på denne variabelen. Prøvd prepare og execute. Fortsatt ingen resultater.

 

Jeg bruker variabler direkte i andre query() spørringer jeg kjører, og de kjører helt fint. Merkelig at det skulle bli noe krøll med akkurat denne.

Har du noen forslag?

skriv ut spørringen før du kjører den - første steg i debugging. Ofte viser det seg at verdier i variabler ikke er det du forventet.

Lenke til kommentar

Selvfølgelig kan spørringer være variable og det vet du. Tenkt etter - hvordan må du gå frem for å finne ut av hvor problemet ligger?

 

Jepp, klar over det. Derfor jeg stusset litt på hvorfor det ikke fungerte.

 

Nei, det var det da. Hvordan gå frem.

Datatypene er de samme, prøvd og legge alt i en variabel for så å kjøre query på denne variabelen. Prøvd prepare og execute. Fortsatt ingen resultater.

 

Jeg bruker variabler direkte i andre query() spørringer jeg kjører, og de kjører helt fint. Merkelig at det skulle bli noe krøll med akkurat denne.

Har du noen forslag?

skriv ut spørringen før du kjører den - første steg i debugging. Ofte viser det seg at verdier i variabler ikke er det du forventet.

 

Ja, det har jeg gjort fler ganger.

Den er som den skal:

string(127) "SELECT * FROM `tabell1` JOIN tabell2 ON  tabell1.ssd =  tabell2.nk WHERE dato LIKE '%15,  Mar - 2011%' ORDER BY  tabell2.r2  DESC" 

 

Om jeg kopierer spørringen herifra og kjører den i phpMyAdmin fungerer den.

Hvorfor fungerer det ikke kjøre den med php?

Lenke til kommentar
  • 1 måned senere...

Noen som kan gi meg en god grunn til å prøve PDO, da jeg i dag bruker mysqli? Bruker kun MySQL, og skriver det meste objektorientert.

 

Har lest litt om PDO på nettet, men ser ikke helt hvorfor folk nevner det såpass ofte, da mysqli gjør jobben fint samt ser bra ut.

Lenke til kommentar

Benytter man PDO kan man i teorien enkelt skifte fra MySQL til f.eks. PostgreSQL. Man trenger ikke å skifte ut ørten mysql*-kall mot pg*-kall. Uheldigvis stemmer ikke teori og praksis alltid like bra. I realiteten slipper man riktignok unna å endre funksjonskallene, men selve spørringene kan i verstefall måtte endres noe pga. differanse mellom de forskjellige databasesystemene.

Endret av Ernie
Lenke til kommentar

Jeg er under utdanning, og er vant med MySQL, så tror ikke jeg kommer til å hoppe over på noen annen database med det første, og prosjektene mine er ikke større enn at jeg kan endre på spørringene der det trengs. Tar derfor ikke "problemene" på forskudd.

 

Er det noen annen grunn til at jeg burde vurdere PDO?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...