Ik ben vollop bezig met het schrijven van een filmmanager in php.
Nu ik stoot op een probleempje. In mijn toevoeg pagina, wil ik de gebruiker het gerne laten kiezen middels een dropdown box. Het probleem is echter dat een film aan meerdere gernes kan voldoen.
Bv: actie, thriller horror.
Nu ik haal al de mogelijke gernes uit de database.
Dat doe ik op deze manier:
Maar, zo kan ik echter maar 1 waarde selecteren. Iemand een idee hoe ik dit best zou aanpakken. Het resultaat, de meerdere gernes zouden echter als 1 string in mijn db moeten komen.
dat is geen goed datamodel. Een film kan in meerdere genres vallen, en een genre kan bij meerdere films horen. In database-taal heet dat een veel-op-veel relatie en die zijn verboden.
De oplossing is om een koppeltabel te maken waarin je het volgende doet:
stel de film met id=1 valt in de genres met id 1, 2 en 3
dan heb je dus een tabel 'films', een tabel 'genres' en een tabel 'koppel_films_genres
In die tabel heb je de velden film_id en genre_id. Nu kun je drie records aanmaken:
film_id | genre_id
--------------------
1 | 1
1 | 2
1 | 3
Als je een rijtje met genres in een select stopt, kun je meerdere selecties toestaan door hem "multiple" te maken.
<select name="genres" multiple>
Na verzenden van het formulier staan de geselecteerde waardes dan in $_POST['genres'] als een array. Je kunt ze dan uitlezen met foreach.
Nu, in plaats van het echo'en van het resultaat. Zou ik alle gernes in een string in de db willen plaatsen. Dit is geen probleem om dat te doen, maar ik zou graag als output in mijn filmoverzicht het volgende krijgen:
actie-drama-horror
Is het mogemlijk mij soms nog even te helpen om dat op die manier in een variable te krijgen?
Dat wil ik best doen, maar wat vind je van het verhaal over die koppeltabel uit mijn eerste antwoord? Een goed opgezette database (dus met een goed datamodel) is te verkiezen boven de manier waarop jij het nu aan wilt pakken.
Als een database goed is opgezet is er weinig of geen redundantie. Redundantie betekent grofweg dat gegevens niet dubbel voorkomen. In jouw opzet krijg je records die er zo uitzien:
in de tabel film heb je het veld film_genre niet meer nodig, want de genres per film kun je straks uit de koppeltabel halen. Ik ga een voorbeeldje voor je maken, moment.
Ik heb een voorbeeld gemaakt, locaal getest op WAMP5. Bestudeer de code, en als er vragen zijn, hoor ik het wel.
<?php
require 'db_config.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// checken of er wel iets is ingevuld laat ik aan jouzelf over :-)
// dat kun je doen met de functie empty ()
// minimale beveiliging
$titel = htmlspecialchars ($_POST['titel']);
$type = htmlspecialchars ($_POST['type']);
if (!get_magic_quotes_gpc ()) {
$titel = addslashes ($titel);
$type = addslashes ($type);
}
// nieuwe record maken in de tabel films
$sql = "
INSERT INTO films
SET titel = '" . $titel . "',
type = '" . $type . "'";
mysql_query ($sql) or trigger_error (mysql_error ());
// nieuwe records maken in de tabel films_genres
$film_id = mysql_insert_id ();
// hier hoort eigenlijk nog een check bij of er wel iets geselecteerd is, dus of de array wel bestaat
foreach ($_POST['genres'] as $value) {
$sql = "
INSERT INTO films_genres
SET film_id = " . $film_id . ",
genre_id = " . $value;
mysql_query ($sql) or trigger_error (mysql_error ());
}
}
function get_genres () {
$sql = "
SELECT id, naam
FROM genres
ORDER BY naam
";
if (!$res = mysql_query ($sql)) {
trigger_error (mysql_errno () . ': ' . mysql_error ());
echo '<pre>';
echo $sql;
echo '</pre>';
}
else {
while ($row = mysql_fetch_assoc ($res)) {
echo '<option value="' . $row['id'] . '">' . $row['naam'] . '</option>';
}
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Films</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<h1>Voeg een film toe</h1>
<p>
<label for="titel">titel:</label>
<input name="titel" type="text">
</p>
<p>
<label for="type">type:</label>
<input name="type" type="text">
</p>
<p>
<label for="genres">genres:</label>
<select name="genres[]" multiple>
<?php
get_genres ();
?>
</select>
</p>
<p>
<input name="toevoegen" type="submit" value="toevoegen">
</p>
</form>
</body>
</html>