[php] webshop wel / geen artikel classes

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Ik ben onbekend met classes in php, wel bekend met oo programmeren in andere talen.

Maar nu ben ik bezig met een opzet voor een webshop en nu zit ik me af te vragen of ik een artikel class moet aanmaken.

Het punt waarover ik twijfel is dat ik 2 pagina's wil hebben met artikelgegevens, een zoeklijst ( oftewel 25 artikelen onder elkaar met een thumbnail en een artikelomschrijving en een prijs ) en een detail pagina.
In een andere programmeertaal ( C / Java ) zou ik ervoor kiezen om 1 Object aan te maken alszijnde artikel en dit steeds te gaan hergebruiken.
Maar omdat php alleen maar per page-request bestaat zit ik mij af te vragen of ik echt 1 object wil aanmaken ( met alle overhead ) wat ik na het laden gelijk weer weggooi, of dat ik gewoon rechtstreeks met querys en arrays aan de slag moet gaan.

Voordelen classes :
- Eenduidige aanspreekmanier voor je object
- "Netter" programmeren

Nadelen classes :
- Gigantisch veel overhead op een zoeklijst ( hele classe moet aangemaakt worden en ik gebruik er maar een klein gedeelte van )
- Geen hergebruik, dus alles wat ik opbouw bij een zoeklijst mag ik opnieuw opbouwen bij een detailpagina.

Wat denken jullie dat het makkelijkste is voor een webshop en een artikel classe?

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Er loopt al een soortgelijke discussie hierover:

[php]Array misbruik in php

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Ikzelf gebruik heir altijd associatieve array's voor.
Toevallig vanochtend het topic zitten lezen welke Grijze Vos aanhaalt waarin wordt beargumenteerd dat een object hiervoor beter geschikt zou zijn.
Mij lijkt het erg omslachtig, maar dat is wer afhankelijk van het schaal van het project. Bij een grootschalig iets waar met meerdere mensen aan gewerkt wordt, of aan gewerkt zal worden, ziou ik er wellicht ooit voor kiezen het met objecten te doen.

Ik gebruik wel een centrale functie voor het ophalen van de artikelen welke een genormaliseerde associatieve array teryggeeft.

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
frickY schreef op maandag 18 juni 2007 @ 23:22:
Ikzelf gebruik heir altijd associatieve array's voor.
Toevallig vanochtend het topic zitten lezen welke Grijze Vos aanhaalt waarin wordt beargumenteerd dat een object hiervoor beter geschikt zou zijn.
Mij lijkt het erg omslachtig, maar dat is wer afhankelijk van het schaal van het project. Bij een grootschalig iets waar met meerdere mensen aan gewerkt wordt, of aan gewerkt zal worden, ziou ik er wellicht ooit voor kiezen het met objecten te doen.

Ik gebruik wel een centrale functie voor het ophalen van de artikelen welke een genormaliseerde associatieve array teryggeeft.
Mja, als je die voorbeeldcode ziet die ik gepost heb dan is het redelijk netjes en redelijk efficient. Geen extra geheugen wordt gebruikt want de objecten kunnen gecreeerd worden meteen als de query gedaan wordt. Al met al ben ik 'om' en voor classes.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

een overzicht en een detail pagina zijn twee verschillende use-cases. gebruik daarvoor dan ook twee verschillende objecten:

- Artikel (select * from artikel where id = XX)
- ArtikelList (select top X naam, afbeelding, prijs from artikel)

maar heb je echt zoveel overhead dan ?? dat valt echt wel mee hoor... beter gezegd: als je het goed doet zelfs verwaarloosbaar (bouw sowiso caching in !)

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
@Skafa
Is een ArtikelList niet een numerieke array met Artikel-objecten?

@Grijze Vos
Je voorbeeld met mysql_fetch_object laat inderdaad weinig te wensen over. Behalve dan dat de servers waar ik op moet werken geen PHP5 draaien

Een praktijk voorbeeld van hoe ik het nu vaak oplos;
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function getHeadlines() {
    $result = mysql_query("
        SELECT n.Nieuws_id, n.Nieuws_naam, n.Nieuws_content, n.Nieuws_van, CONCAT_WS('/', d.Dir_naam, u.Upload_naam) AS hoofdfoto
        FROM Nieuws AS n
        LEFT JOIN Fileuploads AS u ON u.Upload_id=n.Nieuws_hoofdfoto
        LEFT JOIN Filedirs AS d ON d.Dir_id=u.Dir_id
        ORDER BY n.Nieuws_van DESC");
    $headlines = array();
    while($row = mysql_fetch_assoc($result)) {
        $row['naam'] = htmlentities($row['Nieuws_naam']);
        $row['body'] = cleanupEditor($row['Nieuws_content']);
        $row['url'] = "/headlines/" . $row['Nieuws_id'] . "-" . safeURL($row["Nieuws_naam"]) . ".html";
        if(!file_exists(DOC_ROOT . "/" . $row['hoofdfoto'])) {
            $row['hoofdfoto'] = false;
        }
        $headlines[] = $row;
    }
    if(sizeof($headlines) == 0) {
        return false;
    } else {
        return $headlines;
    }
}


Als ik me niet vergis zou een deel hiervan naar de class-constructor kunnen, wat me opzich positief lijkt. Heb je tenminste centraal staan hoe een nieuwsitem eruit ziet. terwijl ik nu het normaliseren van de naam, body en url een paar keer opnieuw moet doen in andere functies. Bovenstaand werkt overigens erg prettig.. maar msischien dat het met een object nog prettiger wordt.

[ Voor 96% gewijzigd door frickY op 19-06-2007 15:44 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Ik was gisteren blij verrast met de notie van Grijze Vos dat PHP sinds versie 5 mysql_fetch_object nuttig heeft gemaakt. Tot nog toe gebruikte ik altijd een enigszins omslachtige manier om toch vanuit een collectie klasse private properties van objecten te kunnen zetten:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Foo {

    private $bar;
    public $quux;

    public function __construct($arr = null) {
        if (is_array($arr)) {
            foreach($arr as $key => $val) {
            $this->$key = $val;
        }
    }

    public static function getBaseSQL() {
        $sql = 'SELECT `bar`,`quux` FROM `foo`';
        return $sql;
    }
}

Class FooCollection extends Collection {
    
    public function load() {
        $sql = sprintf("%s WHERE `condition` = true",
                    Foo::getBaseSQL()
                );
        if ($succes = $this->DB->query($sql)) {
            while($row = $this->DB->fetchRow()) {
                $foo = new Foo($row);
                $this->addItem($foo);
            }
        }
        return $succes;
    }
}

Reden om het zo te doen, is vooral overzicht voor mezelf. Alle zaken die met "Foo" te maken hebben staan centraal in de klassedefinitie van Foo. Overhead maak ik me niet zo druk om eerlijk gezegd, ten eerste omdat die waarschijnlijk wel mee valt en ten tweede omdat een extra server veel goedkoper is dan extra tijd kwijt zijn aan onderhoud...

[ Voor 0% gewijzigd door T-MOB op 19-06-2007 09:52 . Reden: Foutje.. ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op dinsdag 19 juni 2007 @ 03:35:
een overzicht en een detail pagina zijn twee verschillende use-cases. gebruik daarvoor dan ook twee verschillende objecten:

- Artikel (select * from artikel where id = XX)
- ArtikelList (select top X naam, afbeelding, prijs from artikel)
Onzin. Wat is nu het verschil tussen een artikel als hij los is of als hij in een lijst staat? Niks. Een lijst artikelen is niet meer dan dat. Een lijst met daarin artikel objecten. Keurig voor beide usecases herbruikbaar. (eventueel kun je in het geval van de lijst bepaalde properties niet vullen uit efficientie, maar daarvoor hoef je niet een andere class te maken)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • rvrbtcpt
  • Registratie: November 2000
  • Laatst online: 19-09 16:18
Misschien lijkt het nu ook wat omslachtig om met objecten te gaan werken, maar als je nu een beetje een mooi framework maakt dan zal het later uitbreiden en herbruiken van je webshop code wel gemakkelijker gaan.
Hoe snel krijg je niet de vraag of je niet nog even het een of ander erbij wil maken.
Een nieuw product attribuut, relaties met andere producten, kortingen, en dan zal het waarschijnlijk fijner werken als je reeds een fatsoenlijke basis hebt.

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Gomez12 schreef op maandag 18 juni 2007 @ 22:44:
- Gigantisch veel overhead op een zoeklijst ( hele classe moet aangemaakt worden en ik gebruik er maar een klein gedeelte van )
Overhead smoverhead. Het aanmaken van wel 25 objecten kost gewoon geen tijd. En als je in de lijst niet alle info nodig hebt, vul je toch gewoon de dingen als de uitgebreide beschrijving e.d. niet?

"Premature optimization is the root of all evil."

https://niels.nu


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
@Grijze Wolf
Stel ik zou op een PHP5 bak werken en de methode gebruiken die jij aangeeft. Zou ik dan het volgende kunnen doen in plaats van de methode die ik eerder postte?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
class Nieuwsitem {
    private $Nieuws_id, $Nieuws_van, $Nieuws_tot, $naam, $body, $url;       
    function Nieuwsitem() {
        $this->naam = htmlentities($this->Nieuws_naam); 
        $this->body = cleanupEditor($this->Nieuws_content); 
        $this->url = "/headlines/" . $this->Nieuws_id . "-" . safeURL($this->Nieuws_naam) . ".html"; 
        if(!file_exists(DOC_ROOT . "/" . $this->hoofdfoto)) { 
            $this-?hoofdfoto = false; 
        }       
    }   
}

function getHeadlines() { 
    $result = mysql_query(" 
        SELECT n.Nieuws_id, n.Nieuws_naam, n.Nieuws_content, n.Nieuws_van, CONCAT_WS('/', d.Dir_naam, u.Upload_naam) AS hoofdfoto 
        FROM Nieuws AS n 
        LEFT JOIN Fileuploads AS u ON u.Upload_id=n.Nieuws_hoofdfoto 
        LEFT JOIN Filedirs AS d ON d.Dir_id=u.Dir_id 
        ORDER BY n.Nieuws_van DESC"); 
    $headlines = array(); 
    while($nieuwsItem = mysql_fetch_object($result, "Nieuwsitem")) {
        $headlines[] = $nieuwsItem; 
    } 
    if(sizeof($headlines) == 0) { 
        return false; 
    } else { 
        return $headlines; 
    } 
} 
?>


Ik heb het 'normaliseren' express in Nieuwsitem() gedaan in plaats van __construct(), omdat ik niet zeker weet of de variabelen daar al beschikbar zijn? In de __construct zou wel mooier zijn.
Of kan het normaliseren op dat punt helemaal nog niet? Zoniet zie ik het voordeel boven arrays namelijk niet zo. Zowel lijkt het me ideaal :)

[ Voor 17% gewijzigd door frickY op 19-06-2007 15:46 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
frickY schreef op dinsdag 19 juni 2007 @ 15:42:
@Grijze Wolf
Stel ik zou op een PHP5 bak werken en de methode gebruiken die jij aangeeft. Zou ik dan het volgende kunnen doen in plaats van de methode die ik eerder postte?
Ik heb het net met de volgende constructor getest:
PHP:
1
2
3
4
public function __construct() {
    $this->_DB = Registry::getInstance()->get('DB');
    $this->_foo = $this->_name;
}

Resultaat is dat de _foo property dezelfde waarde heeft als de _name property uit de database. Ergo, het werkt :). Waarom je htmlentities() over properties van je object zou willen gooien is me overigens wel een raadsel

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Gomez12 schreef op maandag 18 juni 2007 @ 22:44:
Nadelen classes :
- Gigantisch veel overhead op een zoeklijst ( hele classe moet aangemaakt worden en ik gebruik er maar een klein gedeelte van )
Voor zover ik weet (ervaring met C++) voegt het alleen maar een pointer naar de correcte vtable toe voor de data.

Acties:
  • 0 Henk 'm!

Verwijderd

Volgens mij werd het eerder in dit topic ook al aangehaald: ga in hemelsnaam niet nadenken over overhead als je een pagina met wat zoek resultaten moet tonen. Heel veel webscripters denken al gauw dat ze een of andere `killer-app` maken maar wees realistisch. 9 van de 10 websites/applicaties die de meesten van ons maken hebben niets te maken met overheadkwesties. Succes in ieder geval, objecten zijn vaak aantrekkelijk overigens - hoe minimaal het voordeel ook is ten opzichte van arrays e.d.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Wat Glimi bedoeld is dat er eigenlijk gewoon helemaal geen overhead is. Zeker als je het vergelijkt met de DB query die er vaak voor uitgevoerd wordt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Janoz schreef op woensdag 20 juni 2007 @ 07:50:
Wat Glimi bedoeld is dat er eigenlijk gewoon helemaal geen overhead is. Zeker als je het vergelijkt met de DB query die er vaak voor uitgevoerd wordt.
Tenzij PHP echt iets heel raars doet wat ik niet weet, denk ik ook dat dat "gigantische overhead" zwaar en zwaar overdreven is. In nagenoeg alle (moderne) programmeertalen waar ik mee gewerkt hebt is het instantieeren van enkele objecten nou niet hetgeen je op wilt optimaliseren in een dergelijke usecase.

Als je nu in een wetenschappelijk algoritme 1000'en objecten in een loop aanmaakte die 1000.000'en keren doorlopen werd, ja dan zou je eens kunnen gaan kijken naar alternatieven.

Maar 25 objecten aanmaken is helemaal niets voor een enkele request. Alleen al de HTTP overhead is velen malen groter, laat staan de DB query tijd ;)

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • Gwaihir
  • Registratie: December 2002
  • Niet online
Verwijderd schreef op dinsdag 19 juni 2007 @ 23:27:
Volgens mij werd het eerder in dit topic ook al aangehaald: ga in hemelsnaam niet nadenken over overhead als je een pagina met wat zoek resultaten moet tonen.
Ja en nee..

Ik heb vaker dan me lief is applicaties gezien die bij 'artikel' zijn begonnen met denken en de artikellijst er vervolgens zwaar belabberd overheen hebben geplakt. Je kent het vast wel: de lijst doet een query om de artikel-ids te krijgen en ieder artikel wat daarmee aangemaakt wordt doet vervolgens een eigen query om z'n gegevens op te halen |:(.

Oh, en die lijst is uiteraard met slechts een simpele WHERE clause uit de database gevist, in een array gelezen en dan door PHP naar wens gesorteerd 8)7.

De point van deze rant: er is wel degelijk "gigantische overhead" om over na te denken. Die zit alleen niet in het wel of niet gebruiken van bepaalde taalconstructies van PHP, maar in het wel of niet slim met je database om gaan.

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Birdie schreef op woensdag 20 juni 2007 @ 11:13:
De point van deze rant: er is wel degelijk "gigantische overhead" om over na te denken. Die zit alleen niet in het wel of niet gebruiken van bepaalde taalconstructies van PHP, maar in het wel of niet slim met je database om gaan.
Da's geeen overhead. Da's gewoon domme dingen doen. Ik heb tijdens m'n studie bij een webdesignbedrijfje gewerkt waar ik een CMS moest onderhouden. Een klant klaagde dat het zoeken te traag ging. Na eens in die functionaliteit gedoken te zijn (was nog met dat deel bezig geweest) bleek dat die vorige 'programmeur' inderdaad een select * from bla where X, Y, Z deed, uit dat resultaat alleen de IDs gebruikte, en dan per row weer een select deed om de rest van de resultaten op te halen.

Er zaten nog veel meer fouten in natuurlijk, maar dat was geen kwestie van niet nadenken over 'overhead', dat was iemand die gewoon de klok had horen luiden en met een ijslepel aan kwam zetten.

https://niels.nu


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Even een korte insight hoe ik het ongeveer doe:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class Entity {
   function Entity ( $tableName ) { ... }
   /* ... */
   function getRecordSetBy ( $whereClause = null, $orderClause = null, $limitClause = null, etc .... ) {
      return new RecordSet ( 
         $this, 
         $GLOBALS['db']->selectAll ( 
            $this->getSelectQuery ( 
               $whereClause, 
               $orderClause, 
               $limitClause, etc .... 
            )
         ) 
      );
   }



   function newRecord ( $recordValues ) {
      $recordClass = $this->getRecordClass ();
      return new $recordClass ( $this, $recordValues );
   }
   /* ... */
}

class RecordSet extends ArrayList {
   function RecordSet ( &$entity, $values ) {
      ArrayList::ArrayList ( $values );
      $this->entity =& $entity;
   }
   /* ... */
   function next () {
      return $this->entity->newRecord ( parent::next () ) ;
   }
   /* ... */
}

class Record extends Map {
   function Record ( &$entity, $values ) {
      Map::Map ( $values );
      $this->entity =& $entity;
   }
   /* ... */
}

class NewsEntity extends Entity {
   function getRecordClass () { return 'NewsItem'; } 
}

class NewsItem extends Record {
   function getDateDisplay () {
      return date ( config::get ( 'date.default-format' ), $this->get ( 'timestamp' ) );
   }
}

$e = new NewsEntity ( 'news_items' );
$records = $e->getRecordSetBy ( new SqlWhereClause( 'is_public', 'true' ) );
while ( $r = $records->next() ) {
   echo '<h2>', $r->getTitle(), '</h2>';
   echo '<p>', $r->getIntro (), '... <a href="#">Lees verder</a></p>';
}


Even wat kort door de bocht allemaal maar dat is het idee wel zo'n beetje. De enige overhead waar ik niet blij mee ben is dat de RecordSet geinstantieerd wordt met een result array die al helemaal uit de database getrokken is, maar goed, dat is overkomelijk zo lang je geen recordsets van 100'en items binnen gaat sleuren waar allemaal TEXT velden in staan ofzo.

Kortom; gewoon doen, OO is veel prettiger werken dan allemaal arrays waar je helemaal simpel van wordt.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1