/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
Gem/hent data i et objekt - PHP5
Fra : Peter Farsinsen


Dato : 11-10-06 21:53

Hej

Jeg har stirret mig helt blind på et formentligt ganske simpelt problem.
Google har imidlertid ikke lige et bud, så jeg håber I kan hjælpe.

Hvis jeg har flg. (pseudokode):

class Artist {
private $name;
private $age;
private $dbo;

public function __construct(DBO &$dbo) {
$this->$dbo = $dbo;
}
}

Så vil jeg gerne kunne:

1) tilføje en artist og gemme data i databasen
2) hente en artist (efter id eller navn) fra databasen

Hvad er bedste praksis for at "smelte" disse to funktionaliteter sammen
i én klasse. Det det er de samme data, der er tale om, går jeg ud fra,
at de skal være i samme klasse.

--
Peter Farsinsen
fornavn@efternavn.dk

 
 
Jesper Brunholm (12-10-2006)
Kommentar
Fra : Jesper Brunholm


Dato : 12-10-06 07:34

Peter Farsinsen skrev:
> Jeg har stirret mig helt blind på et formentligt ganske simpelt problem.
> Google har imidlertid ikke lige et bud, så jeg håber I kan hjælpe.
>
> Hvis jeg har flg. (pseudokode):
>
> class Artist {
> private $name;
> private $age;
> private $dbo;
>
> public function __construct(DBO &$dbo) {
> $this->$dbo = $dbo;
> }
> }

DBO er (sandsynligvis, jeg går ud fra det) et databaseobjekt som sørger
for at du kan forbinde til databasen og hente/gemme i den?

Din Artist Class er så et interface til at håndtere forbindelsen mellem
databasen og fremvisningen på et website.

> Så vil jeg gerne kunne:
>
> 1) tilføje en artist og gemme data i databasen

Lav en function som modtager argumenterne til at lave en ny artist, og
kald databasen med en indsætningsquery

> 2) hente en artist (efter id eller navn) fra databasen

Lav tilsvarende en function som henter en given artists data ud af
databasen og gemmer dem i det aktuelle artist-objekt.

Lav en fjerde function som kan udlevere Artist data

> Hvad er bedste praksis for at "smelte" disse to funktionaliteter sammen
> i én klasse. Det det er de samme data, der er tale om, går jeg ud fra,
> at de skal være i samme klasse.

Ja, det lyder logisk at lade en artist være et samlet objekt, men du
skal nok have artistens oprettelse med i constructoren, så den enten
modtager id på den artist som den skal hente ud af databasen, eller de
data som er Artistens grund-egenskaber (som så skal inddateres i
databasen inden Artist-objektet lukkes og slettes igen).

Hvis du er i tvivl om, om det er rigtigt at lade et objekt udføre en
opgave, kan du forestille dig at hvert objekt i dit projekt er en
person, med en serie opgaver. De projektansatte er allesammen højt
specialiserede til netop deres opgave, og derfor ikke ret gode til at
arbejde med andet end deres spidskompetence. Hvis man pålægger flere
ansatte opgaver der er nært beslægtede, vil de ofte komme i konflikt om
hvem der har ansvaret for hvad i forbindelse med opgaverne.
At sende et objekt videre til et andet, kan i analogien beskrives som at
sende en projektmappe med en kunde fra en ansat til en anden.

mvh

Jesper Brunholm









Martin (12-10-2006)
Kommentar
Fra : Martin


Dato : 12-10-06 12:48

Jesper Brunholm wrote:
> At sende et objekt videre til et andet, kan i analogien beskrives som at
> sende en projektmappe med en kunde fra en ansat til en anden.

og så går der altid bøvl i den, hvis flere personer skal have 1 kunde :)
Ej - spøg til side.
Faktisk en meget god forklaring på hvordan klasser skal bygges op.

Peter Farsinsen (12-10-2006)
Kommentar
Fra : Peter Farsinsen


Dato : 12-10-06 16:52

Jesper Brunholm wrote:

> DBO er (sandsynligvis, jeg går ud fra det) et databaseobjekt som sørger
> for at du kan forbinde til databasen og hente/gemme i den?
>
> Din Artist Class er så et interface til at håndtere forbindelsen mellem
> databasen og fremvisningen på et website.

DBO er rigtig nok en instans af, i dette tilfælde AdoDB, databaseklassen.

Artist er "nederst i fødekæden" og del af et større modul, som jeg
regner med at kontrollere med noget MVC-agtigt kode. Går jeg galt i byen
med at kun at bruge det pattern på modul-niveau?

>> Så vil jeg gerne kunne:
>>
>> 1) tilføje en artist og gemme data i databasen
>
> Lav en function som modtager argumenterne til at lave en ny artist, og
> kald databasen med en indsætningsquery

....

> Ja, det lyder logisk at lade en artist være et samlet objekt, men du
> skal nok have artistens oprettelse med i constructoren, så den enten
> modtager id på den artist som den skal hente ud af databasen, eller de
> data som er Artistens grund-egenskaber (som så skal inddateres i
> databasen inden Artist-objektet lukkes og slettes igen).

Noget i stil med http://kloegt.dk/records/class.artist.php ? Kommenter
gerne, hvis I gider ;)

Jeg er ikke helt blank, hvad OOP angår, men det virker lidt forkert, at
gemme data fra selve klassen, som brugen af en relationel database
fordrer. I virkeligheden burde man jo gemme hele objektet med
$dbo->save($obj); men det går jo ikke ;)

> Hvis du er i tvivl om, om det er rigtigt at lade et objekt udføre en
> opgave, kan du forestille dig at hvert objekt i dit projekt er en
> person, med en serie opgaver. De projektansatte er allesammen højt
> specialiserede til netop deres opgave, og derfor ikke ret gode til at
> arbejde med andet end deres spidskompetence. Hvis man pålægger flere
> ansatte opgaver der er nært beslægtede, vil de ofte komme i konflikt om
> hvem der har ansvaret for hvad i forbindelse med opgaverne.
> At sende et objekt videre til et andet, kan i analogien beskrives som at
> sende en projektmappe med en kunde fra en ansat til en anden.

Jeg er opmærksom på og bekendt med responsibilities, men det er svært at
mestre. Din forklaring er dog rigtig fin, det virker i reglen godt at
beskrive ting med en metafor ;)

--
Peter Farsinsen
fornavn@efternavn.dk

Martin (12-10-2006)
Kommentar
Fra : Martin


Dato : 12-10-06 17:37

Peter Farsinsen wrote:
> Noget i stil med http://kloegt.dk/records/class.artist.php ? Kommenter
> gerne, hvis I gider ;)

Du vil da aldrig få noget output i din getArtist method.
saveData og loadDate burde nok være private, eller protected metoder
(hvis det ellers har nogen betydning for dig, at lave det korrekt)

Information om artisten ville jeg nok lave anderledes.

Jeg ville nok lave en
var $artistInfo = array();

også ellers return $this->artistInfo;
og $this->artistInfo["name"]=$r['name'];
Så ville det ikke koste så meget tid når der kommer flere oplysninger om
artisten.

Jeg ved ikke helt, men jeg ville nok lave en helt anden klasse til at
indsætte artist oplysninger.

Peter Farsinsen (12-10-2006)
Kommentar
Fra : Peter Farsinsen


Dato : 12-10-06 18:14

Martin wrote:

> Du vil da aldrig få noget output i din getArtist method.

Det er selvfølgelig en fejl. Der er tale om kode, der aldrig skal bruges
- altså proof of concept.

> saveData og loadDate burde nok være private, eller protected metoder
> (hvis det ellers har nogen betydning for dig, at lave det korrekt)

loadData(); er privat, da den kun kaldes af konstruktøren, den kunne
selvfølgelig være protected, hvis jeg udvidder klassen. saveData er
public, hvis jeg skulle hente, ændre og gemme et eksisterende "objekt"
fra databasen.

> Information om artisten ville jeg nok lave anderledes.
>
> Jeg ville nok lave en
> var $artistInfo = array();
>
> også ellers return $this->artistInfo;
> og $this->artistInfo["name"]=$r['name'];

Jeg synes det er fint, at oplysningerne returneres i et array, men i
selve klassen foretrækker jeg variabler. Det er sikkert et spørgsmål om
smag.

> Jeg ved ikke helt, men jeg ville nok lave en helt anden klasse til at
> indsætte artist oplysninger.

Det er lige præcis dét, jeg prøver at regne ud. Problemet er bare, at
det kan give vanvittigt mange klasser. Gem/hent-stuff hører jo for så
vidt ikke hjemme i klassen, men er, som jeg skrev, en effekt af at bruge
en relationel database. Det kunne være fint, hvis der var en vej udenom ;)

--
Peter Farsinsen
fornavn@efternavn.dk

Nezar Nielsen (16-10-2006)
Kommentar
Fra : Nezar Nielsen


Dato : 16-10-06 11:01

Peter Farsinsen wrote:
> Det er lige præcis dét, jeg prøver at regne ud. Problemet er bare, at
> det kan give vanvittigt mange klasser. Gem/hent-stuff hører jo for så
> vidt ikke hjemme i klassen, men er, som jeg skrev, en effekt af at bruge
> en relationel database. Det kunne være fint, hvis der var en vej udenom ;)

Det er svært at komme helt udenom databasehejs, når det *ER* ting, der
skal ligge i en database, jeg har sluppet udenom det ved at lave en
metaklasse som alting nedarver fra, som står for at snakke med
databasen, så i de nedarvende klasser har jeg en opsætning af hvordan
klassen ser ud nede i databasen samt en constructor, der kalder
parent-klassens constructor i stil med:

class test extends persistent_object{
   var $class='test';
   var $_class_definition=array(
      'fields'=>array(
         'title'=>array(
            'type'=>PO_DATATYPE_STRING,
            'null' => false
         ),
   );

   var $title;

   function __construct($init=null){
      return parent::__construct($init);
   }
}

med den kode er jeg i stand til at hente instanser med

//'test' fortæller hvilken type objekt jeg er ude efter
$alle_test_instanser = test::locate('test');

(locate metoden tager også flere parametre til at indgrænse søgningen,
limit'e, order by'e osv.)

$ob = new test;
$ob->setid(32);
$ob->load();

$ob->title = 'yeah';
$ob->save();

--
Mvh. Nezar Nielsen
http://gorilla.dk

Peter Farsinsen (16-10-2006)
Kommentar
Fra : Peter Farsinsen


Dato : 16-10-06 12:39

Nezar Nielsen wrote:

> Det er svært at komme helt udenom databasehejs, når det *ER* ting, der
> skal ligge i en database, jeg har sluppet udenom det ved at lave en
> metaklasse som alting nedarver fra, som står for at snakke med
> databasen, så i de nedarvende klasser har jeg en opsætning af hvordan
> klassen ser ud nede i databasen samt en constructor, der kalder
> parent-klassens constructor i stil med:

Tak for inputtet. Jeg har slet ikke tænkt på, at det kunne gøres på den
måde, men det ser umiddelbart rigtig smart ud - jeg vil i hvert fald
tegne lidt videre på mit papir ;)

Eneste kommentar; er det ikke en fejl, at din constructor i test
returnerer noget? Jeg er af den opfattelse, at constructor aldrig skal
returnere noget...

--
Peter Farsinsen
fornavn@efternavn.dk

Nezar Nielsen (16-10-2006)
Kommentar
Fra : Nezar Nielsen


Dato : 16-10-06 15:04

Peter Farsinsen wrote:
> Eneste kommentar; er det ikke en fejl, at din constructor i test
> returnerer noget? Jeg er af den opfattelse, at constructor aldrig skal
> returnere noget...

Det er ret længe siden jeg lavede den klasse, men såvidt jeg husker
returnerer den bare true eller en PEAR_Error hvis noget gik galt, det er
pre-exceptions-kode :)

--
Mvh. Nezar Nielsen
http://www.gorilla.dk

Michael Rasmussen (16-10-2006)
Kommentar
Fra : Michael Rasmussen


Dato : 16-10-06 17:26

On Mon, 16 Oct 2006 16:03:48 +0200, Nezar Nielsen wrote:

>
> Det er ret længe siden jeg lavede den klasse, men såvidt jeg husker
> returnerer den bare true eller en PEAR_Error hvis noget gik galt, det er
> pre-exceptions-kode :)
>
Er det ikke fordi, det er oprindeligt PHP4 kode?
Det du i virkeligheden ønsker, er et abstract factory pattern, hvor
konstruktøren er privat, og hvor man henter en konkret instans gennem en
statisk metode.

class Instance {

private function __construct() {}

public static getInstance($concretInstance) {
switch ($concretInstace) {
case "someInstance": return new SomeInstance; break;
.......
   default:
      return new Exception("unknown implementation");
}
}
}

try {
$myInstance = Instance::getInstance("someInstance");
}
catch (Exception $e) {
trigger_error(e->getMessage(), E_USER_ERROR);
}

--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917

Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408522
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste