[PHP/MySQL] Producten vergelijken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • royduin
  • Registratie: November 2007
  • Laatst online: 18-09 15:49
Beste tweakers,

ben ik weer met een vraag. Lijkt me niet al te moeilijk maar ik kom er niet uit :(
Ik heb een database met daarin allerlei product informatie. Nu wil ik producten kunnen vergelijken, hoe ik de gegevens in de database heb staan is dit mogelijk. Enkel hoe echo ik dit netjes?

De database:
producten_new:
id, naam, prijs, fabrikant
1,Laptopje 1, 500, Asus
2, Laptopje 2, 600, Toshiba

producten_specs:
product_id, cat, name, value
1,Processor,Kloksnelheid,2.4Ghz
1,Processor,Socket,775
1,Werkgeheugen,Capaciteit,4GB
2,Processor,Kloksnelheid,2.6Ghz
2,Processor,Socket,775

De output moet worden (in een tabel):
------------------------------
Naam: Laptopje 1 | Laptopje 2
Prijs: 500 | 600
Merk: Asus | Toshiba
------------------------------
Processor
------------------------------
Kloksnelheid: 2.4Ghz | 2.6Ghz
Socket: 775 | 775
------------------------------
Werkgeheugen
------------------------------
Capaciteit: 4GB | -

Weetjes:
- Er moeten meerdere producten vergeleken kunnen worden. Er is een $_GET met daarin meerdere product id's.
- Het kan voorkomen zoals in het voorbeeld dat een product niet alle specificaties heeft. Zo ook niet opgeslagen in de database, zie werkgeheugen in het voorbeeld.

Ik verwacht absoluut niet dat alles voorgekauwd gaat worden. Enkel krijg ik het niet "verticaal" voor elkaar. "Horizontaal" gaat het wel (zoals het ook in de database staat): 1,Laptopje 1, 500, Asus. Hoe pak ik dit aan?

Alvast bedankt!

Acties:
  • 0 Henk 'm!

  • Maethor2
  • Registratie: Augustus 2010
  • Laatst online: 12-06-2024
royduin schreef op woensdag 13 april 2011 @ 17:01:
Ik verwacht absoluut niet dat alles voorgekauwd gaat worden. Enkel krijg ik het niet "verticaal" voor elkaar. "Horizontaal" gaat het wel (zoals het ook in de database staat): 1,Laptopje 1, 500, Asus. Hoe pak ik dit aan?
Toon eens je "horizontale" code, dan kunnen we makkelijk zeggen wat je moet doen om het anders te zetten

Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Geselecteerde producten doornemen om te kijken met welke product properties je allemaal te maken hebt. Dit worden de namen op je X as in de tabel. Daarna ga je de producten doorlopen in een loopje om de tabel op te bouwen. Wanneer je de properties moet weergeven van de producten maak je gebruik van de eerder properties lijst.

Per product loopje deze properties lijst door, wanneer een product deze propertie niet heeft dan laat je hem leeg anders vul je hem. Zo ga je alle producten door en vul je de tabel. Het is alleen even de truc hoe je dit gaat echoen of je met een <table> werkt of met <div>. Je moet voor de manier kiezen van producten doorlopen welke het efficiëntste is en daarna het beste past bij je weergave.

Acties:
  • 0 Henk 'm!

  • royduin
  • Registratie: November 2007
  • Laatst online: 18-09 15:49
@Maethor2: Niet echt boeiend, enkel voor de product info:
PHP:
1
2
3
4
5
6
7
<?php
$ids = "1,2,3";
$query = mysql_query("SELECT * FROM producten_new WHERE id IN (".mysql_real_escape_string($ids).")");
while($row = mysql_fetch_assoc($query)){
  echo "Naam: ".$row['naam']." - &euro;".$row['prijs']." - Merk: ".$row['fabrikant']."<br />";
}
?>


Zo heb ik de producten onder elkaar. Wat ik hier kan doen is dit in een div zetten. Tussen naam, prijs en merk een br'etje en alle div'jes van links naar rechts weergeven.
Enkel kan dit niet met de producten_specs omdat we daar geen vaste velden hebben (niet bij elk product is dezelfde eigenschap gedefinieerd). Eerst een lijst met alle eigenschappen (links). Dan het volgende divje waar de specs van dat product ge'echo'ed worden. Met br'etjes. Mist er een eigenschap staat deze niet achter de juiste eigenschap..

@4Real: Klinkt logisch. Nu de uitvoering nog :P Lees hem zo nog een aantal keer door en straks even wat proberen. Denk dat ik alweer een stukje verder ben! :D

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Wat ik zou doen is een Array vullen in PHP met de verschillende producten.
PHP:
1
2
3
4
$data = Array(
  1 => Array("cpu"=>"Intel", "ram"=>"2gig"),
  2 => Array("cpu"=>"AMD", "hd"=>"1TB")
);

En bij het opbouwen van dat array sla je alle voorbijkomende attributen op in een ander array, uniek natuurlijk.

En dan met forEach door dat 2e array lopen en daarin met forEach door je $data, en per product kijken of dat atribuut bestaat.

Dat is althans mijn 1e ingeving :)

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • royduin
  • Registratie: November 2007
  • Laatst online: 18-09 15:49
We zijn alweer een stukje verder..
Alleen het gebruik van sessions is niet echt handig, beter een array hiervoor gebruiken zoals jullie ook aangeven. Morgen weer verder experimenteren. Ik laat weer van me horen.

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
$content .= '<div style="float: left; width: 200px;">';
    $query = mysql_query("SELECT DISTINCT cat,name FROM producten_specs WHERE product_id IN (".$_SESSION['vergelijken'].") ORDER BY cat,name ASC");
    while($row = mysql_fetch_assoc($query)){
        //echo $row['cat'].' - '.$row['name'].' - '.$row['value'].'<br />';
        //Array ipv session..
        $_SESSION[$row['cat'].'-'.$row['name']] = TRUE;
        $content .= $row['cat'].' - '.$row['name'].'<br />';
    }
    $content .= '</div>';
    
    $content .= '<div style="float: left; width: 200px;">';
    $query2 = mysql_query("SELECT * FROM producten_specs WHERE product_id IN (".$_SESSION['vergelijken'].") ORDER BY product_id,cat,name ASC");
    while($row2 = mysql_fetch_assoc($query2)){
        
        //array van hierboven gebruiken om te kijken of die spec aanwezig is..
        
        if($row2['product_id'] != $product_id){
            $content .= '</div>';
            $content .= '<div style="float: left; width: 200px;">';
            $content .= $row2['value'].'<br />';
            $product_id = $row2['product_id'];
        } else {
            $content .= $row2['value'].'<br />';
        }
        
        
    }
    $content .= '</div>';

Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
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
<?php 

$resource = mysql_query("SELECT DISTINCT cat,name FROM producten_specs WHERE product_id IN (".$_SESSION['vergelijken'].") ORDER BY cat,name ASC"); 

$specList = array();

while($row = mysql_fetch_assoc($resource))
{ 
    if ( isset($specList) === false )
    {
        $specList[$row['cat']] = array();
    }

    array_push($specList[$row['cat']], $row['name']);
} 

// mogelijkheid om specList te sorteren, multisort weet niet of dat ook wel
// anders kun je categorien als 'name' in één keer sorteren

$htmlList = array();

$resource = mysql_query("SELECT * FROM producten_specs WHERE product_id IN (".$_SESSION['vergelijken'].") ORDER BY product_id,cat,name ASC"); 
while($row = mysql_fetch_assoc($resource))
{
    foreach ($specList as $category => $name)
    {
        if ( isset($htmlList[$category]) === false )
        {
            $htmlList[$category] = array();
        }

        if ( isset($htmlList[$category][$name]) === false )
        {
            $htmlList[$category][$name] = array();
        }

        $result = ( isset($row[$name]) === true ) ? $row[$name] : '';

        array_push($htmlList[$category][$name], $result);
    }
}

// Als goed is heb je nu een array waar je doorheen kunt lopen om de output te genereren.
// Eerst kom je alle categorieren tegen (welke mogelijk zijn gesorteerd als je dat daar boven al hebt gedaan [zowel cat als name niveau])
// Daarna kom je bij de spec naam uit en daar heb je meerdere resultaten van de producten die je vergelijkt.
// Als een product de spec heeft dan is het resultaat opgenomen anders is het leeg zodat je een mooi grid kunt opbouwen

?> 


Eerder had ik al in zijn abstract verteld hoe het ongeveer zou kunnen en hier heb ik het toegepast op je code. Gooi het er eens in en als je met print_r de array print dan kun je wel zien wat het resultaat zal zijn.

Acties:
  • 0 Henk 'm!

  • royduin
  • Registratie: November 2007
  • Laatst online: 18-09 15:49
Bedankt voor je reactie! Ben ermee aan de gang gegaan, helaas niet het juiste resultaat kunnen krijgen.
Inmiddels waarschijnlijk heel omslachtig en raar bezig geweest maar het resultaat is goed:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    $query = mysql_query("SELECT DISTINCT cat,name FROM producten_specs WHERE product_id IN (".$_SESSION['vergelijken'].") ORDER BY cat,name ASC");
    while($row = mysql_fetch_assoc($query)){
        $aanwezig .= $row['cat'].'-'.$row['name'].',';
        if($row['cat'] != $categorie){
            $waarde[$row['cat'].'-'.$row['name']] = '<tr><td><strong><u>'.$row['cat'].'</u></strong></td></tr>';
        }
        $categorie = $row['cat'];
        $waarde[$row['cat'].'-'.$row['name']] = '<tr><td><strong>'.$row['name'].'</strong></td>';
    }

    $query2 = mysql_query("SELECT * FROM producten_specs WHERE product_id IN (".$_SESSION['vergelijken'].") ORDER BY product_id,cat,name ASC");
    while($row2 = mysql_fetch_assoc($query2)){
        $waarde[$row2['cat'].'-'.$row2['name']] .= '<td>'.$row2['value'].'</td>';       
    }
    
    $content .= '<table>';
    $values = explode(",", $aanwezig);
    foreach($values as $value){
        $content .= $waarde[$value].'</tr>';
    }
    $content .= '</table>';


Hoor graag aan- of opmerkingen.

Morgen weer verder proberen, één probleem. Het eerste product heeft alle specificaties. Lege value bij product 1 wordt ingevuld door de value van het 2e product.

[ Voor 31% gewijzigd door royduin op 14-04-2011 22:06 ]


Acties:
  • 0 Henk 'm!

  • fleppuhstein
  • Registratie: Januari 2002
  • Laatst online: 07-09 13:37
Mijn advies is om eerst eens te gaan normaliseren. Bij een vergelijkings-site is het een redelijk aanname dat de input via verschillende personen/kanalen wordt ingevoerd. De ene persoon heeft het over "Werkgeheugen". Dan andere weer over geheugen. En de derde persoon doet de invoer in MB terwijl de eerste en twee hebben in gevoerd in GB.

Ik zou een aantal tabellen introduceren

product:
----
id serial
name varchar(512)

property
---
id serial
name varchar(512)

product_property
----
product integer FK product.id
property integer FK property.id
value varchar(64)
unit integer (numerieke values uitspecificeren in class constants)
updated_at date

Is zomaar iets gebaseerd op 5 minuten modeleren. Dit stelt je in staat om eventueel zelfs pc's met laptops te vergelijken. en zelfs toekomstige features eenvoudig bij te voegen, denk aan LightPeak, USB 3.0 etc.

Je ziet dan ook gelijk de php classes vanzelf ontstaan. Hierdoor kan je natuurlijk weer een vergelijkings class schrijven welkeheel eenvoudig verschillen links, verschillen rechts en overeenkomsten kan tonen.

[ Voor 20% gewijzigd door fleppuhstein op 14-04-2011 22:09 ]


Acties:
  • 0 Henk 'm!

  • royduin
  • Registratie: November 2007
  • Laatst online: 18-09 15:49
De data komt bij icecat vandaan. Dit is allemaal al gedaan :D

Acties:
  • 0 Henk 'm!

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
De output is zeker geen valide HTML zo ver ik kan interpreteren:

HTML:
1
2
<tr><td>een cat</td></tr>
<tr><td>een name</td><td>een value</td></tr>


Je uit te poepen data heeft de volgende structuur die je ook zal moeten bouwen: vgl-tabel[cat][name][product].

code:
1
2
3
4
5
6
7
8
9
10
11
vgl-tabel Array(
  cat 1 Array (
    name 1 Array ( value 1 product 1, null, value 1 product 3 ),
    name 5 Array ( value 5 product 1, value 5 product 2, value 5 product 3 )
  ),
  cat 7 Array (
    name 2 Array ( value 2 product 1, value 2 product 2, value 2 product 3 ),
    name 3 Array ( null, value 3 product 2, value 3 product 3 ),
    name 4 Array ( value 4 product 1, value 4 product 2, value 4 product 3 )
  )
)
Volgens mij kan je de array in één keer opbouwen en dan moet je em ook nog eens uitlezen. Ik heb het gevoel dat je nu opbouw en uitlezen mixt...
Pagina: 1