Vet att jag tidigare pratat om crud och lite annat. Men jag har inte täckt hur man kommer igång att arbeta med sin databas.
Så tanken är följande
- I Del I så skapar vi en tabell och stoppar in en rad som vi sedan hämtar (länk)
- I Del II bygger vi ett formulär som gör att vi kan fylla en klass t.ex. och skicka till databasen och få svar på det. (länk)
- I Del III har vi flera tabeller med många rader, då ska vi lära oss hur man ställer frågor till databasen mot många tabeller samtidigt och vad vi kan göra med det. (länk)
- I Del IV kommer vi uppdatera data i databasen (länk)
- I Del V kommer vi gå mer på djupet med MySQL-frågor.
Nu har vi en tabell, vad ska man med det till? Räcker förvisso till en gästbok. Men vi siktar lite högre än så. Vi börjar med att skapa en tabell som ska innehålla alla elever som går i skolan.
Vi ger varje elev ett unikt id, en referens till deras klass, förnamn, efternamn, födelseår. Kommer vi på något senare så kan vi ju lägga till det.
<?php
include ‘config.php’;
mysql_select_db($db_name,$link);
$sqlCreateTable = "CREATE TABLE elever (
`elev_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`klass_id` INT NOT NULL ,
`elev_fnamn` VARCHAR( 30 ) NOT NULL ,
`elev_enamn` VARCHAR( 30 ) NOT NULL ,
`elev_far` INT( 4 ) NOT NULL ,
`modified` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = MYISAM";
$result = mysql_query($sqlCreateTable,$link);
echo $result;
?>
varchar(30) säger att vi har ett text-fält som max innehåller 30 tecken. Brukar räcka när det gäller namn. Även Svensson Karlsson som efternamn får vi in där.
Nu tänkte jag att vi ska göra ett formulär där vi kan mata in vår data. Vi gör en fil som heter laggtillelever.php som vi lägger i root-mappen.
Den får se ut enligt följande
<?php
include ‘includes/config.php’;
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<a href="index.php">Klassöversikt</a><br/>
<form method="post" action="includes/addElev.php">
<label>Förnamn:<input type="text" name="elev_fnamn" /></label><br>
<label>Efternamn:<input type="text" name="elev_enamn" /></label><br>
<label>Född år (xxxx):<input type="text" name="elev_far" maxlength="4" /></label><br>
<input type="submit" value="Lägg till Klass"/><input type="reset" value="Rensa"/>
</form>
</body>
</html>
Nu har vi 2 saker att fundera på. 1. Vilken klass hör eleven till? 2. Vi måste på något sätt visa vilken klass vi stoppar eleven i. Då kan vi välja på att skapa en drop-lista där man får välja klassnamn, eller så gör vi en länk till denna sidan från index-sidan. Så går man i listan med klasserna och klickar på en länk som säger något i stil med “Lägg till elev”. Denna i sin tur har en länk som går till laggtillelever.php?kid=’klassid’ så kan vi i laggtillelever hämta upp klass-id’t med $_GET[‘kid’]. Hade kunnat göra samma sak fast istället för en länk hade vi haft ett formulär som på “lägg till elev” hade använt laggtillelever.php som action. Så när vi kommer till laggtillelever.php har vi klass_id i $_POST. Vi hade kunnat göra laggtillelever.php som en fil som bara innehöll formuläret och sedan ladda det i en div som vi visar när man klickar på lägg till elev, och då också sätter värde på klass_id med hjälp av javascript. Men denna guide handlar inget om layout osv. utan om att hämta och skicka saker till en databas. Jag kommer välja metoden med länk som ger oss en $_get-variabel. Den är bra för då kan man ladda om laggtillelever när man står där. Med $_post tappar man värdet då. Vi ska nu göra en justering på både displayKlass.php och laggtillelever.php Vi börjar med displayKlass.php.
Vi ersätter:
$table .= "<td>$antalElever</td>";
Med:
$table .= "<td>$antalElever <a href=’laggtillelever.php?kid=$Klass_id’ />Lägg till elev</a></td>";
Om vi nu sparar och öppnar index.php i webbläsaren så har det dykt upp en länk bakom antal elever. Kanske inte snyggaste placeringen. Men där är den. Håller du musen över ser du att den går till t.ex. “http://localhost/Skola/laggtillelever.php?kid=3”. Nu över till vår ganska nyskapade laggtillelever.php. Där ska vi lägga till en rad precis i början på formuläret. Direkt efter första inleddande <form>-taggen till och med. Vi lägger till följande:
<input type="hidden" name="Klass_id" value="<?php echo $_GET['kid']; ?>"/>
Vad vi gör här är att vi skapar en dold egenskap för formuläret. Där vvi matar in vårat värde som ligger i addressen ?kid=3. Så här kommer den i vår exempel-url tilldelas värdet 3.
Nu är det ju väldigt opedagogiskt att inte visa namn på klassen som vi ska lägga till eleven i. Så för säkerhets skull så lägger vi till den. Vilket också ger oss möjligheten att träna på lite mer sql-frågor. Vi vill ju även så så att $_Get finns så att den har något värde. Annars vet vi ju inte var vi gör av eleven i fråga. Iom att vi ska kolla upp namnet så skyddar vi ju oss också lite mot att någon skriver ?kid=korv osv så att man inte bara matar in något med värden som inte kan relatera till någon klass.
Så vi rotar fram klassen. Och visar lite extra data. Så efter lite omarbetning ser laggtillelever.php ut enligt följande:
<?php
include ‘includes/config.php’;
$rows = 0;
if(isset ($_GET['kid']))
{
$kid = $_GET['kid'];
mysql_select_db($db_name, $link);
// vi letar upp vår klass med hjälp av klass-id som är unikt.
$sqlSelectKlass = "select * from klasser where Klass_id=’$kid’ limit 1";
$result = mysql_query($sqlSelectKlass) or die(mysql_error());
$row = mysql_fetch_array($result);
$rows = mysql_num_rows($result);
// vi packar upp vår array så koden blir renare
extract($row);
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<a href="index.php">Klassöversikt</a><br/>
//Vi vill ju inte att något görs om inte vi har en klass.
<?php if($rows ==1){ ?>
<p>Lägg till elev i klass <?php echo $klassNamn; ?> årgång <?php echo $argang; ?></p>
<form method="post" action="includes/addElev.php">
<input type="hidden" name="Klass_id" value="<?php echo $Klass_id; ?>"/>
<label>Förnamn:<input type="text" name="elev_fnamn" /></label><br>
<label>Efternamn:<input type="text" name="elev_enamn" /></label><br>
<label>Född år (xxxx):<input type="text" name="elev_far" maxlength="4" /></label><br>
<input type="submit" value="Lägg till Elev"/><input type="reset" value="Rensa"/>
</form>
<?php }
// Man måste meddela om inte klassen hittas
else { ?>
<h1>Klassen hittades ej</h1>
<p>Gå tillbaka till klassöversikten för att välja klass<br>
<a href="index.php">Klassöversikt (länk)</a> </p>
<?php } ?>
</body>
</html>
Så först skapar vi en variabel som heter rows som vi tilldelar värdet 0. Ett fult sätt att gå runt om $_get[kid] inte finns.
Nu måste vi ta tag i addElev.php. Vi kommer göra ungefär som CreateKlass (som kanske borde heta addKlass istället. Ursäkta mig för förvirrande namn-mönster).
Såhär gör vi addElev.php iaf.
<?php
include ‘config.php’;
//isset är ett bra kommando att kunna. Is Set. Kollar om en parameter finns.
if(isset ($_POST))
{
extract($_POST);
mysql_select_db($db_name, $link);
$sqlInsert = "insert into elever (klass_id,elev_fnamn,elev_enamn,elev_far) values ($Klass_id, ‘$elev_fnamn’,'$elev_enamn’,$elev_far)";
$result = mysql_query($sqlInsert,$link) or die(mysql_error());
if($result == 0)
$message = "<h1>Något gick fel…</h1>";
if($result == 1)
$message = "<h1>Elev tillagd</h1>";
}
//Vi måste ju göra något om inte kid är satt.
if(!isset ($_POST['Klass_id']))
{
$message = "<h1>Du har inte valt klass!</h1>";
}
$message .= "<p><a href=’../index.php’>Gå tillbaka</a></p>";
echo $message;
?>
I verkligheten kanske vi hade haft person-nummer på eleven och kollat så att inte eleven finns innan, och om eleven fanns informerat om detta eller uppdaterat informationen på eleven. (vi ska uppdatera lite information senare).
Nu kan vi skapa elever, men vad ska vi göra med dom?
Minns ni att vi har ett fält som heter antal elever? Det är ju jättedumt, hade det inte varit bättre att räkna antal elever i databasen istället? Vi ska nu uppdatera displayKlass så att vi använder databasen bättre.
Vi ersätter
$sqlSelect = "Select * from klasser”;
med:
$sqlSelect = "Select *,count(elev_id) as antal from klasser join elever on klasser.klass_id=elever.klass_id group by klasser.klass_id";
Den stora nackdelen är att om vi gör det såhär så kommer vi inte få med dom klasserna som inte har några registrerade elever. Men vi kommer få resultatet grupperat per klass med antal elever som antal. count(variabel) as antal gör så att det kommer tillbaka ett fält med värdet den har räknat. count är dock lite meningslöst om man inte gör en group by. För att komma runt detta får vi göra en Left join. En left join tar inte hänsyn till om det finns något att join:a med på andra sidan. Det är inte hela datan som är resultatet utan först och främst huvudtabellen, sedan är det andra en sekundär tabell man kollar på om man hittar något. Så vi gör om den igen så den blir:
$sqlSelect = "Select *,count(elev_id) as antal from klasser left join elever on klasser.klass_id=elever.klass_id group by klasser.klass_id";
Nu kan man göra select * i såhär små tabeller, men sedan för man ange Exakt den data man vill ha ut. t.ex.
$sqlSelect = "Select klassNamn, argang,count(elev_id) as antal from klasser left join elever on klasser.klass_id=elever.klass_id group by klasser.klass_id";
Om ni kör bägge rader i ett sql-gränssnitt ser man en klar skillnad (exempelvis phpmyadmin).
Jag visar för säkerhets skull. Jag har 3 klasser, 1 elev.
Fråga utan left join:
Fråga med left join:
Fråga med left join och bara valda fält:
Som ni förstår blir det ganska markant skillnad i mängden data som skickas. Speciellt när man är inne och länkar ihop massa tabeller. För det är väldigt sällan som man faktiskt vill komma åt all data. I mitt exempel med 3 rader och några kolumner så är det väl försumbart. Men om man skulle ha en hel skola t.ex. med årskurs 1-9, 2 parralellklasser med 30 elever i varje så är vi ju på 18 klasser och 540 elever. Fortfarande ingen data att prata om. Men lite mer data när man gör frågan.
Nästa steg är att ändra raden i displayKlass.php som skickar ut $antalElever till att skicka ut $antal.
Från:
$table .= "<td>$antalElever <a href=’laggtillelever.php?kid=$Klass_id’ />Lägg till elev</a></td>";
Till:
$table .= "<td>$antal <a href=’laggtillelever.php?kid=$Klass_id’ />Lägg till elev</a></td>";
Om vi kör index.php så får vi nu
Och antal elever ändras hela tiden efter att man lägger till och tar bort elever. Nu ska vi gå vidare och göra så att vi kan visa våra elever, därefter ska vi göra en elevuppdatering i form av klass-byte.
Vi börjar med att skapa en fil som heter visaKlass.php som ligger direkt i roten.
Vi anropar den med ett klass_id precis som laggtillelever.php
visaKlass.php kan se ut enligt följande:
<?php
include ‘includes/config.php’;
if(isset($_GET))
{
$kid = $_GET['kid'];
mysql_select_db($db_name, $link);
$sqlGetKlass = "select klassNamn from klasser where klass_id=$kid limit 1";
$resultKlass = mysql_query($sqlGetKlass,$link) or die(mysql_error());
$rowKlass = mysql_fetch_array($resultKlass);
$numKlass = mysql_num_rows($resultKlass);
if($numKlass >0)
{
extract($rowKlass);
// vi har ju satt limit ett, så vi kommer inte loopa på denna datan.
$sqlGetElever = "select *,concat(elev_fnamn,’ ‘,elev_enamn)as namn from elever where klass_id=$kid";
$resultElever = mysql_query($sqlGetElever, $link) or die(mysql_error());
$rowElever = mysql_fetch_array($resultElever);
$numElever = mysql_num_rows($resultElever);
$data = "<h1>Elever i klass: $klassNamn ($numElever elever)</h1>";
if($numElever >0 )
{
$data .= "<table>";
$data .= "<tr style=background-color:black;color:white;><th>Namn</th></tr>";
do{
extract($rowElever);
$data .= "<tr>";
//nu matar vi ut namn som är ett "konstgjort" fält som består av förnamn och efternamn med ett mellanrum emellan. Gjort med concat
$data .= "<td>$namn</td>";
$data .= "</tr>";
}while($rowElever = mysql_fetch_assoc($resultElever));
$data .= "</table>";
$data .= "<p><a href=’laggtillelever.php?kid=$kid’ />Lägg till elev</a></p>";
}
else
{
$data .= "<h1>Inga elever i klassen</h1>";
}
}
else
{
$data = "<h1>Hittade ej klassen</h1>";
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<p><a href="index.php">Klassöversikt</a></p>
<?php echo $data; ?>
</body>
</html>
Ungefär som displayKlass, men lite mer, vi kollar flera tabeller, skapat sammansatta tabell-fält (namn) osv. Nu ska vi föresten justera displayKlass en liten aning.
Vi ändrar:
$table .= "<td>$antal <a href=’laggtillelever.php?kid=$Klass_id’ />Lägg till elev</a></td>";
Till:
$table .= "<td>$antal <a href=’laggtillelever.php?kid=$Klass_id’ />Lägg till elev</a>";
if($antal>0) {
$table .= “ – <a href=’visaKlass.php?kid=$Klass_id’>Visa elever</a>";
}
$table .= "</td>";
Detta gör så att om det finns några elever i klassen registrerade så kan man klicka på Visa elever och kommer till en lista. Enligt följande.
Som leder till:
Så nu kan vi lägga till klasser och elever, kolla på eleverna osv. Så nu har vi repeterat att välja lite ur databasen. Gjort specifika frågor, lite mer avancerade frågor där länkar ihop tabeller och summerar antal osv. Så Del III är härmed avslutad!
Här är filerna i en zip-fil