Åtgärder

Skillnad mellan versioner av "CS enkelt prov"

Från Skolbok

m (Tabellstruktur)
m (Kodanalys)
 
(30 mellanliggande versioner av samma användare visas inte)
Rad 3: Rad 3:
 
Som jag tog upp i  början så utgår jag ifrån KISS; så enkelt som det bara går men ändå inte så förenklat att det blir oanvändbart. Utifrån det perspektivet skall vi skapa ett riktigt enkelt prov. Det finns vissa utgångspunkter:
 
Som jag tog upp i  början så utgår jag ifrån KISS; så enkelt som det bara går men ändå inte så förenklat att det blir oanvändbart. Utifrån det perspektivet skall vi skapa ett riktigt enkelt prov. Det finns vissa utgångspunkter:
  
1: Provet består av t.ex. tio frågor vars svar blandas ihop i en enda text. Jag har försökt att bygga upp system med olika antal frågor per prov där varje fråga är en post i en datatabell, men då måste varje prov bestå av tre olika databastabeller: en tabell med provnamn som fungerar som behållare, en tabell med frågor och svar och en tabell som binder samman frågorna med provnamnet. Om man däremot utgår ifrån en enda text som svar räcker det med en enda tabell, det är mer begränsat, men mycket enklare att hantera.
+
1: Provet består av valfritt antal frågor vars svar blandas ihop i en enda text. Jag har försökt att bygga upp system med olika antal frågor per prov där varje fråga är en post i en datatabell, men då måste varje prov bestå av tre olika databastabeller: en tabell med provnamn som fungerar som behållare, en tabell med frågor och svar och en tabell som binder samman frågorna med provnamnet. Om man däremot utgår ifrån en enda text som svar räcker det med en enda tabell, det är mer begränsat, men mycket enklare att hantera.
  
 
2: Eleven skriver text till alla frågor. Detta är inte hugget i sten, det går att utforma så att eleven istället väljer färdiga svar från olika listor, men det går jag igenom längre fram. I det här första exemplet är samtliga frågor utformade på exakt samma sätt.
 
2: Eleven skriver text till alla frågor. Detta är inte hugget i sten, det går att utforma så att eleven istället väljer färdiga svar från olika listor, men det går jag igenom längre fram. I det här första exemplet är samtliga frågor utformade på exakt samma sätt.
  
3: Eleven behöver inte logga in. Största problemet med Internetbaserade lösningar är att elever måste logga in först, och läraren sliter sitt hår när tre, fem, åtta osv. elever dyker upp och meddelar att de glömt/tappat sina inloggningsnamn eller lösenord. Det skall vara lika enkelt att göra prov vid datorn som när man sätter sig vid en bänk och fyller i namn och klass med blyertspenna, och då fungerar det helt enkelt inte med personlig inloggning. Istället använders en lösenordsruta med ett "hemligt ord". Endera väljer eleven ordet själv eller så väljer du ett ord åt eleven, det senare är att föredra. Genom att använda ett hemligt ord kan inte andra elever skriva i svar åt varandra. En elev kan t.ex. fylla i ''spindelmannen'' som sitt personliga hemliga ord och då vet ju du som lärare att förnamn + efternamn + spindelmannen är just den eleven. Problemet är att du måste fråga varje elev personligen om vilket hemligt ord de har om du dessutom får in ett prov med samma förnamn + samma efternamn + "ångvält". Därför kan du trycka upp hemliga ord i förväg och dela ut en papperslapp med individuellla hemliga ord till varje elev innan provet. Då vet du att "ångvält" inte är den elevens prov utan någon kamrat som endera vill vara elak och skriva ett dåligt prov, eller vill vara snäll och skriva ett "förbättrat" prov.
+
3: Eleven behöver inte logga in. Största problemet med Internetbaserade lösningar är att elever måste logga in först, och läraren sliter sitt hår när tre, fem, åtta osv. elever dyker upp och meddelar att de glömt/tappat sina inloggningsnamn eller lösenord. Det skall vara lika enkelt att göra prov vid datorn som när man sätter sig vid en bänk och fyller i namn och klass med blyertspenna, och då fungerar det helt enkelt inte med personlig inloggning. Istället används en lösenordsruta med ett "hemligt ord". Endera väljer eleven ordet själv eller så väljer du ett ord åt eleven, det senare är att föredra. Genom att använda ett hemligt ord kan inte andra elever skriva i svar åt varandra. En elev kan t.ex. fylla i ''spindelmannen'' som sitt personliga hemliga ord och då vet ju du som lärare att förnamn + efternamn + spindelmannen är just den eleven. Problemet är att du måste fråga varje elev personligen om vilket hemligt ord de har om du dessutom får in ett prov med samma förnamn + samma efternamn + "ångvält". Därför kan du trycka upp hemliga ord i förväg och dela ut en papperslapp med individuella hemliga ord till varje elev innan provet. Då vet du att "ångvält" inte är den elevens prov utan någon kamrat som endera vill vara elak och skriva ett dåligt prov, eller vill vara snäll och skriva ett "förbättrat" prov.
  
 
4: Provet går inte att redigera av eleverna efter det att det sparats. Då fungerar det som en Wiki och det går alltid att se äldre versioner. Det enda eleven kan göra är att spara en ny version av samma prov. På det viset kan du spåra fuskare på ett rätt enkelt sätt.
 
4: Provet går inte att redigera av eleverna efter det att det sparats. Då fungerar det som en Wiki och det går alltid att se äldre versioner. Det enda eleven kan göra är att spara en ny version av samma prov. På det viset kan du spåra fuskare på ett rätt enkelt sätt.
Rad 17: Rad 17:
 
7: Varje inlämnat prov har ett tillhörande textfält där du kan skriva en bedömning och själv fylla i vilka betygsmål du tycker att eleven uppnått i hela provet. När det är dags att lämna tillbaka det färdigrättade provet kan du endera skriva ut elevprov+facit+din bedömning till eleven och ge den resultatet i pappersform, eller skapa en pdf-fil med uppgifterna som du skickar med e-mail till eleven så sparar skolan pengar både på att proven inte behöver skrivas ut och på att resultatet kan läsas online.
 
7: Varje inlämnat prov har ett tillhörande textfält där du kan skriva en bedömning och själv fylla i vilka betygsmål du tycker att eleven uppnått i hela provet. När det är dags att lämna tillbaka det färdigrättade provet kan du endera skriva ut elevprov+facit+din bedömning till eleven och ge den resultatet i pappersform, eller skapa en pdf-fil med uppgifterna som du skickar med e-mail till eleven så sparar skolan pengar både på att proven inte behöver skrivas ut och på att resultatet kan läsas online.
  
8: varje prov skall ha en ruta för att lägga in ett elev-id så att du, om du vill, kan lägga in en koppling mellan provdatabasen och elevdatabasen.
+
8: varje prov skall ha en ruta för att lägga in ett elev-id så att du, om du vill, kan lägga in en koppling mellan provdatabasen och elevdatabasen Likaså skall det finnas ett lärar-id så att det är möjligt att flera lärare kan dela samma provtabell, men så att man samtidigt förhindrar att lärare ändrar andras prov av misstag.
  
 
==Tabellstruktur==
 
==Tabellstruktur==
Rad 26: Rad 26:
 
  ID    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 
  ID    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 
  ELEV_ID INT,
 
  ELEV_ID INT,
 +
LARAR_ID INT,
 
  F_NAMN VARCHAR (50),
 
  F_NAMN VARCHAR (50),
 
  E_NAMN VARCHAR (50),
 
  E_NAMN VARCHAR (50),
Rad 33: Rad 34:
 
  FACIT TEXT,
 
  FACIT TEXT,
 
  ELEVSVAR TEXT,
 
  ELEVSVAR TEXT,
 +
PROVKOMMENTAR TEXT,
 
  RESULTAT VARCHAR (50),
 
  RESULTAT VARCHAR (50),
 
  DATUM_GJORT VARCHAR (50),
 
  DATUM_GJORT VARCHAR (50),
Rad 38: Rad 40:
 
  );
 
  );
  
TEXT är en ny sorts fält du inte sett tidigare, men det är helt enkelt ett fält i databasen som rymmer en större mängd text.  
+
TEXT är en ny sorts fält du inte sett tidigare, men det är helt enkelt ett fält i databasen som rymmer en obegränsad (nästan) mängd text till skillnad från VARCHAR som endast rymmer 255 tecken.  
  
RESULTAT tänkte jag kan användas för att fylla i ett betyg eller liknande omdöme. Skolverket får frispel när man skriver ut ett betygsvärde på ett prov, medan eleverna alltid vill veta vilket betyg de fick provet. Det är upp till varje lärare att avgöra. Själv brukar jag istället numrera betygsmålen och sedan fylla i siffror för målen: C2, E1 och E3 kan t.ex. ha blivit uppfyllda och då skriver jag i det istället.
+
ELEV_ID och LARAR_ID är som standard 0, något vi fixar när vi lägger in poster, eftersom alla ID nummer börjar 1. Då vet vi att om det är en 0:a saknas koppling till en speciell elev eller lärare medan det går att samköra provet med elevregistret eller lärarregistret om värdet är över 0.
  
FACIT används så att provfråga + provsvar sparas efter varandra så att det är lätt att se hur de hänger ihop. En fråga kan ha svar på flera betygsnivåer och då bör det finnas facit till E, C och A nivå. Allra minst skall facit finnas för E nivån.
+
FACIT används så att provfråga + provsvar sparas efter varandra så att det är lätt att se hur de hänger ihop. En fråga kan ha svar på flera betygsnivåer och då bör det finnas facit till E, C och A nivå. Allra minst skall facit finnas för E nivån.  
  
ELEV_ID är som standard 0, något vi fixar när vi lägger in poster, eftersom alla ID nummer börjar 1. Då vet vi att om det är en 0:a saknas koppling till en speciell elev medan det går att samköra provet med elevregistret om värdet är över 0.  
+
PROVKOMMENTAR är ett textfält som används istället för den traditionella kommentaren i marginalen där man kan sammanställa hur många poäng eleven fick, vad den gjorde för fel, vad den hade kunnat förbättrat osv.
 +
 
 +
RESULTAT tänkte jag kan användas för att fylla i ett betyg eller liknande omdöme. Skolverket får frispel när man skriver ut ett betygsvärde på ett prov, medan eleverna alltid vill veta vilket betyg de fick provet. Det är upp till varje lärare att avgöra om det är bra att göra så. Själv brukar jag istället numrera betygsmålen och sedan fylla i siffror för målen: C2, E1 och E3 kan t.ex. ha blivit uppfyllda och då skriver jag i det istället.
  
 
DATUM_RATTAT är litet överkurs, men det kan vara bra att se vilket datum det var du senast rättade eller redigerade någonting i en enskild elevs prov. Det är för din egen skull och inget som någon elev kan tänkas se.
 
DATUM_RATTAT är litet överkurs, men det kan vara bra att se vilket datum det var du senast rättade eller redigerade någonting i en enskild elevs prov. Det är för din egen skull och inget som någon elev kan tänkas se.
  
Logga in i MySQL och skapa tabellen.
+
Logga in i MySQL och skapa tabellen innan du fortsätter med att skapa sidan som tillhör tabellen (se nedan).
 +
 
 +
Logga in i MySQL med:
 +
mysql -u root -p
 +
Fyll i lösenord och skriv:
 +
use skolan
 +
Därefter klistrar du bara in koden här ovanför så att datatabellen skapas.
  
 
==Provexempel==
 
==Provexempel==
Rad 54: Rad 64:
  
 
  <?php
 
  <?php
 +
  session_start();
 
  //Filnamn  ww2start.php
 
  //Filnamn  ww2start.php
 +
 +
// Funktion för att förhindra databashackning
 +
function rensatext($textattrensa)
 +
{
 +
$textattrensa = stripslashes($textattrensa); //Tar bort snedstreck
 +
$textattrensa = mysql_real_escape_string($textattrensa); //Fixar enkla- och dubbla citattecken
 +
return $textattrensa; //skickar tillbaka justerad text
 +
}
 
   
 
   
 
  //Olika viktiga variabler
 
  //Olika viktiga variabler
Rad 61: Rad 80:
 
  $password="password1"; // Lösenord till root, kan t.ex. vara password1
 
  $password="password1"; // Lösenord till root, kan t.ex. vara password1
 
  $db_name="skolan"; // Databasens namn
 
  $db_name="skolan"; // Databasens namn
$tbl_name="teacher"; // Tabellens namn
 
 
   
 
   
 
  // Anslut till MySQL servern och välj rätt tabell
 
  // Anslut till MySQL servern och välj rätt tabell
Rad 68: Rad 86:
 
   
 
   
 
  // Alla olika variabler som skall läggas in i databasen när eleven sparar resultatet
 
  // Alla olika variabler som skall läggas in i databasen när eleven sparar resultatet
 +
 +
 
  $elev_id=0;
 
  $elev_id=0;
 +
$larar_id=0; //Här kan du fylla i ditt eget id direkt, om du vet om det
 +
$provnamn='ProvWW2';
 +
//$facit= längre ner, efter alla frågor och svar
 +
$provkommentar = 'Orättat'; //Här skriver du till eleven, poäng på prov osv, men inte nu
 +
$resultat = 'Orättat'; //Här skrivs resultatet, men inte nu.
 +
$datumgjort = date('Y-m-d H:i:s');
 +
$datumraettat = 'Orättat'; //Detta ändras när du rättat provet
 +
 +
//Har man tryckt på knappen?
 +
if($_POST['formSubmit'] == "Spara")
 +
{
 
  $elev_fnamn=$_POST['elev_fnamn'];
 
  $elev_fnamn=$_POST['elev_fnamn'];
 
  $elev_enamn=$_POST['elev_enamn'];
 
  $elev_enamn=$_POST['elev_enamn'];
Rad 74: Rad 105:
 
  $elev_klass=$_POST['elev_klass'];
 
  $elev_klass=$_POST['elev_klass'];
 
  //Skulle kunna skrivas som $elev_klass = '8A' om alla är i samma klass
 
  //Skulle kunna skrivas som $elev_klass = '8A' om alla är i samma klass
  $provnamn='ProvWW2';
+
  //Men då skulle det ligga utanför knapphändelsen
  //$facit= längre ner, efter alla frågor och svar
+
   
 
  //Elevens olika svar
 
  //Elevens olika svar
 
  $S1=$_POST['elev_svar1'];
 
  $S1=$_POST['elev_svar1'];
Rad 82: Rad 113:
 
  $S4=$_POST['elev_svar4'];
 
  $S4=$_POST['elev_svar4'];
 
  $S5=$_POST['elev_svar5'];
 
  $S5=$_POST['elev_svar5'];
 +
$inskickat = 'true';
 +
}
 +
else
 +
{
 +
$elev_fnamn='förnamn';
 +
$elev_enamn='efternamn';
 +
$elev_hemligt=''; //OBS! wiki:n tar bort koden för två enkla citattecken
 +
$elev_klass='klass';
 
   
 
   
  $elevsvar=$S1 + $S2 + $S3 + $S4 + $S5;
+
//Elevens olika svar
  $resultat = 'Orättat';
+
  $S1='Svar:';
  $datumgjort = date('Y-m-d H:i:s');
+
$S2='Svar:';
  $datumrättat = 'Orättat';
+
  $S3='Svar:';
  $inskickat = $_POST['inskickat'];
+
  $S4='Svar:';
 +
  $S5='Svar:';
 +
  $inskickat = 'false';
 +
}
 
   
 
   
 +
$elevsvar="Svar1<br>".$S1."<br>Svar2<br>".$S2."<br>Svar3<br>".$S3."<br>Svar4<br>".$S4."<br>Svar5<br>".$S5."<br>";
 
   
 
   
  $Q1=”Vad var orsaken till Tysklands och Polens ovänskap?;
+
  $Q1="1: Vad var orsaken till Tysklands och Polens ovänskap?<br>";
  $FACIT1=”E=Man hade ofta bråkat om gränserna.  
+
  $FACIT1="E=Man hade ofta bråkat om gränserna.<br>
  C=Västra Polen hade tillhört Tyskland men gick över till Polen efter 1:a världskriget och gränslandets tyskar behandlades illa av polackerna.  
+
  C=Västra Polen hade tillhört Tyskland men gick över till Polen efter 1:a världskriget och gränslandets tyskar behandlades illa av polackerna.<br>
 
  A=Under historiens gång hade Polen ibland inte existerat som land utan varit en del av andra länder. Polackerna såg på Tyskarna som erövrare. Vissa polacker tog chansen att
 
  A=Under historiens gång hade Polen ibland inte existerat som land utan varit en del av andra länder. Polackerna såg på Tyskarna som erövrare. Vissa polacker tog chansen att
  hämnas på de tyskar som bodde i västra Polen, vilket var dumt eftersom Hitler tog upp det som en orsak till ett krig.;
+
  hämnas på de tyskar som bodde i västra Polen, vilket var dumt eftersom Hitler tog upp det som en orsak till ett krig.<br>";
  $Q2=”Varför var Danzigkorridoren så viktig?;
+
  $Q2="2: Varför var Danzigkorridoren så viktig?<br>";
  $FACIT2=”E=Det var den enda kuststräcka som Polen hade tillgång till.  
+
  $FACIT2="E=Det var den enda kuststräcka som Polen hade tillgång till.<br>
  C=För tyskarna var korridoren ett problem eftersom den skar av det viktiga Östpreussen från det övriga Tyskland. Tyskarna visste att om de kunde skära av korridoren skulle de vinna två
+
  C=För tyskarna var korridoren ett problem eftersom den skar av det viktiga Östpreussen från det övriga Tyskland. Tyskarna visste att om de kunde skära av korridoren skulle de vinna två saker, fri  
saker, fri tillgång till Östpreussens land och att polackerna tvingades driva all handel genom Danzig, en hamn som inte var polsk.  
+
tillgång till Östpreussens land och att polackerna tvingades driva all handel genom Danzig, en hamn som inte var polsk.<br> 
  A=Danzig var synnerligen tyskvänligt, även om det var en fristad. Skulle polens handel tvingas genom Danzig skulle Tyskland kunna ta ut höga avgifter och bli väldigt rika samtidigt som
+
  A=Danzig var synnerligen tyskvänligt, även om det var en fristad. Skulle polens handel tvingas genom Danzig skulle Tyskland kunna ta ut höga avgifter och bli väldigt rika samtidigt som hamnen i
  hamnen i Östpreussen skulle kunna användas för handel till och från Tyskland landvägen, något som var omöjligt så länge Danzigkorridoren var i polsk kontroll.;
+
  Östpreussen skulle kunna användas för handel till och från Tyskland landvägen, något som var omöjligt så länge Danzigkorridoren var i polsk kontroll.<br> ";
  $Q3=”Varför var Molotov-Ribbentrop pakten så viktig?;
+
  $Q3="3: Varför var Molotov-Ribbentrop pakten så viktig?<br> ";
  $FACIT3=E=För att genom den kunde inte Tyskland och Sovjetunionen starta ett krig mot varandra.  
+
  $FACIT3="E=För att genom den kunde inte Tyskland och Sovjetunionen starta ett krig mot varandra.<br> 
  C=Eftersom de två stormakterna Tyskland och Sovjetunionen, som egentligen var politiska fiender, inte längre behövde skydda sig mot varandra kunde militären som skyddade den gemensamma
+
  C=Eftersom de två stormakterna Tyskland och Sovjetunionen, som egentligen var politiska fiender, inte längre behövde skydda sig mot varandra kunde militären som skyddade den gemensamma gränsen
  gränsen spridas ut mot andra fronter.  
+
  spridas ut mot andra fronter.<br> 
 
  A=Pakten innebar dessutom att Europa i praktiken delades upp mellan stormakterna där Sovjet lovades den östra halvan vilket var ungefär samma område som Sovjet tappade efter 1:a
 
  A=Pakten innebar dessutom att Europa i praktiken delades upp mellan stormakterna där Sovjet lovades den östra halvan vilket var ungefär samma område som Sovjet tappade efter 1:a
 
  världskriget. Pakten gav dessutom Tyskland tillgång till sovjetiska råvaror man själva led brist på, som t.ex. olja och bensin. Något som var väldigt viktigt inför attacken mot
 
  världskriget. Pakten gav dessutom Tyskland tillgång till sovjetiska råvaror man själva led brist på, som t.ex. olja och bensin. Något som var väldigt viktigt inför attacken mot
  Västeuropa.;
+
  Västeuropa.<br> ";
  $Q4=”Hur gick det till när kriget bröt ut?;
+
  $Q4="4: Hur gick det till när kriget bröt ut?<br> ";
  $FACIT4=”E=Tyska trupper gick in i Polen 1/9 1939 trots att England varnat om att det skulle starta ett krig. Tyskland brydde sig inte och krigsförklaringen England-Polen var ett
+
  $FACIT4="E=Tyska trupper gick in i Polen 1/9 1939 trots att England varnat om att det skulle starta ett krig. Tyskland brydde sig inte och krigsförklaringen England-Polen var ett
  faktum.  
+
  faktum.<br>
 
  C= Tyskland hade provocerat fram ett krigsutbrott genom att låta förklädda tyskar anfalla andra tyskar så att det skulle se ut som att stackars Tyskland blivit oskyldigt anfallet av
 
  C= Tyskland hade provocerat fram ett krigsutbrott genom att låta förklädda tyskar anfalla andra tyskar så att det skulle se ut som att stackars Tyskland blivit oskyldigt anfallet av
  det elaka Polen. Därför var man tvungna att försvara sig. Allt var naturligtvis bara propaganda.  
+
  det elaka Polen. Därför var man tvungna att försvara sig. Allt var naturligtvis bara propaganda.<br>
 
  A=Man började med att beskjuta Westerplatte, Polens enda kustfort, för att snabbt kunna ta över östersjökusten. Med hamnarna säkrade var det enkelt att anfalla från flera olika håll.
 
  A=Man började med att beskjuta Westerplatte, Polens enda kustfort, för att snabbt kunna ta över östersjökusten. Med hamnarna säkrade var det enkelt att anfalla från flera olika håll.
 
  Tyskland gjorde vad man kunde för att anfalla så fort, och så hårt, som möjligt, precis som man hade gjort mot Ryssland i början av 1:a världskriget. Ett verktyg för detta var
 
  Tyskland gjorde vad man kunde för att anfalla så fort, och så hårt, som möjligt, precis som man hade gjort mot Ryssland i början av 1:a världskriget. Ett verktyg för detta var
 
  blitzkrieg, att man sköt sönder broar ock liknande bakom fronten och skapade luckor i Polens försvar med hjälp av pansarvagnar som sedan lugnt kunde fortsätta in i Polens kärnland utan
 
  blitzkrieg, att man sköt sönder broar ock liknande bakom fronten och skapade luckor i Polens försvar med hjälp av pansarvagnar som sedan lugnt kunde fortsätta in i Polens kärnland utan
  att riskera att bli anfallna ;
+
  att riskera att bli anfallna.<br> ";
  $Q5=”Många flyktingar drabbades hårt, varför? Och var kom alla flyktingar ifrån?;
+
  $Q5="5: Många flyktingar drabbades hårt, varför? Och var kom alla flyktingar ifrån?<br> ";
  $FACIT5=”E=När tyska flygplan bombade städerna och tyska trupper snabbt trängde in i Polen flydde vanliga civila bort från tyskarna.  
+
  $FACIT5="E=När tyska flygplan bombade städerna och tyska trupper snabbt trängde in i Polen flydde vanliga civila bort från tyskarna.<br> 
 
  C= Flyktingarna hade ingenstans att ta vägen eftersom tyskarna anföll från flera håll och dessutom anföll Sovjet från öst. Varken tyskarna eller sovjeterna var speciellt snälla mot
 
  C= Flyktingarna hade ingenstans att ta vägen eftersom tyskarna anföll från flera håll och dessutom anföll Sovjet från öst. Varken tyskarna eller sovjeterna var speciellt snälla mot
  flyktingarna heller utan mängder dödades eller skadades när de var ivägen för de framvällande tyska- och ryska trupperna.  
+
  flyktingarna heller utan mängder dödades eller skadades när de var ivägen för de framvällande tyska- och sovjetiska trupperna.<br> 
  A=Bland de som flydde fanns även tyskättlingar bosatta i Polen som försökte fly till de tyska trupperna eftersom polacker tog chansen att anfalla dem, som t.ex. i byn Bromberg.  
+
  A=Bland de som flydde fanns även tyskättlingar bosatta i Polen som försökte fly till de tyska trupperna eftersom polacker tog chansen att anfalla dem, som t.ex. i byn Bromberg.<br> ";
 +
 +
$facit= $Q1."<br>".$FACIT1."<br>".$Q2."<br>".$FACIT2."<br>".$Q3."<br>".$FACIT3."<br>".$Q4."<br>".$FACIT4."<br>".$Q5."<br>".$FACIT5;
 +
 +
//Rensa bort alla ovälkomna tecken i ingående text
 +
$elev_fnamn= rensatext($elev_fnamn);
 +
$elev_enamn= rensatext($elev_enamn);
 +
$elev_hemligt= rensatext($elev_hemligt);
 +
$elev_klass= rensatext($elev_klass);
 +
$facit=rensatext($facit);
 +
$elevsvar=rensatext($elevsvar);
 +
 +
//Spara provet
 +
if ($inskickat=='true')
 +
{
 +
$sql="INSERT INTO simpeltprov
 +
(ID,ELEV_ID,LARAR_ID,F_NAMN,E_NAMN,HEMLIGTORD,KLASS,PROVNAMN,FACIT,ELEVSVAR,PROVKOMMENTAR,RESULTAT,DATUM_GJORT,DATUM_RATTAT)
 +
VALUES
 +
(null,$elev_id,$larar_id,'".$elev_fnamn."','".$elev_enamn."','".$elev_hemligt."','".$elev_klass."','".$provnamn."','".
 +
$facit."','".$elevsvar."','".$provkommentar."','".$resultat."','".$datumgjort."','".$datumraettat."')";
 +
 +
$result=mysql_query($sql);
 +
if($result){
 +
echo "Provet är Sparat i databasen"; //Det gick bra
 +
}else{
 +
  echo "<b>FEL!</b> ditt prov sparades inte."; //Det uppstod något fel
 +
  }
 +
}
 
   
 
   
$facit= $Q1+$Facit1+$Q2+$Facit2+$Q3+$Facit3+$Q4+$Facit4+$Q5+$Facit5;
 
 
  ?&gt;
 
  ?&gt;
 
   
 
   
Rad 132: Rad 201:
 
  &lt;title&gt;Prov om 2:a världskrigets utbrott &lt;/title&gt;
 
  &lt;title&gt;Prov om 2:a världskrigets utbrott &lt;/title&gt;
 
  &lt;/head&gt;
 
  &lt;/head&gt;
 +
 
 
  &lt;body&gt;
 
  &lt;body&gt;
  &lt;form name="form1" method="post" action="ww2start.php"&gt;”;
+
  &lt;form name="form1" method="post" action="ww2start.php"&gt;
  &lt;h2&gt;Prov om andra världskrigets utbrott&lt;/h2&gt;&lt;br&gt;&lt;br&gt;
+
 +
  &lt;h2&gt;Prov om andra världskrigets utbrott&lt;/h2&gt;&lt;br&gt;
 
  &lt;b&gt;Förnamn&lt;/b&gt;&lt;br&gt;
 
  &lt;b&gt;Förnamn&lt;/b&gt;&lt;br&gt;
  &lt;input name="elev_fnamn" type="text" id="elev_fnamn"&gt;&lt;br&gt;
+
  &lt;input name="elev_fnamn" type="text" value= &lt;?=$elev_fnamn;?&gt;&gt;&lt;br&gt;
 
  &lt;b&gt;Efternamn&lt;/b&gt;&lt;br&gt;
 
  &lt;b&gt;Efternamn&lt;/b&gt;&lt;br&gt;
  &lt;input name="elev_enamn" type="text" id="elev_enamn"&gt;&lt;br&gt;
+
  &lt;input name="elev_enamn" type="text" value= &lt;?=$elev_enamn;?&gt;&gt;&lt;br&gt;
 
  &lt;b&gt;Klass&lt;/b&gt;&lt;br&gt;
 
  &lt;b&gt;Klass&lt;/b&gt;&lt;br&gt;
  &lt;input name="elev_klass" type="text" id="elev_klass"&gt;&lt;br&gt;
+
  &lt;input name="elev_klass" type="text" value= &lt;?=$elev_klass;?&gt;&gt;&lt;br&gt;
 
   
 
   
 
  &lt;b&gt;Hemligt ord (syns inte)&lt;/b&gt;&lt;br&gt;
 
  &lt;b&gt;Hemligt ord (syns inte)&lt;/b&gt;&lt;br&gt;
  &lt;input name="elev_hemligt" type="password" id="elev_hemligt"&gt;&lt;br&gt;
+
  &lt;input name="elev_hemligt" type="password" value= &lt;?=$elev_hemligt;?&gt;&gt;&lt;br&gt;
 
   
 
   
 
  &lt;b&gt;Instruktioner&lt;/b&gt;&lt;br&gt;
 
  &lt;b&gt;Instruktioner&lt;/b&gt;&lt;br&gt;
Rad 151: Rad 222:
 
  Om någon av dessa två regler bryts får du göra ett liknande prov med papper och penna efter skoltid istället.&lt;br&gt;&lt;br&gt;
 
  Om någon av dessa två regler bryts får du göra ett liknande prov med papper och penna efter skoltid istället.&lt;br&gt;&lt;br&gt;
 
   
 
   
  Läs igenom samtliga svar innan du trycker på ”spara”-knappen längst ner. När du väl sparat provet kan du inte ändra det längre. &lt;br&gt;&lt;br&gt;
+
  Läs igenom samtliga svar en gång extra innan du trycker på "spara"-knappen längst ner.&lt;br&gt;&lt;br&gt;
 
  &lt;h4&gt;Lycka till!&lt;/h4&gt;
 
  &lt;h4&gt;Lycka till!&lt;/h4&gt;
 
   
 
   
 
   
 
   
 
  &lt;?php
 
  &lt;?php
echo $Q1;
 
echo ”&lt;textarea  name=\"elev_svar1\" id=\"elev_svar1\" rows=\"20\" cols=\"40\"&gt;&lt;br&gt;”;
 
echo $Q2;
 
echo ”&lt;textarea  name=\"elev_svar2\" id=\"elev_svar2\" rows=\"20\" cols=\"40\"&gt;&lt;br&gt;”;
 
echo $Q3;
 
echo ”&lt;textarea  name=\"elev_svar3\" id=\"elev_svar3\" rows=\"20\" cols=\"40\"&gt;&lt;br&gt;”;
 
echo $Q4;
 
echo ”&lt;textarea  name=\"elev_svar4\" id=\"elev_svar4\" rows=\"20\" cols=\"40\"&gt;&lt;br&gt;”;
 
echo $Q5;
 
echo ”&lt;textarea  name=\"elev_svar5\" id=\"elev_svar5\" rows=\"20\" cols=\"40\"&gt;&lt;br&gt;”;
 
?&gt;
 
&lt;input type="hidden" name="inskickat" value="true"&gt;
 
 
   
 
   
  &lt;input type="submit" value="Spara" /&gt;
+
echo $Q1."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar1\" rows=\"10\" cols=\"76\"&gt;$S1&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q2."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar2\" rows=\"10\" cols=\"76\"&gt;$S2&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q3."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar3\" rows=\"10\" cols=\"76\"&gt;$S3&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q4."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar4\" rows=\"10\" cols=\"76\"&gt;$S4&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q5."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar5\" rows=\"10\" cols=\"76\"&gt;$S5&lt;/textarea&gt;&lt;br&gt;";
 +
 +
?&gt;
 +
 +
&lt;br&gt;
 +
  &lt;input type="submit" name="formSubmit" value="Spara" /&gt;
 
  &lt;/form&gt;
 
  &lt;/form&gt;
  &lt;p&gt; Provet bygger på texten i  &lt;a href=”http://www.grundskoleboken.se/wiki/Andra_v%C3%A4rldskriget,_krigsutbrottet” target=”new”&gt;
+
  &lt;p&gt; Provet bygger på texten i  &lt;a href="http://www.grundskoleboken.se/wiki/Andra_v%C3%A4rldskriget,_krigsutbrottet" target="new"&gt;
 
  http://www.grundskoleboken.se&lt;/a&gt; som tar upp andra världskrigets utbrott.
 
  http://www.grundskoleboken.se&lt;/a&gt; som tar upp andra världskrigets utbrott.
 
   
 
   
 
  &lt;/body&gt;
 
  &lt;/body&gt;
 
  &lt;/html&gt;
 
  &lt;/html&gt;
 +
 +
Starta gedit och klistra in koden här ovanför. Spara filen i var/www som ww2start.php. Gör en länk till provet från index.php och prova att göra provet som om du vore en elev.
 +
 +
==Kodanalys==
 +
 +
Så vad är det egentligen som händer i koden? Längst upp har vi
 +
&lt;?php
 +
för att visa att skriptet börjar, som standard lägger man allt som behövs beräknas i hemsidan här uppe innan &lt;html&gt; taggarna.
 +
 +
 +
session_start();
 +
för att se till så att en inloggad användare (du) inte tappar sin "biljett" på att den är inloggad.
 +
 +
 +
//Filnamn  ww2start.php
 +
Namnet på filen du jobbar med, det är inget som måste med men det underlättar för dig själv om det finns med.
 +
 +
 +
// Funktion för att förhindra databashackning
 +
  function rensatext($textattrensa)
 +
  {
 +
  $textattrensa = stripslashes($textattrensa); //Tar bort snedstreck
 +
  $textattrensa = mysql_real_escape_string($textattrensa);
 +
//Fixar enkla- och dubbla citattecken
 +
  return $textattrensa; //skickar tillbaka justerad text
 +
  }
 +
Det är väldigt bra att kunna hantera funktioner i php. Kommer du ihåg samma kod från inloggningen? Då fick du skriva in både stripslashes och mysql_real_escape_string två gånger; en gång för inloggningsnamnet och en gång för lösenordet. Har du en funktion kan du använda samma funktion för all text. Har du många rader underlättar funktioner något enormt. Och funktioner kan användas överallt när du behöver beräkna- eller ändra någonting om och om igen. Hur fungerar uppbyggnaden?
 +
function = vi talar om att vi skall beskriva en funktion.
 +
rensatext=namnet på funktionen, hitta på logiska namn.
 +
($textattrensa) = det vi skickar in i funktionen utifrån.
 +
$textattrensa = stripslashes($textattrensa); //Tar bort snedstreck
 +
$textattrensa = mysql_real_escape_string($textattrensa);
 +
//Fixar enkla- och dubbla citattecken
 +
Detta är egentligen två inbyggda funktioner i php och vi använder dem för att ändra texten så att man inte förstör möjligheten att lägga in text i databasen. Annars räcker det med ett I’m hungry” för att förhindra kontakten mellan sidan och MySQLdatabasen eftersom texten innehåller ett ’-tecken som är samma sorts tecken som används för MySQL satser (se nedan). Dessutom förhindras att elaka människor hackar databasen utifrån om man gör på det här sättet.
 +
 +
Man lägger alltid in funktioner så högt upp i sidan som möjligt, eller ändå hellre i en separat egen sida som man länkar till, men hur man gör det går jag igenom längre fram.
 +
 +
 +
  //Olika viktiga variabler
 +
  $host="localhost"; // Host , på en privat dator duger oftast localhost
 +
  $username="root"; // Mysql användarnamn, antagligen root
 +
  $password="password1"; // Lösenord till root, kan t.ex. vara password1
 +
  $db_name="skolan"; // Databasens namn
 +
Allt detta behövs för att vi skall kunna logga in på MySQL databasen och spara resultatet som eleverna skriver. Nu är det rätt bökigt att skriva i allt detta på varenda sida så man brukar ha en separat egen sida för dem som man länkar till, men hur man gör det går jag igenom längre fram.
 +
 +
 +
// Anslut till MySQL servern och välj rätt tabell
 +
  mysql_connect("$host", "$username", "$password")or die("Kan inte ansluta till databasen");
 +
  mysql_select_db("$db_name")or die("Kan inte välja datatabellen");
 +
Vi försöker att ansluta till MySQL servern och välja rätt databas med de uppgifter vi angett.
 +
 +
// Alla olika variabler som skall läggas in i databasen när eleven sparar resultatet
 +
  $elev_id=0;
 +
  $larar_id=0; //Här kan du fylla i ditt eget id direkt, om du vet om det
 +
  $provnamn='ProvWW2';
 +
  $provkommentar = 'Orättat'; //Här skriver du till eleven, poäng på prov osv, men inte nu
 +
  $resultat = 'Orättat'; //Här skrivs resultatet, men inte nu.
 +
  $datumgjort = date('Y-m-d H:i:s');
 +
  $datumraettat = 'Orättat'; //Detta ändras när du rättat provet
 +
De här variablerna är sådana som inte ändras beroende på vad användarna gör. Datumkoden är litet speciell, den skriver år-månad-dag timme:minut:sekund vid det ögonblick som sidan visas. Det innebär att om eleven tar en timme på sig att göra provet kommer tiden att vara en timme fel. För att undvika det kan man flytta ner tidsberäkningen till alldeles efter det att man lägger in texten i databasen istället (se nedan).
 +
 +
 +
//Har man tryckt på knappen?
 +
  if($_POST['formSubmit'] == "Spara")
 +
  {
 +
  $elev_fnamn=$_POST['elev_fnamn'];
 +
  $elev_enamn=$_POST['elev_enamn'];
 +
  $elev_hemligt=$_POST['elev_hemligt'];
 +
  $elev_klass=$_POST['elev_klass'];
 +
  //Skulle kunna skrivas som $elev_klass = '8A' om alla är i samma klass
 +
  //Men då skulle det ligga utanför knapphändelsen
 +
 +
  //Elevens olika svar
 +
  $S1=$_POST['elev_svar1'];
 +
  $S2=$_POST['elev_svar2'];
 +
  $S3=$_POST['elev_svar3'];
 +
  $S4=$_POST['elev_svar4'];
 +
  $S5=$_POST['elev_svar5'];
 +
  $inskickat = 'true';
 +
  }
 +
Om man tryckt på submitkanppen som har namnet Spara (man kn ha flera knappar i ett formulär) så sparas det eleven skrivet i de olika fälten i olika variabler. Det eleven t.ex. skrev i förnamnsfältet, som har namnet elev_fnamn, sparas som variabeln $elev_fnamn. Namnet på fältet finns angivet i html-koden och variablens namn har jag hittat på själv.
 +
 +
$inskickat är en variabel som helt enkelt avgör om du skickat in formuläret eller inte. Det är alltid falskt (fasle) när sidan först visas och blir sann (true) efter det att man tryckt på spara-knappen minst en gång. Detta görs för att man inte skall spara ett tomt, ogjort prov i databasen. Glöm inte att kapsla in allt mellan två måsvinge-tecken  { kod här }
 +
 +
 +
  else
 +
  {
 +
  $elev_fnamn='förnamn';
 +
  $elev_enamn='efternamn';
 +
  $elev_hemligt=''; //OBS! wiki:n tar bort koden för två enkla citattecken
 +
  $elev_klass='klass';
 +
 +
  //Elevens olika svar
 +
  $S1='Svar:';
 +
  $S2='Svar:';
 +
  $S3='Svar:';
 +
  $S4='Svar:';
 +
  $S5='Svar:';
 +
  $inskickat = 'false';
 +
  }
 +
Variablerna får inte vara tomma, det ger otäcka fel. Därför måste vi också fylla i vad variablerna innehåller för värden om man INTE tryckt på någon knapp. Observera att det är exakt samma variabler i denna kod som i koden för om man tryckt på en knapp.
 +
 +
Två enkla citattecken i rad visar att inget skall fyllas i, tyvärr är det också ett sätt att visa kursiv stil i en wiki (som det här är) så de försvinner. Där det står ” OBS! wiki:n tar bort koden för två enkla citattecken
 +
” skall det alltså egentligen stå två enkla citattecken, men du ser det bara om du väljer ”visa wikitext” längst upp.
 +
 +
 +
$elevsvar="Svar1&lt;br&gt;".$S1."&lt;br&gt;Svar2&lt;br&gt;".$S2."&lt;br&gt;Svar3&lt;br&gt;".$S3."&lt;br&gt;Svar4&lt;br&gt;".$S4."&lt;br&gt;Svar5&lt;br&gt;".$S5."&lt;br&gt;";
 +
 +
Sedan gäller det att lägga ihop alla fem (eller fler i andra prov) elevsvaren i en enda variabel ($elevsvar). Som jag sa tidigare, detta är ett enkelt sätt att ha växlande antal frågor i olika prov som utgår ifrån samma mall.
 +
 +
I php lägger man ihop två texter genom att placera en punkt mellan dem. Ett enkelt exempel:
 +
$rad1 = ’hej ’;
 +
$rad2 = ’du’;
 +
Echo $rad1.$rad2  //ger: hej du
 +
Som du ser i koden sparar vi varje svar genom att lägga till Svar1 (för svar ett) i början så att det är enklare att se vad eleven svarat på för fråga, samt en radbrytning i slutet så att varje svar börjar på en ny rad när det är dags att rätta dem.
 +
 +
 +
$Q1="1: Vad var orsaken till Tysklands och Polens ovänskap?&lt;br&gt;";
 +
$FACIT1="E=Man hade ofta bråkat om gränserna.&lt;br&gt;
 +
(osv.)
 +
Här ger jag varje fråga en egen variabel, och varje svar en egen variabel. Detta för att det skall gå lätt att visa upp stora textstycken på rätt plats genom att bara ange variabelnamnet.
 +
 +
 +
$facit= $Q1."&lt;br&gt;".$FACIT1."&lt;br&gt;".$Q2."&lt;br&gt;".$FACIT2."&lt;br&gt;".$Q3."&lt;br&gt;".$FACIT3."&lt;br&gt;".$Q4."&lt;br&gt;".$FACIT4."&lt;br&gt;".$Q5."&lt;br&gt;".$FACIT5;
 +
 +
Precis som med elevens alla svar lägger jag ihop alla frågor med de korrekta svaren i en enda variabel ($facit) så att det skall gå lätt att visa upp hela provet inklusive facit för eleverna (och deras föräldrar). Hur man skapar en provvisare kommer jag till längre fram.
 +
 +
 +
//Rensa bort alla ovälkomna tecken i ingående text
 +
  $elev_fnamn= rensatext($elev_fnamn);
 +
  $elev_enamn= rensatext($elev_enamn);
 +
  $elev_hemligt= rensatext($elev_hemligt);
 +
  $elev_klass= rensatext($elev_klass);
 +
  $facit=rensatext($facit);
 +
  $elevsvar=rensatext($elevsvar);
 +
Innan texten läggs in i databasen rensatr vi den med vår funktion som finns i toppen av dokumentet så att inga backslash, citattecken eller enkelt citattecken  avsiktligt eller av misstag kommer med och förstör möjligheterna att spara texten i databasen.
 +
 +
Skulle du titta på hur texten ser ut nu kommer du att märka att det finns en backslash framför alla enkla- och dubbla citattecken, men också där alla radbrytningar är. Om du visar upp texten i en textruta ser den fin ut, men om du skriver ut den rakt i dokumentet ser det värre ut då t.ex. alla radbrytningar markeras med backslash och ett n. Oroa dig inte, det finns funktioner för att återställa texten som t.ex. nl2br($text); som förvandlar alla radbrytningar till &lt;br&gt; tecken istället.
 +
 +
 +
//Spara provet
 +
if ($inskickat=='true')
 +
{
 +
$sql="INSERT INTO simpeltprov(ID,ELEV_ID,LARAR_ID,F_NAMN,E_NAMN,HEMLIGTORD,KLASS,PROVNAMN,FACIT,ELEVSVAR,PROVKOMMENTAR,RESULTAT,DATUM_GJORT,DATUM_RATTAT)
 +
VALUES
 +
  (null,$elev_id,$larar_id,'".$elev_fnamn."','".$elev_enamn."','".$elev_hemligt."','".$elev_klass."','".$provnamn."','".$facit."','".$elevsvar."','".$provkommentar."','".$resultat."','".$datumgjort."','".$datumraettat."')";
 +
 +
 +
Har man tryckt på knappen? Är inskickat sant (observera de dubbla == tecknen när man jämför någonting, det är lätt att göra fel).
 +
 +
Är det så skapar vi en text för att spara information i databasen. Först anger vi vilka datafält som skall fyllas och därefter vilka värden som skall in i fälten. Egentligen behöver man inte ange namnen på fälten, men det är inte fel att fylla i dem eftersom det underlättar felsökning om det strular till sig, vilket det ofta gör. Värdena som man skickar till databasen skall ha enkelt citattecken före och efter om det är text, men inga enkla citattecken om det är siffror. Det är ofta jag misslyckas här när jag endera glömmer ett citattecken någonstans eller en punkt, då blir sidan bara helvit utan några tecken på alls ch det är bara att börja felsöka textraden.
 +
 +
 +
  $result=mysql_query($sql);
 +
  if($result){
 +
  echo "Provet är Sparat i databasen"; //Det gick bra
 +
  }else{
 +
    echo "&lt;b&gt;FEL!&lt;/b&gt; ditt prov sparades inte."; //Det uppstod något fel
 +
    }
 +
  }
 +
Sedan kommer slutet av php-satsen. Hela textraden heter $sql och vi ser om det lyckas med $result. mysql_query($sql); innebär helt enkelt att vi försöker att köra textraden mot MySQL databasen.  Fungerade det att spara? Fint, då skrivs det ut allra längst upp på sidan. Blev det något fel? Då skrivs även det ut. All text sparas dock i hemsidans textrutor så om det uppstår ett fel får du be eleven kopiera texten, ruta för ruta, i ett word-dokument och skicka in det till dig på annat vis.
 +
 +
 +
?&gt;
 +
Slut på all php som behöver skrivas innan sidan visas.
 +
 +
 +
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
 +
&lt;html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="sv-SE"&gt;
 +
&lt;head&gt;
 +
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
 +
&lt;title&gt;Prov om 2:a världskrigets utbrott &lt;/title&gt;
 +
&lt;/head&gt;
 +
 
 +
&lt;body&gt;
 +
 +
Den text som behövs för att tala om för Google Chrome, Firefox eller liknande program att en hemsida skall visas.
 +
 +
 +
&lt;form name="form1" method="post" action="ww2start.php"&gt;
 +
Här börjar ett formulär. Det skall postas när man trycker på en submitknapp och det skall postas till sig själv. Konstigt? Nej, egentligen inte. Det underlättar en hel del om man postar formulären till sig själv eftersom man kan bibehålla värdena i alla textrutor på ett enkelt sätt även om man tappar kontakten med databas-servern.
 +
 +
 +
  &lt;h2&gt;Prov om andra världskrigets utbrott&lt;/h2&gt;&lt;br&gt;&lt;br&gt;
 +
  &lt;b&gt;Förnamn&lt;/b&gt;&lt;br&gt;
 +
  &lt;input name="elev_fnamn" type="text" value=
 +
  &lt;?=$elev_fnamn;?&gt;&gt;&lt;br&gt;
 +
  &lt;b&gt;Efternamn&lt;/b&gt;&lt;br&gt;
 +
  &lt;input name="elev_enamn" type="text" value=
 +
  &lt;?=$elev_enamn;?&gt;&gt;&lt;br&gt;
 +
  &lt;b&gt;Klass&lt;/b&gt;&lt;br&gt;
 +
  &lt;input name="elev_klass" type="text" value=
 +
  &lt;?=$elev_klass;?&gt;&gt;&lt;br&gt;
 +
 +
  &lt;b&gt;Hemligt ord (syns inte)&lt;/b&gt;&lt;br&gt;
 +
  &lt;input name="elev_hemligt" type="password" value=
 +
  &lt;?=$elev_hemligt;?&gt;&gt;&lt;br&gt;
 +
 +
Här fyller eleven i alla uppgifter om sig själv. ”name=” måste vara med för att php skall kunna hantera informationen från fälten. Man kan fylla i ett fast värde, eller ange att den i förväg skall innehålla värdet av en variabel. Förnamnet har t.ex.
 +
value= &lt;?=$elev_fnamn;?&gt;
 +
vilket innebär att det står "Förnamn" i rutan innan eleven skrivit ett eget namn, och efter att formuläret sparats står elevens förnamn där istället.
 +
 +
Grundregeln för databashantering är att användaren skall skriva så litet som möjligt för att undvika att det blir fel i databasen. Vad händer om vissa elever skriver ”8A”, andra ”8 A” andra ”8a” och vissa ”8an”? För MySQL är detta fyra olika klasser. Då är det bättre att ha en fast variabel ”$klass=’8A’; i början av dokumentet. Samma sak med elevnamnen, kan du så dra den informationen ur elevdatabasen och låt eleverna klicka på sitt namn i en lista istället. Jag går igenom hur det går till längre fram.
 +
 +
 +
Under detta kommer instruktionerna och sedan:
 +
 +
&lt;?php
 +
 
 +
echo $Q1."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar1\" rows=\"10\"  cols=\"76\"&gt;$S1&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q2."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar2\" rows=\"10\" cols=\"76\"&gt;$S2&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q3."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar3\" rows=\"10\" cols=\"76\"&gt;$S3&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q4."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar4\" rows=\"10\" cols=\"76\"&gt;$S4&lt;/textarea&gt;&lt;br&gt;";
 +
echo $Q5."&lt;br&gt;";
 +
echo "&lt;textarea  name=\"elev_svar5\" rows=\"10\" cols=\"76\"&gt;$S5&lt;/textarea&gt;&lt;br&gt;";
 +
 +
?&gt;
 +
Här skrivs enkelt alla frågorna in och en textruta för varje svar kommer med. ”cols=” avgör hur bred textrutan är och ett A4 papper tar ungefär 76 tecken. Om du däremot skapar prov för iPads eller iPhones/andrid kan du göra textrutorna smalare och högre. ”rows=” visar hur många textrader som syns i textrutan, men man kan skriva många fler rader än så.
 +
 +
 +
&lt;br&gt;
 +
&lt;input type="submit" name="formSubmit" value="Spara" /&gt;
 +
&lt;/form&gt;
 +
 +
Slut på php och sedan knappen man trycker på. Sedan avslutas formuläret. Om man har olika knappar kan man ge dem olika namn. Det finns en hake här, om eleven klickar på ENTER tangenten istället i någon annan ruta än ett textfält kan det hända att sidan förnyas utan att knappen tryckts in, vilket i värsta fall innebär att allt eleven gjort går förlorat. Därför bör du aldrig skapa ett prov med svarsrutor först och rutor för namn osv. sist. Var noga med att poängtera för eleverna att de måste trycka på knappen i slutet.
 +
 +
 +
&lt;/body&gt;
 +
&lt;/html&gt;
 +
Och här avslutas sidan.
 +
 +
 +
Som sagt, det ser mastigt ut, och det kanske inte är det allra enklaste, men med det här provet som mall kan du tillverka precis hur många databasdrivna prov som helst. Nu har jag inte lagt till något ”lullull” alls som bilder, ljud eller film, utan det är sådant du kan göra för att få provet att se mer tilltalande ut.
  
Starta gedit och klistra in koden här ovanför. Spara filen i var/www som ww2start.php. Gör en länk till provet från index.php och prova att göra provet som om du vore en elev.
 
  
  
 
[[Kategori: Privat]]
 
[[Kategori: Privat]]

Nuvarande version från 13 juni 2012 kl. 08.58

Ett enkelt prov

Som jag tog upp i början så utgår jag ifrån KISS; så enkelt som det bara går men ändå inte så förenklat att det blir oanvändbart. Utifrån det perspektivet skall vi skapa ett riktigt enkelt prov. Det finns vissa utgångspunkter:

1: Provet består av valfritt antal frågor vars svar blandas ihop i en enda text. Jag har försökt att bygga upp system med olika antal frågor per prov där varje fråga är en post i en datatabell, men då måste varje prov bestå av tre olika databastabeller: en tabell med provnamn som fungerar som behållare, en tabell med frågor och svar och en tabell som binder samman frågorna med provnamnet. Om man däremot utgår ifrån en enda text som svar räcker det med en enda tabell, det är mer begränsat, men mycket enklare att hantera.

2: Eleven skriver text till alla frågor. Detta är inte hugget i sten, det går att utforma så att eleven istället väljer färdiga svar från olika listor, men det går jag igenom längre fram. I det här första exemplet är samtliga frågor utformade på exakt samma sätt.

3: Eleven behöver inte logga in. Största problemet med Internetbaserade lösningar är att elever måste logga in först, och läraren sliter sitt hår när tre, fem, åtta osv. elever dyker upp och meddelar att de glömt/tappat sina inloggningsnamn eller lösenord. Det skall vara lika enkelt att göra prov vid datorn som när man sätter sig vid en bänk och fyller i namn och klass med blyertspenna, och då fungerar det helt enkelt inte med personlig inloggning. Istället används en lösenordsruta med ett "hemligt ord". Endera väljer eleven ordet själv eller så väljer du ett ord åt eleven, det senare är att föredra. Genom att använda ett hemligt ord kan inte andra elever skriva i svar åt varandra. En elev kan t.ex. fylla i spindelmannen som sitt personliga hemliga ord och då vet ju du som lärare att förnamn + efternamn + spindelmannen är just den eleven. Problemet är att du måste fråga varje elev personligen om vilket hemligt ord de har om du dessutom får in ett prov med samma förnamn + samma efternamn + "ångvält". Därför kan du trycka upp hemliga ord i förväg och dela ut en papperslapp med individuella hemliga ord till varje elev innan provet. Då vet du att "ångvält" inte är den elevens prov utan någon kamrat som endera vill vara elak och skriva ett dåligt prov, eller vill vara snäll och skriva ett "förbättrat" prov.

4: Provet går inte att redigera av eleverna efter det att det sparats. Då fungerar det som en Wiki och det går alltid att se äldre versioner. Det enda eleven kan göra är att spara en ny version av samma prov. På det viset kan du spåra fuskare på ett rätt enkelt sätt.

5: Provet skall stämplas med både datum och tid för inlämning, på det viset kan du förhindra fusk. Finns ingen tidsstämpel kan eleven påstå att den gjort provet under provtillfället trots att den gjort det vid ett helt annat tillfälle.

6: Samtidigt som du skriver frågan skriver du svaret. På det sättet finns ett facit. Då kan du också göra en enkel rutin som skriver ut fråga + svar åt eleverna efter det att provet är klart så att de själva lätt kan se vad de gjorde för fel. Dessutom underlättas din egen rättning. I facit kan du använda HTML taggar så kan du förtydliga det du tycker är viktigt om du visar upp facit i en hemsida efter provet.

7: Varje inlämnat prov har ett tillhörande textfält där du kan skriva en bedömning och själv fylla i vilka betygsmål du tycker att eleven uppnått i hela provet. När det är dags att lämna tillbaka det färdigrättade provet kan du endera skriva ut elevprov+facit+din bedömning till eleven och ge den resultatet i pappersform, eller skapa en pdf-fil med uppgifterna som du skickar med e-mail till eleven så sparar skolan pengar både på att proven inte behöver skrivas ut och på att resultatet kan läsas online.

8: varje prov skall ha en ruta för att lägga in ett elev-id så att du, om du vill, kan lägga in en koppling mellan provdatabasen och elevdatabasen Likaså skall det finnas ett lärar-id så att det är möjligt att flera lärare kan dela samma provtabell, men så att man samtidigt förhindrar att lärare ändrar andras prov av misstag.

Tabellstruktur

Så, med allt detta definierat är det dags att skapa en datatabell där uppgifterna kan lagras:

CREATE TABLE simpeltprov (                
ID    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ELEV_ID INT,
LARAR_ID INT,
F_NAMN VARCHAR (50),
E_NAMN VARCHAR (50),
HEMLIGTORD VARCHAR (50),
KLASS VARCHAR (50),
PROVNAMN VARCHAR (50),
FACIT TEXT,
ELEVSVAR TEXT,
PROVKOMMENTAR TEXT,
RESULTAT VARCHAR (50),
DATUM_GJORT VARCHAR (50),
DATUM_RATTAT VARCHAR (50)
);

TEXT är en ny sorts fält du inte sett tidigare, men det är helt enkelt ett fält i databasen som rymmer en obegränsad (nästan) mängd text till skillnad från VARCHAR som endast rymmer 255 tecken.

ELEV_ID och LARAR_ID är som standard 0, något vi fixar när vi lägger in poster, eftersom alla ID nummer börjar på 1. Då vet vi att om det är en 0:a saknas koppling till en speciell elev eller lärare medan det går att samköra provet med elevregistret eller lärarregistret om värdet är över 0.

FACIT används så att provfråga + provsvar sparas efter varandra så att det är lätt att se hur de hänger ihop. En fråga kan ha svar på flera betygsnivåer och då bör det finnas facit till E, C och A nivå. Allra minst skall facit finnas för E nivån.

PROVKOMMENTAR är ett textfält som används istället för den traditionella kommentaren i marginalen där man kan sammanställa hur många poäng eleven fick, vad den gjorde för fel, vad den hade kunnat förbättrat osv.

RESULTAT tänkte jag kan användas för att fylla i ett betyg eller liknande omdöme. Skolverket får frispel när man skriver ut ett betygsvärde på ett prov, medan eleverna alltid vill veta vilket betyg de fick på provet. Det är upp till varje lärare att avgöra om det är bra att göra så. Själv brukar jag istället numrera betygsmålen och sedan fylla i siffror för målen: C2, E1 och E3 kan t.ex. ha blivit uppfyllda och då skriver jag i det istället.

DATUM_RATTAT är litet överkurs, men det kan vara bra att se vilket datum det var du senast rättade eller redigerade någonting i en enskild elevs prov. Det är för din egen skull och inget som någon elev kan tänkas se.

Logga in i MySQL och skapa tabellen innan du fortsätter med att skapa sidan som tillhör tabellen (se nedan).

Logga in i MySQL med:

mysql -u root -p

Fyll i lösenord och skriv:

use skolan

Därefter klistrar du bara in koden här ovanför så att datatabellen skapas.

Provexempel

Exemplet kanske verkar fruktansvärt jobbigt med mängder av kod, men poängen är att du, i framtiden, bara behöver ändra delar av koden. Grovarbetet är gjort åt dig.

<?php
 session_start();
//Filnamn  ww2start.php

// Funktion för att förhindra databashackning
function rensatext($textattrensa)
{
$textattrensa = stripslashes($textattrensa); //Tar bort snedstreck
$textattrensa = mysql_real_escape_string($textattrensa); //Fixar enkla- och dubbla citattecken
return $textattrensa; //skickar tillbaka justerad text
}

//Olika viktiga variabler
$host="localhost"; // Host , på en privat dator duger oftast localhost
$username="root"; // Mysql användarnamn, antagligen root
$password="password1"; // Lösenord till root, kan t.ex. vara password1
$db_name="skolan"; // Databasens namn

// Anslut till MySQL servern och välj rätt tabell
mysql_connect("$host", "$username", "$password")or die("Kan inte ansluta till databasen");
mysql_select_db("$db_name")or die("Kan inte välja datatabellen");

// Alla olika variabler som skall läggas in i databasen när eleven sparar resultatet


$elev_id=0;
$larar_id=0; //Här kan du fylla i ditt eget id direkt, om du vet om det
$provnamn='ProvWW2';
//$facit= längre ner, efter alla frågor och svar
$provkommentar = 'Orättat'; //Här skriver du till eleven, poäng på prov osv, men inte nu
$resultat = 'Orättat'; //Här skrivs resultatet, men inte nu.
$datumgjort = date('Y-m-d H:i:s');
$datumraettat = 'Orättat'; //Detta ändras när du rättat provet

//Har man tryckt på knappen?
if($_POST['formSubmit'] == "Spara")
{
$elev_fnamn=$_POST['elev_fnamn'];
$elev_enamn=$_POST['elev_enamn'];
$elev_hemligt=$_POST['elev_hemligt'];
$elev_klass=$_POST['elev_klass'];
//Skulle kunna skrivas som $elev_klass = '8A' om alla är i samma klass
//Men då skulle det ligga utanför knapphändelsen

//Elevens olika svar
$S1=$_POST['elev_svar1'];
$S2=$_POST['elev_svar2'];
$S3=$_POST['elev_svar3'];
$S4=$_POST['elev_svar4'];
$S5=$_POST['elev_svar5'];
$inskickat = 'true';
}
else
{
$elev_fnamn='förnamn';
$elev_enamn='efternamn';
$elev_hemligt=; //OBS! wiki:n tar bort koden för två enkla citattecken
$elev_klass='klass';

//Elevens olika svar
$S1='Svar:';
$S2='Svar:';
$S3='Svar:';
$S4='Svar:';
$S5='Svar:';
$inskickat = 'false';
}

$elevsvar="Svar1<br>".$S1."<br>Svar2<br>".$S2."<br>Svar3<br>".$S3."<br>Svar4<br>".$S4."<br>Svar5<br>".$S5."<br>";

$Q1="1: Vad var orsaken till Tysklands och Polens ovänskap?<br>";
$FACIT1="E=Man hade ofta bråkat om gränserna.<br> 
C=Västra Polen hade tillhört Tyskland men gick över till Polen efter 1:a världskriget och gränslandets tyskar behandlades illa av polackerna.<br> 
A=Under historiens gång hade Polen ibland inte existerat som land utan varit en del av andra länder. Polackerna såg på Tyskarna som erövrare. Vissa polacker tog chansen att
hämnas på de tyskar som bodde i västra Polen, vilket var dumt eftersom Hitler tog upp det som en orsak till ett krig.<br>";
$Q2="2: Varför var Danzigkorridoren så viktig?<br>";
$FACIT2="E=Det var den enda kuststräcka som Polen hade tillgång till.<br> 
C=För tyskarna var korridoren ett problem eftersom den skar av det viktiga Östpreussen från det övriga Tyskland. Tyskarna visste att om de kunde skära av korridoren skulle de vinna två saker, fri 
tillgång till Östpreussens land och att polackerna tvingades driva all handel genom Danzig, en hamn som inte var polsk.<br>  
A=Danzig var synnerligen tyskvänligt, även om det var en fristad. Skulle polens handel tvingas genom Danzig skulle Tyskland kunna ta ut höga avgifter och bli väldigt rika samtidigt som hamnen i
Östpreussen skulle kunna användas för handel till och från Tyskland landvägen, något som var omöjligt så länge Danzigkorridoren var i polsk kontroll.<br> ";
$Q3="3: Varför var Molotov-Ribbentrop pakten så viktig?<br> ";
$FACIT3="E=För att genom den kunde inte Tyskland och Sovjetunionen starta ett krig mot varandra.<br>  
C=Eftersom de två stormakterna Tyskland och Sovjetunionen, som egentligen var politiska fiender, inte längre behövde skydda sig mot varandra kunde militären som skyddade den gemensamma gränsen
spridas ut mot andra fronter.<br>   
A=Pakten innebar dessutom att Europa i praktiken delades upp mellan stormakterna där Sovjet lovades den östra halvan vilket var ungefär samma område som Sovjet tappade efter 1:a
världskriget. Pakten gav dessutom Tyskland tillgång till sovjetiska råvaror man själva led brist på, som t.ex. olja och bensin. Något som var väldigt viktigt inför attacken mot
Västeuropa.<br> ";
$Q4="4: Hur gick det till när kriget bröt ut?<br> ";
$FACIT4="E=Tyska trupper gick in i Polen 1/9 1939 trots att England varnat om att det skulle starta ett krig. Tyskland brydde sig inte och krigsförklaringen England-Polen var ett
faktum.<br> 
C= Tyskland hade provocerat fram ett krigsutbrott genom att låta förklädda tyskar anfalla andra tyskar så att det skulle se ut som att stackars Tyskland blivit oskyldigt anfallet av
det elaka Polen. Därför var man tvungna att försvara sig. Allt var naturligtvis bara propaganda.<br> 
A=Man började med att beskjuta Westerplatte, Polens enda kustfort, för att snabbt kunna ta över östersjökusten. Med hamnarna säkrade var det enkelt att anfalla från flera olika håll.
Tyskland gjorde vad man kunde för att anfalla så fort, och så hårt, som möjligt, precis som man hade gjort mot Ryssland i början av 1:a världskriget. Ett verktyg för detta var
blitzkrieg, att man sköt sönder broar ock liknande bakom fronten och skapade luckor i Polens försvar med hjälp av pansarvagnar som sedan lugnt kunde fortsätta in i Polens kärnland utan
att riskera att bli anfallna.<br> ";
$Q5="5: Många flyktingar drabbades hårt, varför? Och var kom alla flyktingar ifrån?<br> ";
$FACIT5="E=När tyska flygplan bombade städerna och tyska trupper snabbt trängde in i Polen flydde vanliga civila bort från tyskarna.<br>  
C= Flyktingarna hade ingenstans att ta vägen eftersom tyskarna anföll från flera håll och dessutom anföll Sovjet från öst. Varken tyskarna eller sovjeterna var speciellt snälla mot
flyktingarna heller utan mängder dödades eller skadades när de var ivägen för de framvällande tyska- och sovjetiska trupperna.<br>  
A=Bland de som flydde fanns även tyskättlingar bosatta i Polen som försökte fly till de tyska trupperna eftersom polacker tog chansen att anfalla dem, som t.ex. i byn Bromberg.<br> "; 

$facit= $Q1."<br>".$FACIT1."<br>".$Q2."<br>".$FACIT2."<br>".$Q3."<br>".$FACIT3."<br>".$Q4."<br>".$FACIT4."<br>".$Q5."<br>".$FACIT5;

//Rensa bort alla ovälkomna tecken i ingående text
$elev_fnamn= rensatext($elev_fnamn);
$elev_enamn= rensatext($elev_enamn);
$elev_hemligt= rensatext($elev_hemligt);
$elev_klass= rensatext($elev_klass);
$facit=rensatext($facit);
$elevsvar=rensatext($elevsvar);

//Spara provet
if ($inskickat=='true')
{
$sql="INSERT INTO simpeltprov
(ID,ELEV_ID,LARAR_ID,F_NAMN,E_NAMN,HEMLIGTORD,KLASS,PROVNAMN,FACIT,ELEVSVAR,PROVKOMMENTAR,RESULTAT,DATUM_GJORT,DATUM_RATTAT) 
VALUES 
(null,$elev_id,$larar_id,'".$elev_fnamn."','".$elev_enamn."','".$elev_hemligt."','".$elev_klass."','".$provnamn."','".
$facit."','".$elevsvar."','".$provkommentar."','".$resultat."','".$datumgjort."','".$datumraettat."')";

$result=mysql_query($sql);
if($result){
echo "Provet är Sparat i databasen"; //Det gick bra
}else{
 echo "FEL! ditt prov sparades inte."; //Det uppstod något fel
 }
}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="sv-SE">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Prov om 2:a världskrigets utbrott </title>
</head>
 
<body>
<form name="form1" method="post" action="ww2start.php">

<h2>Prov om andra världskrigets utbrott</h2><br>
<b>Förnamn</b><br>
<input name="elev_fnamn" type="text" value= <?=$elev_fnamn;?>><br>
<b>Efternamn</b><br>
<input name="elev_enamn" type="text" value= <?=$elev_enamn;?>><br>
<b>Klass</b><br>
<input name="elev_klass" type="text" value= <?=$elev_klass;?>><br>

<b>Hemligt ord (syns inte)</b><br>
<input name="elev_hemligt" type="password" value= <?=$elev_hemligt;?>><br>

<b>Instruktioner</b><br>
Fyll i förnamn, efternamn, klass och ditt hemliga ord i rutorna här ovanför.  Varje fråga har en textruta under sig, det är i den du skall fylla i ditt svar. 
Det är <b>förbjudet</b> att ha någon annan sida uppe på datorn utom provsidan. Likaså är det förbjudet att använda någon form av kontakt mellan elever 
(MSN, steam, facebook, sms  osv.) under provtillfället vare sig det sker mellan datorer eller telefoner. 
Om någon av dessa två regler bryts får du göra ett liknande prov med papper och penna efter skoltid istället.<br><br>

Läs igenom samtliga svar en gång extra innan du trycker på "spara"-knappen längst ner.<br><br>
<h4>Lycka till!</h4>


<?php

echo $Q1."<br>";
echo "<textarea  name=\"elev_svar1\" rows=\"10\" cols=\"76\">$S1</textarea><br>";
echo $Q2."<br>";
echo "<textarea  name=\"elev_svar2\" rows=\"10\" cols=\"76\">$S2</textarea><br>";
echo $Q3."<br>";
echo "<textarea  name=\"elev_svar3\" rows=\"10\" cols=\"76\">$S3</textarea><br>";
echo $Q4."<br>";
echo "<textarea  name=\"elev_svar4\" rows=\"10\" cols=\"76\">$S4</textarea><br>";
echo $Q5."<br>";
echo "<textarea  name=\"elev_svar5\" rows=\"10\" cols=\"76\">$S5</textarea><br>";

?> 

<br>
<input type="submit" name="formSubmit" value="Spara" />
</form>
<p> Provet bygger på texten i  http://www.grundskoleboken.se/wiki/Andra_v%C3%A4rldskriget,_krigsutbrottet" target="new">
http://www.grundskoleboken.se som tar upp andra världskrigets utbrott.

</body>
</html>

Starta gedit och klistra in koden här ovanför. Spara filen i var/www som ww2start.php. Gör en länk till provet från index.php och prova att göra provet som om du vore en elev.

Kodanalys

Så vad är det egentligen som händer i koden? Längst upp har vi

<?php 

för att visa att skriptet börjar, som standard lägger man allt som behövs beräknas i hemsidan här uppe innan <html> taggarna.


session_start();

för att se till så att en inloggad användare (du) inte tappar sin "biljett" på att den är inloggad.


//Filnamn  ww2start.php

Namnet på filen du jobbar med, det är inget som måste med men det underlättar för dig själv om det finns med.


// Funktion för att förhindra databashackning
 function rensatext($textattrensa)
 {
 $textattrensa = stripslashes($textattrensa); //Tar bort snedstreck
 $textattrensa = mysql_real_escape_string($textattrensa); 
//Fixar enkla- och dubbla citattecken
 return $textattrensa; //skickar tillbaka justerad text
 }

Det är väldigt bra att kunna hantera funktioner i php. Kommer du ihåg samma kod från inloggningen? Då fick du skriva in både stripslashes och mysql_real_escape_string två gånger; en gång för inloggningsnamnet och en gång för lösenordet. Har du en funktion kan du använda samma funktion för all text. Har du många rader underlättar funktioner något enormt. Och funktioner kan användas överallt när du behöver beräkna- eller ändra någonting om och om igen. Hur fungerar uppbyggnaden?

function = vi talar om att vi skall beskriva en funktion.
rensatext=namnet på funktionen, hitta på logiska namn.
($textattrensa) = det vi skickar in i funktionen utifrån.
$textattrensa = stripslashes($textattrensa); //Tar bort snedstreck
$textattrensa = mysql_real_escape_string($textattrensa); 
//Fixar enkla- och dubbla citattecken

Detta är egentligen två inbyggda funktioner i php och vi använder dem för att ändra texten så att man inte förstör möjligheten att lägga in text i databasen. Annars räcker det med ett I’m hungry” för att förhindra kontakten mellan sidan och MySQLdatabasen eftersom texten innehåller ett ’-tecken som är samma sorts tecken som används för MySQL satser (se nedan). Dessutom förhindras att elaka människor hackar databasen utifrån om man gör på det här sättet.

Man lägger alltid in funktioner så högt upp i sidan som möjligt, eller ändå hellre i en separat egen sida som man länkar till, men hur man gör det går jag igenom längre fram.


 //Olika viktiga variabler
 $host="localhost"; // Host , på en privat dator duger oftast localhost
 $username="root"; // Mysql användarnamn, antagligen root
 $password="password1"; // Lösenord till root, kan t.ex. vara password1
 $db_name="skolan"; // Databasens namn

Allt detta behövs för att vi skall kunna logga in på MySQL databasen och spara resultatet som eleverna skriver. Nu är det rätt bökigt att skriva i allt detta på varenda sida så man brukar ha en separat egen sida för dem som man länkar till, men hur man gör det går jag igenom längre fram.


// Anslut till MySQL servern och välj rätt tabell
 mysql_connect("$host", "$username", "$password")or die("Kan inte ansluta till databasen");
 mysql_select_db("$db_name")or die("Kan inte välja datatabellen");

Vi försöker att ansluta till MySQL servern och välja rätt databas med de uppgifter vi angett.

// Alla olika variabler som skall läggas in i databasen när eleven sparar resultatet
 $elev_id=0;
 $larar_id=0; //Här kan du fylla i ditt eget id direkt, om du vet om det
 $provnamn='ProvWW2';
 $provkommentar = 'Orättat'; //Här skriver du till eleven, poäng på prov osv, men inte nu
 $resultat = 'Orättat'; //Här skrivs resultatet, men inte nu.
 $datumgjort = date('Y-m-d H:i:s');
 $datumraettat = 'Orättat'; //Detta ändras när du rättat provet

De här variablerna är sådana som inte ändras beroende på vad användarna gör. Datumkoden är litet speciell, den skriver år-månad-dag timme:minut:sekund vid det ögonblick som sidan visas. Det innebär att om eleven tar en timme på sig att göra provet kommer tiden att vara en timme fel. För att undvika det kan man flytta ner tidsberäkningen till alldeles efter det att man lägger in texten i databasen istället (se nedan).


//Har man tryckt på knappen?
 if($_POST['formSubmit'] == "Spara")
 {
 $elev_fnamn=$_POST['elev_fnamn'];
 $elev_enamn=$_POST['elev_enamn'];
 $elev_hemligt=$_POST['elev_hemligt'];
 $elev_klass=$_POST['elev_klass'];
 //Skulle kunna skrivas som $elev_klass = '8A' om alla är i samma klass
 //Men då skulle det ligga utanför knapphändelsen

 //Elevens olika svar
 $S1=$_POST['elev_svar1'];
 $S2=$_POST['elev_svar2'];
 $S3=$_POST['elev_svar3'];
 $S4=$_POST['elev_svar4'];
 $S5=$_POST['elev_svar5'];
 $inskickat = 'true';
 }

Om man tryckt på submitkanppen som har namnet Spara (man kn ha flera knappar i ett formulär) så sparas det eleven skrivet i de olika fälten i olika variabler. Det eleven t.ex. skrev i förnamnsfältet, som har namnet elev_fnamn, sparas som variabeln $elev_fnamn. Namnet på fältet finns angivet i html-koden och variablens namn har jag hittat på själv.

$inskickat är en variabel som helt enkelt avgör om du skickat in formuläret eller inte. Det är alltid falskt (fasle) när sidan först visas och blir sann (true) efter det att man tryckt på spara-knappen minst en gång. Detta görs för att man inte skall spara ett tomt, ogjort prov i databasen. Glöm inte att kapsla in allt mellan två måsvinge-tecken { kod här }


 else
 {
 $elev_fnamn='förnamn';
 $elev_enamn='efternamn';
 $elev_hemligt=; //OBS! wiki:n tar bort koden för två enkla citattecken
 $elev_klass='klass';

 //Elevens olika svar
 $S1='Svar:';
 $S2='Svar:';
 $S3='Svar:';
 $S4='Svar:';
 $S5='Svar:';
 $inskickat = 'false';
 }

Variablerna får inte vara tomma, det ger otäcka fel. Därför måste vi också fylla i vad variablerna innehåller för värden om man INTE tryckt på någon knapp. Observera att det är exakt samma variabler i denna kod som i koden för om man tryckt på en knapp.

Två enkla citattecken i rad visar att inget skall fyllas i, tyvärr är det också ett sätt att visa kursiv stil i en wiki (som det här är) så de försvinner. Där det står ” OBS! wiki:n tar bort koden för två enkla citattecken ” skall det alltså egentligen stå två enkla citattecken, men du ser det bara om du väljer ”visa wikitext” längst upp.


$elevsvar="Svar1<br>".$S1."<br>Svar2<br>".$S2."<br>Svar3<br>".$S3."<br>Svar4<br>".$S4."<br>Svar5<br>".$S5."<br>";

Sedan gäller det att lägga ihop alla fem (eller fler i andra prov) elevsvaren i en enda variabel ($elevsvar). Som jag sa tidigare, detta är ett enkelt sätt att ha växlande antal frågor i olika prov som utgår ifrån samma mall.

I php lägger man ihop två texter genom att placera en punkt mellan dem. Ett enkelt exempel:

$rad1 = ’hej ’;
$rad2 = ’du’;
Echo $rad1.$rad2  //ger: hej du

Som du ser i koden sparar vi varje svar genom att lägga till Svar1 (för svar ett) i början så att det är enklare att se vad eleven svarat på för fråga, samt en radbrytning i slutet så att varje svar börjar på en ny rad när det är dags att rätta dem.


$Q1="1: Vad var orsaken till Tysklands och Polens ovänskap?<br>";
$FACIT1="E=Man hade ofta bråkat om gränserna.<br>
(osv.)

Här ger jag varje fråga en egen variabel, och varje svar en egen variabel. Detta för att det skall gå lätt att visa upp stora textstycken på rätt plats genom att bara ange variabelnamnet.


$facit= $Q1."<br>".$FACIT1."<br>".$Q2."<br>".$FACIT2."<br>".$Q3."<br>".$FACIT3."<br>".$Q4."<br>".$FACIT4."<br>".$Q5."<br>".$FACIT5;

Precis som med elevens alla svar lägger jag ihop alla frågor med de korrekta svaren i en enda variabel ($facit) så att det skall gå lätt att visa upp hela provet inklusive facit för eleverna (och deras föräldrar). Hur man skapar en provvisare kommer jag till längre fram.


//Rensa bort alla ovälkomna tecken i ingående text
 $elev_fnamn= rensatext($elev_fnamn);
 $elev_enamn= rensatext($elev_enamn);
 $elev_hemligt= rensatext($elev_hemligt);
 $elev_klass= rensatext($elev_klass);
 $facit=rensatext($facit);
 $elevsvar=rensatext($elevsvar);

Innan texten läggs in i databasen rensatr vi den med vår funktion som finns i toppen av dokumentet så att inga backslash, citattecken eller enkelt citattecken avsiktligt eller av misstag kommer med och förstör möjligheterna att spara texten i databasen.

Skulle du titta på hur texten ser ut nu kommer du att märka att det finns en backslash framför alla enkla- och dubbla citattecken, men också där alla radbrytningar är. Om du visar upp texten i en textruta ser den fin ut, men om du skriver ut den rakt i dokumentet ser det värre ut då t.ex. alla radbrytningar markeras med backslash och ett n. Oroa dig inte, det finns funktioner för att återställa texten som t.ex. nl2br($text); som förvandlar alla radbrytningar till <br> tecken istället.


//Spara provet
if ($inskickat=='true')
{
$sql="INSERT INTO simpeltprov(ID,ELEV_ID,LARAR_ID,F_NAMN,E_NAMN,HEMLIGTORD,KLASS,PROVNAMN,FACIT,ELEVSVAR,PROVKOMMENTAR,RESULTAT,DATUM_GJORT,DATUM_RATTAT) 
VALUES 
 (null,$elev_id,$larar_id,'".$elev_fnamn."','".$elev_enamn."','".$elev_hemligt."','".$elev_klass."','".$provnamn."','".$facit."','".$elevsvar."','".$provkommentar."','".$resultat."','".$datumgjort."','".$datumraettat."')";

Har man tryckt på knappen? Är inskickat sant (observera de dubbla == tecknen när man jämför någonting, det är lätt att göra fel).

Är det så skapar vi en text för att spara information i databasen. Först anger vi vilka datafält som skall fyllas och därefter vilka värden som skall in i fälten. Egentligen behöver man inte ange namnen på fälten, men det är inte fel att fylla i dem eftersom det underlättar felsökning om det strular till sig, vilket det ofta gör. Värdena som man skickar till databasen skall ha enkelt citattecken före och efter om det är text, men inga enkla citattecken om det är siffror. Det är ofta jag misslyckas här när jag endera glömmer ett citattecken någonstans eller en punkt, då blir sidan bara helvit utan några tecken på alls ch det är bara att börja felsöka textraden.


  $result=mysql_query($sql);
  if($result){
  echo "Provet är Sparat i databasen"; //Det gick bra
  }else{
   echo "<b>FEL!</b> ditt prov sparades inte."; //Det uppstod något fel
   }
 }

Sedan kommer slutet av php-satsen. Hela textraden heter $sql och vi ser om det lyckas med $result. mysql_query($sql); innebär helt enkelt att vi försöker att köra textraden mot MySQL databasen. Fungerade det att spara? Fint, då skrivs det ut allra längst upp på sidan. Blev det något fel? Då skrivs även det ut. All text sparas dock i hemsidans textrutor så om det uppstår ett fel får du be eleven kopiera texten, ruta för ruta, i ett word-dokument och skicka in det till dig på annat vis.


?>

Slut på all php som behöver skrivas innan sidan visas.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="sv-SE">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Prov om 2:a världskrigets utbrott </title>
</head>
 
<body>

Den text som behövs för att tala om för Google Chrome, Firefox eller liknande program att en hemsida skall visas.


<form name="form1" method="post" action="ww2start.php">

Här börjar ett formulär. Det skall postas när man trycker på en submitknapp och det skall postas till sig själv. Konstigt? Nej, egentligen inte. Det underlättar en hel del om man postar formulären till sig själv eftersom man kan bibehålla värdena i alla textrutor på ett enkelt sätt även om man tappar kontakten med databas-servern.


 <h2>Prov om andra världskrigets utbrott</h2><br><br>
 <b>Förnamn</b><br>
 <input name="elev_fnamn" type="text" value=
 <?=$elev_fnamn;?>><br>
 <b>Efternamn</b><br>
 <input name="elev_enamn" type="text" value= 
 <?=$elev_enamn;?>><br>
 <b>Klass</b><br>
 <input name="elev_klass" type="text" value=
 <?=$elev_klass;?>><br>

 <b>Hemligt ord (syns inte)</b><br>
 <input name="elev_hemligt" type="password" value=
 <?=$elev_hemligt;?>><br>

Här fyller eleven i alla uppgifter om sig själv. ”name=” måste vara med för att php skall kunna hantera informationen från fälten. Man kan fylla i ett fast värde, eller ange att den i förväg skall innehålla värdet av en variabel. Förnamnet har t.ex. value= <?=$elev_fnamn;?> vilket innebär att det står "Förnamn" i rutan innan eleven skrivit ett eget namn, och efter att formuläret sparats står elevens förnamn där istället.

Grundregeln för databashantering är att användaren skall skriva så litet som möjligt för att undvika att det blir fel i databasen. Vad händer om vissa elever skriver ”8A”, andra ”8 A” andra ”8a” och vissa ”8an”? För MySQL är detta fyra olika klasser. Då är det bättre att ha en fast variabel ”$klass=’8A’; i början av dokumentet. Samma sak med elevnamnen, kan du så dra den informationen ur elevdatabasen och låt eleverna klicka på sitt namn i en lista istället. Jag går igenom hur det går till längre fram.


Under detta kommer instruktionerna och sedan:

<?php
 
echo $Q1."<br>";
echo "<textarea  name=\"elev_svar1\" rows=\"10\"   cols=\"76\">$S1</textarea><br>";
echo $Q2."<br>";
echo "<textarea  name=\"elev_svar2\" rows=\"10\" cols=\"76\">$S2</textarea><br>";
echo $Q3."<br>";
echo "<textarea  name=\"elev_svar3\" rows=\"10\" cols=\"76\">$S3</textarea><br>";
echo $Q4."<br>";
echo "<textarea  name=\"elev_svar4\" rows=\"10\" cols=\"76\">$S4</textarea><br>";
echo $Q5."<br>";
echo "<textarea  name=\"elev_svar5\" rows=\"10\" cols=\"76\">$S5</textarea><br>";

?>

Här skrivs enkelt alla frågorna in och en textruta för varje svar kommer med. ”cols=” avgör hur bred textrutan är och ett A4 papper tar ungefär 76 tecken. Om du däremot skapar prov för iPads eller iPhones/andrid kan du göra textrutorna smalare och högre. ”rows=” visar hur många textrader som syns i textrutan, men man kan skriva många fler rader än så.


<br>
<input type="submit" name="formSubmit" value="Spara" />
</form>

Slut på php och sedan knappen man trycker på. Sedan avslutas formuläret. Om man har olika knappar kan man ge dem olika namn. Det finns en hake här, om eleven klickar på ENTER tangenten istället i någon annan ruta än ett textfält kan det hända att sidan förnyas utan att knappen tryckts in, vilket i värsta fall innebär att allt eleven gjort går förlorat. Därför bör du aldrig skapa ett prov med svarsrutor först och rutor för namn osv. sist. Var noga med att poängtera för eleverna att de måste trycka på knappen i slutet.


</body>
</html>

Och här avslutas sidan.


Som sagt, det ser mastigt ut, och det kanske inte är det allra enklaste, men med det här provet som mall kan du tillverka precis hur många databasdrivna prov som helst. Nu har jag inte lagt till något ”lullull” alls som bilder, ljud eller film, utan det är sådant du kan göra för att få provet att se mer tilltalande ut.