[PHP] Zit vast met download systeem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 18-08 18:12
Na een hele dag kloten open ik hier maar een post.

Ik ben dus bezig met een download systeem met categorien, met de tabellen:

Tabel "download_cats":
+---+--------+---------+
| id | naam | uitleg |
+---+--------+---------+

Tabel "downloads":
+---+------+---------+
| id | titel | cat_id |
+---+------+---------+

"download_cats.id" is dus gelijk aan "downloads.cat_id"

Nu wil ik in mijn admin in lijstje maken van downloads en daarachter de naam van de categorie waarin die zit. Dit is mijn code tot nu:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$s_categorie = mysql_query ( "SELECT id, naam FROM download_cats" ) or die ( mysql_error ( ) );
$s_downloads = mysql_query ( "SELECT id, titel, cat_id FROM downloads" ) or die ( mysql_error ( ) );
if ( mysql_num_rows ( $s_downloads ) ) {
    while ( $f_downloads = mysql_fetch_assoc ( $s_downloads ) ) {
        echo '  <table width="600"><tr>'."\n";
        echo '    <td width="25%">'.$f_downloads['titel'].'</td>'."\n";
        
        $f_categorie = mysql_fetch_assoc($s_categorie)
        $f_categorie["id"]  == $f_downloads["cat_id"] ) {
        echo '<td width="25%">' .$f_categorie['naam']. '</td>'."\n";

        echo '    <td width="25%"><a href="download_bewerken.php?actie=bewerken&id='.$f_downloads['id'].'">Bewerken</a></td>'."\n";
        echo '    <td width="25%"><a href="download_bewerken.php?actie=delete&id='.$f_downloads['id'].'">Verwijderen</a></td>'."\n";
        echo '  </tr></tabel>'."\n";
        }
    } else {
        echo 'geen downloads';
}

Hiermee krijg ik wel een lijstje met de downloads, maar niet met de juiste categorie erachter. In de kolom met de categorien komt een normaal lijstje met alle categorien, zoals dit:
(ik heb 6 downloads en 3 categorien)

+----------------+-----------------+-----------+-------------+
| download a | categorie 1 | bewerk | verwijder |
+----------------+-----------------+-----------+-------------+
| download b | categorie 2 | bewerk | verwijder |
+----------------+-----------------+-----------+-------------+
| download c | categorie 3 | bewerk | verwijder |
+----------------+-----------------+-----------+-------------+
| download d | ---------------- | bewerk | verwijder |
+----------------+-----------------+-----------+-------------+
| download e | ---------------- | bewerk | verwijder |
+----------------+-----------------+-----------+-------------+
| download f | ---------------- | bewerk | verwijder |
+----------------+-----------------+-----------+-------------+

Er zullen nog wel veel meer andere fouten in de code zitten, maar ik ben ook nog niet zolang met PHP en MYSQL bezig.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Maak hoe dan ook een associatie tabel. Dat geeft je wat meer ruimte in de toekomst:
code:
1
2
3
4
5
CREATE TABLE downloads_download_cat
(
  download_id INT,
  cat_id INT
)

Zo kun je later ook meerdere categorieen aan 1 download koppelen.

Verder zou ik dan een query in deze richting gebruiken:
code:
1
2
3
4
5
6
7
8
SELECT
  d.*,
  c.naam
FROM
  downloads d,
  download_cats c
WHERE
  d.cat_id = c.id

Snappie em?

Wat jij verkeerd doet is dat je alle categorieen gewoon los ophaalt. Bij iedere download haal je dan gewoon een nieuwe categorie zonder hem te koppelen aan de betreffende download. Na 3 downloads ben je dan door je categorieen heen en zie ze dus niet meer verschijnen.

[ Voor 28% gewijzigd door Michali op 04-01-2005 18:58 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 18-08 18:12
Bedankt voor je reactie.
Die extra tabel maakt het voor mij alleen maar moeilijker denk ik, en ik zal een een download ook niet aan meerdere categorien toevoegen dus ik doe dat liever niet.

Ik heb een normale code nodig die van de downloads.cat_id kijkt in de download_cats tabel welke "naam" bij het "cat_id" hoort.

Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 11:30

Guldan

Thee-Nerd

Nu ik je code zo ongeveer zelf zit te schrijven zie ik ook in 1 keer wat je fout is.

Ik gebruik zelf altijd mysql_fetch_array, maar het probleem is dat je van de categorien niet de betreffende categorie ophaalt maar gewoon alle. Ik zou zoiets gebruiken:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$s_downloads = mysql_query ( "SELECT id, titel, cat_id FROM downloads" ) or die ( mysql_error ( ) );

    while($ophaal1 = mysql_fetch_array($s_downloads))
    {
    //hala de waarden uit de array ophaal en sla dit op in variablen
    $id = $ophaal1['id'];
    $titel = $ophaal1['titel'];
    $cat_id = $ophaal1['cat_id'];
    
        //haal bij de categorie die in $cat_id opgeslagen is de rest van de informatie op a.d.v
        //van de andere query.
        $s_categorie = mysql_query ( "SELECT id, naam FROM download_cats WHERE id =$cat_id" ) or die ( mysql_error ( ) );
        while($ophaal2= mysql_fetch_array($s_categorie))
        {
        $categorieid = $ophaal2['id'];
        $categorienaam = $ophaal2['naam'];
        
        //geef de waarden uit de tabel op het scherm weer
        echo "Download id:" . $id . "Titel:" . $titel ."Categorie id:" . $cat_id. "Categorie naam" . $categorienaam;
        }
    }


ik hoop dat het zo wat duidelijker is. mysql_fetch_array haalt ook gewoon de waarden op uit de query maar zet deze in een array. meer uitleg is wel te vinden op php.net. Deze code is ongetest maar ik geloof dat er geen typfouten in zitten. Tenmiste niet in de php :). Ik hoop ook dat het commentaar duidelijk maakt wat jij fout hebt gedaan.

[ Voor 9% gewijzigd door Guldan op 04-01-2005 20:11 ]

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • MaTriCX
  • Registratie: Augustus 2002
  • Laatst online: 18-07-2024
De tip van Michali is vrij handig.
Omdat je net begint met het leren van PHP en MySQL, kun je jezelf beter proberen aan te leren de juiste syntax van SQL te gebruiken voor het ophalen van data.
Wat jij nu doet is twee queries uitvoeren en vervolgens de een vergelijken met de ander. Dit kan ook in 1, althans als ik begrijp wat je wilt doen.

Ik begrijp uit je verhaal dat je uit de twee tabellen de naam van de download wilt hebben en de bijbehorende naam van de categorie.

De query zou er dan zo uit moeten zien:
code:
1
2
3
4
SELECT d.titel, dc.titel, dc.uitleg 
FROM downloads d, download_cats dc
WHERE d.cat_id = dc.id 
ORDER by d.titel ASC

Deze query selecteert de downloadtitel, categorietitel en de categorieuitleg uit de juiste tabellen. Vervolgens controleert die deze aan de hand van de unieke code. De downloads die geen categorie hebben worden met deze query niet getoond. Hiervoor is weer een iets ingewikkeldere query voor nodig.

in php:
PHP:
1
2
3
4
5
6
// $sql_query is de query
$result_query = mysql_query( $sql_query ); // Eventueel $dbi voor de connectie met de database
// ...
while ( list( $dtitel, $dctitel, $dcuitleg ) = mysql_fetch_array( $result_query ) ) {
   echo "$dtitel, $dctitel, $dcuitleg<br />";
}

Hopelijk is dit ongeveer wat je bedoeld ?

Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 11:30

Guldan

Thee-Nerd

an sich kan de ts dat wel gebruiken maar sommige versie's van mysql ondersteunen nog geen subquery's (dat je dus uit 2 tabellen tegelijk dingen selecteerd). Dan kan hij mijn oplossing beter gebruiken.

ps. thnks voor het showen van de list functie Matricx. Das wel handig eigenlijk. Ik kende de hele functie nog niet :).

edit:

ff wat uitleg voor de ts toegevoegd

[ Voor 19% gewijzigd door Guldan op 04-01-2005 20:43 ]

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • MaTriCX
  • Registratie: Augustus 2002
  • Laatst online: 18-07-2024
Guldan schreef op dinsdag 04 januari 2005 @ 20:41:
an sich kan de ts dat wel gebruiken maar sommige versie's van mysql ondersteunen nog geen subquery's (dat je dus uit 2 tabellen tegelijk dingen selecteerd). Dan kan hij mijn oplossing beter gebruiken.

ps. thnks voor het showen van de list functie Matricx. Das wel handig eigenlijk. Ik kende de hele functie nog niet :).

edit:

ff wat uitleg voor de ts toegevoegd
Subqueries zijn queries waarin het select-statement dubbel wordt gebruikt, dus zoiets als dit:
code:
1
2
3
4
5
6
7
SELECT id, titel 
FROM boek
WHERE boek.id IN (
   SELECT id 
   FROM engelse_boeken 
   WHERE titel LIKE "%Animal Farm%"
)

En die worden inderdaad pas sinds de laatste versies van MySQL ondersteund. De query die ik hem gaf bestaan al een redelijke tijd, maar het is maar net wat de TS makkelijker vindt.

En graag gedaan trouwens :) Het is een stuk overzichtelijker in je programmeercode, vind ik zelf.

Acties:
  • 0 Henk 'm!

  • Alex
  • Registratie: Juli 2001
  • Laatst online: 20-08 21:38
Michali schreef op dinsdag 04 januari 2005 @ 18:55:
Maak hoe dan ook een associatie tabel. Dat geeft je wat meer ruimte in de toekomst:
code:
1
2
3
4
5
CREATE TABLE downloads_download_cat
(
  download_id INT,
  cat_id INT
)

Zo kun je later ook meerdere categorieen aan 1 download koppelen.
Dit is een nieuwe manier van database design :) !!
Waarom zou je een koppeltabel gebruiker als je gewoon een 1:n relatie hebt? Als je nou een n:m had. Dan kon je er niet omheen. Of je krijgt alsnog rare koppelingen. Mara in dit geval ga je uit van een situatie dit vrij waarschijnlijk zich nooit voor gaat doen. Daarbij is het database technisch niet bepaald verantworod lijkt me.
Verder zou ik dan een query in deze richting gebruiken:
code:
1
2
3
4
5
6
7
8
SELECT
  d.*,
  c.naam
FROM
  downloads d,
  download_cats c
WHERE
  d.cat_id = c.id

Snappie em?

Wat jij verkeerd doet is dat je alle categorieen gewoon los ophaalt. Bij iedere download haal je dan gewoon een nieuwe categorie zonder hem te koppelen aan de betreffende download. Na 3 downloads ben je dan door je categorieen heen en zie ze dus niet meer verschijnen.
Persoonlijk moet ik zeggen dat ik niet erg dol ben op deze query. Zeker voor een beginneling is dit vrij onleesbaar. Daarbij betekent dit dat er items verdwijnen die geen categorie hebben. Een niet ideale situatie.

Kom je als snel uit op het ietswat leesbaardere:
code:
1
2
3
4
5
6
7
8
9
SELECT
  dl.naam as dlNaam,
  dl.uitleg as dlUitleg,
  cat.naam as catNaam
FROM
  downloads As dl
LEFT JOIN download_cats As cat
ON
  dl.cat_id = cat.id

Deze post is bestemd voor hen die een tegenwoordige tijd kunnen onderscheiden van een toekomstige halfvoorwaardelijke bepaalde subinverte plagiale aanvoegend intentioneel verleden tijd.
- Giphart


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Alex de Groot schreef op dinsdag 04 januari 2005 @ 20:58:
[...]


Dit is een nieuwe manier van database design :) !!
Waarom zou je een koppeltabel gebruiker als je gewoon een 1:n relatie hebt? Als je nou een n:m had. Dan kon je er niet omheen. Of je krijgt alsnog rare koppelingen. Mara in dit geval ga je uit van een situatie dit vrij waarschijnlijk zich nooit voor gaat doen. Daarbij is het database technisch niet bepaald verantworod lijkt me.
Het lijkt me toch wel voor de hand liggend dat een download meerdere categorieen kan hebben. En dit is zeker geen nieuwe manier van database design. Er zijn zat programmeurs die aanraden altijd een associatie tabel te gebruiken. Het hoeft natuurlijk niet, maar ik zie eerlijk gezegd weinig problemen als j ehet wel zo doet.
Persoonlijk moet ik zeggen dat ik niet erg dol ben op deze query. Zeker voor een beginneling is dit vrij onleesbaar. Daarbij betekent dit dat er items verdwijnen die geen categorie hebben. Een niet ideale situatie.

Kom je als snel uit op het ietswat leesbaardere:
code:
1
2
3
4
5
6
7
8
9
SELECT
  dl.naam as dlNaam,
  dl.uitleg as dlUitleg,
  cat.naam as catNaam
FROM
  downloads As dl
LEFT JOIN download_cats As cat
ON
  dl.cat_id = cat.id
Ik had eigenlijk verwacht dat iedere download verplicht een categorie zou moeten hebben. Verder is een LEFT JOIN echt niet begrijpelijk voor een beginner, ik weet niet waar je dat vandaan haalt? Verder is deze query ook echt niet leesbaarder. Bovendien ben je ook nog eens inconsequent met 'as' en 'As'. Als je de syntax kent weet je precies wat er gebeurt. Als een programmeur deze syntax begrijpt, dan begrijpt hij zeker ook de oplossing die ik net gaf. Die is vrij basis.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Alex
  • Registratie: Juli 2001
  • Laatst online: 20-08 21:38
Michali schreef op dinsdag 04 januari 2005 @ 21:14:
[...]

Het lijkt me toch wel voor de hand liggend dat een download meerdere categorieen kan hebben. En dit is zeker geen nieuwe manier van database design. Er zijn zat programmeurs die aanraden altijd een associatie tabel te gebruiken. Het hoeft natuurlijk niet, maar ik zie eerlijk gezegd weinig problemen als j ehet wel zo doet.
Ik ga daar niet zo één twee drie vanuit. Zeker niet als ik de code zie. Want dan krijg je de mogelijkheid om vaker hetzelfde item te wijzigen.
Ik had eigenlijk verwacht dat iedere download verplicht een categorie zou moeten hebben. Verder is een LEFT JOIN echt niet begrijpelijk voor een beginner, ik weet niet waar je dat vandaan haalt? Verder is deze query ook echt niet leesbaarder. Als je de syntax kent weet je precies wat er gebeurt. Als een programmeur deze syntax begrijpt, dan begrijpt hij zeker ook de oplossing die ik net gaf. Die is vrij basis.
Tot zoverre, een * is altijd onleesbaarder als een query met alle columns. Duidelijke uitvoernamen bezorgen duidelijkere code zodat die vaak ook wat efficiënter wordt.
En jah normaal had ik dar gewoon JOIN neergezet(als het om MySQL gaat 'INNER JOIN') en dan is de query toch in mijn ogen echt een stuk duidelijker afgescheiden. Relaties leggen tussen 2 tabellen op hetzelfde niveau(in de zin van dat ze na elkaar staan) levert mensen vaak meer onduidelijkheid op als het afsplitsen.

En als laatste, soms verwijder je nog wel eens categorie... Wat dan :) ?

Deze post is bestemd voor hen die een tegenwoordige tijd kunnen onderscheiden van een toekomstige halfvoorwaardelijke bepaalde subinverte plagiale aanvoegend intentioneel verleden tijd.
- Giphart


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Alex de Groot schreef op dinsdag 04 januari 2005 @ 21:23:
Want dan krijg je de mogelijkheid om vaker hetzelfde item te wijzigen.
Hoe bedoel je?
Tot zoverre, een * is altijd onleesbaarder als een query met alle columns. Duidelijke uitvoernamen bezorgen duidelijkere code zodat die vaak ook wat efficiënter wordt.
Dat is waar ja. Maar als je een gewoon een overzicht hebt van je database opzet dan heb je dat ook niet zo veel nodig. Het is verder natuurlijk wel beter om expliciet de namen van de velden op te geven die je wilt ophalen om zo zo min mogelijk data op te halen, precies wat je nodig hebt liefst.
En als laatste, soms verwijder je nog wel eens categorie... Wat dan :) ?
Dan voer je een extra query uit die ook alle relaties opruimt. Mischien dan een minder goed idee als je vaak velden toevoegd en verwijderd, maar ik denk niet dat het veel scheelt.

[ Voor 3% gewijzigd door Michali op 04-01-2005 21:30 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • MaTriCX
  • Registratie: Augustus 2002
  • Laatst online: 18-07-2024
Even my 2 cents.
Het ontwerp van N:M is inderdaad voor een beginneling net zo lastig als het gebruik van een LEFT JOIN.
Zoals ik ook al aangaf worden met mijn query de downloads met null-waarden in cat_id (geen categorie) niet getoond. De ingewikkeldere query is inderdaad met LEFT JOIN, die zorgt ervoor dat de NULL-waarden wel worden getoond.
Maar om deze discussie voor te zetten met allerlei aannames die geen kracht bijgezet worden, kun je beter even wachten tot de TopicStarter weer replied.

Acties:
  • 0 Henk 'm!

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 18-08 18:12
Ten eerste allen bedankt voor de reacties !

Met de oplossing van Guldan ben ik eruit gekomen, deze kon ik ook het beste begrijpen.
Meerdere categorieen per download maakt het allemaal iets wat te moeilijk nu nog, nu dus maar even op deze manier.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
verytallman schreef op woensdag 05 januari 2005 @ 02:03:
Ten eerste allen bedankt voor de reacties !

Met de oplossing van Guldan ben ik eruit gekomen, deze kon ik ook het beste begrijpen.
Meerdere categorieen per download maakt het allemaal iets wat te moeilijk nu nog, nu dus maar even op deze manier.
Die oplossing zou ik toch echt niet gebruiken. De reden is dat je dan bij iedere download een extra query moet uitvoeren om de categorie op te halen terwijl dit allemaal netjes in 1 query kan. Dat scheelt heeeel wat performance als je veel downloads wilt gaan uitprinten. Dit zou mijn oplossing zijn geweest (met de query van Alex de Groot):
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
<?php

$downloads_query = "
    SELECT
        d.id AS dl_id,
        d.titel AS dl_titel,
        c.naam AS cat_naam
    FROM
        downloads d
    LEFT JOIN
        download_cats c
    ON
        d.cat_id = c.id
";      

$downloads_result = mysql_query($downloads_query) or die(mysql_error());

if ( mysql_num_rows($downloads_result) )
{
    ?>
    <table width="600">
    <?
    
    while ( $download = mysql_fetch_assoc($downloads_result) )
    {
        ?>
        <tr>
            <td width="25%">
                <?=$download['dl_titel']?>
            </td>
            <td width="25%">
                <?=$download['cat_naam']?>
            </td>
            <td width="25%">
                <a href="download_bewerken.php?actie=bewerken&amp;id=<?=$download['dl_id']?>">
                    Bewerken
                </a>
            </td>
            <td width="25%">
                <a href="download_bewerken.php?actie=delete&amp;id=<?=$download['dl_id']?>">
                    Verwijderen
                </a>
            </td>
        </tr>
        <?
    }
    
    ?>
    </tabel>
    <?
}
else
{
    echo 'geen downloads';
}

?>

[ Voor 26% gewijzigd door Michali op 05-01-2005 12:04 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 18-08 18:12
Michali die code werkt bij mij niet. Moet het ook niet zijn:
code:
1
2
3
4
    FROM 
        downloads AS d 
    LEFT JOIN 
        download_cats AS c

Dus met AS erbij ?
Ik ben er zelf mee bezig het wel werkend te krijgen. Maarja het is meer dingetjes veranderen en kijken of het werkt.

[ Voor 5% gewijzigd door verytallman op 06-01-2005 01:21 ]


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
AS hoeft niet. En een beetje debuggen is toch niet zo moeilijk? Is de hele set leeg of gaat er iets anders fout?

Noushka's Magnificent Dream | Unity

Pagina: 1