Snö på åker, och lite vårsol
Karin hade kommit hem från träningen. Det var lite vårsol kvar ute även om den var på väg ner. vi tog tillfället i akt att gå lite på åkern nedanför huset.
1. Den vy vi är vana att se av Salsa’n
2. Selma utan grimas
1. Såhär glada var Karin och Salsa att se varandra efter flera timmar isär
2. Karin var också glad att träffa Selma
1. Såhär fin utsikt har man om man går långt nere på åkern och vänder sig mot havet.
2. Salsa får springa av sig lite. Försökte få någon action-bild även av Selma, men det är av någon anledning lite svårare…
1. Så mycket naturligare än såhär är svårt att få Salsa.
Begav mig lite tidigare från jobbet i fredags…
och fick klämt av några bilder utmed varbergs strand-promenix. Nu är det ju nästan något ljus någonstans om kvar om man slutar några timmar för tidigt. YAY!!!
Världens sötaste flickvän och hund. (Vovven har inte alltid det där uttrycket dock)
Eftersom jag inte införskaffat någon ministudio än…
… så får man ju passa på när man hittar ett fönster med lite soljus genom
Litet stativ är bra att ha.
synd att jag inte har det…
Ska se om jag eventuellt pillar lite i photoshop senare ikväll för att kolla om man kan spexa lite. Men än så länge straight out of camera!
Ljus och skuggor är sponsrat av fönster och blomma. Bakgrund är, svart = Min dator, vitt = en räkning från GodEl och blåa = ett överblivet hörn på ett cardstock.
Fick klippa denna dock, så bara för att testa…
1. Försökte få tjockleken på klistermärket på min dator…
2. Skugga på bordet. Blomma som står i fönstret. Denna är med lite i alla bilder, tänkte bara förklara vad det var. ![]()
Här kommer 2 bilder på ett usb-minne. Ligger på min slaptop. Notera på bild 2 hur smutsigt det är. Straight out of pocket!!
Svarta saker på svart var inte så spännande. Så hämtade en kaka. Kakan åts sedan upp.
En fast 13mm’s nyckel som jag glömt i avloppet för tvättmaskinen senast jag rensade där… Absurt ospännande bilder och har ingen aning om varför jag lade upp dom…
Ja, leo har bitit i min hörlurs-propp… Men vad ska man göra?
Karin och hennes mamma hade varit på pelargon-festival. Så fort dom gick ut för att fortsätta sin shopping-festival i nästa stad började jag rycka blommor…
Karin: Jag tog bara skadade
Datorn är inte dammig! Den är faktiskt svart-metallic. (det gäller även ovanpå bokhyllan…).. Tänk om jag tagit bild 2 några millimeter till åt sidan så man kunde ha en liten liten svart kant till vänster också…
PHP och lite ajax
Tänkte skriva lite bas om php och ajax. Men blir lite moral-predikan först.
När man handskas med saker som t.ex. ajax/javascript, flash, upplösning osv så får man tänka igenom några saker.
Låt oss säga att vi ska göra det vi ska göra i detta exemplet, ett formulär som vi sedan använder ajax för att skicka iväg för att vi inte vill att sidan ska ladda om när man klickar på Posta.
1. Är vi säkra på att målgruppen för sidan kommer ha möjlighet att köra ajax? Många skolor och stora företag stänger av javascript och dylikt ur säkerhets-synpunkt då man t.ex. via javascript kan exekvera filer osv på klient-maskinen. Men även kanske andra saker så som mobiler, webläsare (lynx kanske) osv. Här kan vi dra en parrallell till optimal upplösning för hemsidor. Gör vi en hemsida för gamers så vet vi att dom ganska troligt sitter med skärmar på 21” osv, medan om vi gör en hemsida om chai-latte kanske får anpassa sidan till iphone eller en macbook 13”-15”.
2. Har vi en backup-lösning för dom som inte har ajax
3. Tillför ajax/javascript så mycket att det är nödvändigt?
Åter till ämnet, vi ska göra ett formulär som vi postar och får tillbaka svar från utan att ladda om sidan. Väldigt smidigt då man kan göra svars-filer som ligger helt bakom i php osv och man behöver inte göra en sida som hanterar post-resultatet.
Till detta ska vi använda prototype.js biblioteket från prototypejs.org. Jättestort bibliotekt och hur mycket bra som helst. Deras hemsida hittar du här och biblioteket kan du ladda ned här
Spara denna i din sedvanliga includes mapp i ditt nya webb-projekt på din server. Under rooten skapar vi en index.html. I den stoppar vi sedan följande:
<html>
<head>
<script type="text/javascript" src="includes/prototype.js" />
<script type="text/javascript">
function send() {
new Ajax.Request("includes/post.php",
{
method: 'post',
postBody: 'text='+ $F('text'),
onComplete: result
});
}function result(req){
$('show').innerHTML= req.responseText;
}
</script>
</head><body>
<form id="test" onsubmit="return false;" action="">
<input type="text" name="text" id="text" >
<input type="submit" value="Posta" onClick="send()">
</form>
<div id="show"></div>
</body>
</html>
som du ser uppifrån så har vi inkluderat prototype.js. Vi skapar ett javascript som gör ej Ajax.Request (funktion i prototype.js som gör förfrågningar). I Request-funktionen så får vi deklarera en method (post), postBody som då är vad vi har för olika fält, i detta fallet har vi bara ett fält, Text. Vi avslutar med vad som ska hända när vi har skickat, vad vi gör med resultatet från filen, onComplete. Där sätter vi en funktion som vi döper till result som vi deklarerar nedanför. Som helt enkelt sätter innehållet i diven show till out-puten av post.php. Låter självklart va?
Så nedanför har vi skapat ett enkelt formulär, skillnaden är att vi har en onsubmit=”return false” Vad den gör är att den hindrar en traditionell postning av formuläret, med omladdning och allt. Och på submit-knappen har vi en onClick=”send()” som kallar på vår java-funktion. Detta innebär ju att du inte behöver ha en submit-knapp överhuvudtaget. det behöver man ju inte normalt heller då man kan trigga en submit i javascript, men det är ett sidospår.
När man normalt trycker på en submit så utförs en method mot action, t.ex. post mot includes/post.php. Post.php har då tillgång till en post-array $_POST som innehåller allting som finns i vårt formulär. Nu utför vi faktiskt ingen riktig postning, så ingen sådan post-buffert kommer att skapas. Därför vi i ajax:en får skapa en egen post-buffert där vi stjäl värdena från formuläret genom kod istället.
includes/post.php ser ut som vilken formulär-mottagare som helst. Den kan uppdatera sql osv osv. Vi behöver inte det, vi returnerar bara ut strängen.
<?php
if($_POST["text"] == "")
echo "du skrev inget";
else
echo "du skrev: ".$_POST["text"];
?>
Om vi sedan kör index.html så kan det se ut enligt följande
Och här kan vi posta om och om igen utan att sidan laddas om.
Testa att lägga formuläret inne i show diven för att se hur innerhtml fungerar.
Vad ska man då ha detta till? hmm… säg att vi har en funktion som laddar data från mysql in i en tabell, och så vill vi kunna sortera. Då skulle man kunna köra sortering fram och tillbaka uppifrån och ned utan att varje gång ladda om hela sidan och tappa positionen man hade på sidan osv.
Jag använde det t.ex. till http://url.ka-os.se/index.php för att skapa en bättre skapning av ny kort länk.
Sammanfattning av alla A-Team avsnitt
Har kollat på A-Team igen, första gången sedan jag såg dom första gången på –90-talet (repris). Dom hade verkligen inte mycket att spela på hur ett avsnitt skulle se ut.
- Någon har problem och ska kontakta dom mystiska A-Team. Vi blir presenterade för skurkarna. Ofta mexikanska, ingen agenda utan dom bara super och slåss och är kompis med polisen.
- Hannibal har klätt ut sig till något för att se om den som vill ha hjälp är värdig att hjälpa. Ger honom en lapp med en plats och tid. Här gör gärna Murdock något dumt eftersom han är helt galen.
- Hannibal har klätt ut sig för att kunna föra personen i fråga till resten. (som brukar stå bakom någonting.
- Militär-polisen gör ett gest-framträdande, kort biljakt.
- Dom åker en sväng, gärna få med BA upp i ett plan genom att söva honom.
- Dom slåss med skurkarna. Gör skurkarna arga så att dom samlar ihop män som ska slå på A-Team.
- BA bygger ett bepansrat fordon. Face charmar en tjej för att få ihop delar.
- Dom åker runt och skjuter på saker i sitt bepansrade fordon. Dom träffar ingenting, ingen dör, en bil kör in i ett träd på sin höjd.
- Skurkarna ger plötsligt upp eftersom A-Team har så häftigt bepansrat fordon.
- Hannibal säger “I love it when a plan comes together”.
- Dom åker hem, helst måste dom söva BA eftersom “I ain’t getting on no plane!”
Nästa vecka se punkt 1
Hur får man en sådan där kort url?
Har du en lång och ful url och vill skicka över en kortare variant. Använder du http://www.shorturl.com/ ? Undrar du hur dom gör det? Nu ska du få veta.
Vi kommer att skapa lite filer och en databas och snart vara igång.
Jag kommer köra från en mapp som heter KortUrl i min xampp-installation. Så min bas-url kommer vara http://localhost/KortUrl
Det första vi gör är att skapa en databas och en tabell. Så här kommer lite sql-kod
CREATE DATABASE `shorturl` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `shorturl`;CREATE TABLE IF NOT EXISTS `links` (
`l_id` int(11) NOT NULL AUTO_INCREMENT,
`l_url` varchar(500) NOT NULL,
`l_title` varchar(500) NOT NULL,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`l_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1
Så här skapas en databas som heter shorturl och en tabell som heter links i den. Links innehåller 1 id, url:en som vi vill länka till. title som ska innehålla titeln på sidan vi länkar till. samt ett “skapat” datum
Skapa en .htaccess-fil först. så att vi kan göra så kort länk som möjligt.
Den får se ut som följande:
RewriteEngine on
RewriteRule ^([a-zA-Z0-9_-])$ includes/loadUrl.php?lid=$1
Vad som händer är att om jag knappar in http://localhost/KortUrl/1 kommer den att köra http://lovalhost/KortUrl/includes/loadUrl.php?lid=1
Så i loadUrl kommer vi ha tillgång till $_GET[‘lid’] som vi kan använda till något roligt. 1:an är vår unika identifierare.
Vi går vidare till att skapa en index.php i rot-mappen. Den får ha följande innehåll. inget direkt komplicerat
<?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>Korta URL:er</title>
</head>
<body>
<h1>Skapa din korta URL</h1>
<form method="post" action="includes/addLink.php">
<label>Länk: <input type="text" name="l_url"/></label><br>
<input type="submit" value="Skapa kort länk"/><input type="reset" value="rensa"/>
</form>
<?php
include 'includes/listtenlatest.php';
?>
</body>
</html>
Som vi ser i koden har vi en bra tanke om vad vi ska göra härnäst. Vi hänvisar till 3 filer som vi ännu inte har byggt. config.php, addLink.php (som ska ta hand om datat från vårt formulär), och en listtenlatest.php som är lite uppenbar.
Vi börjar med config.php som vi lägger i mappen includes.
<?php
$db_host = "localhost";
$db_user = "root";
$db_password = "";
$db_name = "shorturl";
$link = mysql_connect($db_host, $db_user, $db_password) or die(mysql_error());
?>
Nu tar vi en titt på addLink (som vi lägger i includes). Där kommer lite rolig kod.
<?php
include('config.php');
extract($_POST);
//vi kollar om vi kan få tag på sidan, annars är det onödigt att buffra massa data
if (@fclose(@fopen($l_url, "r")))
{
$file = file($l_url);
$file = implode("",$file);
// vi letar i "filen" efter <title> taggarna. Och stjäl det emellan. Sätter $l_title till det
if(preg_match("/<title>(.+)<\/title>/i",$file,$m))
$l_title = $m[1];
}
else
$l_title = $l_url;mysql_select_db($db_name,$link);
$sqlInsert = "insert into links (l_url,l_title) values ('$l_url','$l_title')";
mysql_query($sqlInsert,$link) or die(mysql_error());
$last_id = mysql_insert_id($link);$message = "<h1>Din nya länk är <a href='../$last_id'>http://localhost/KortUrl/$last_id</a></h1>";
$message .= "<p>Din långa url var:<br> <i>$l_url</i></p>";
echo $message
?>
Så här letar vi upp titeln på sidan. Kopplar sidan url till ett id. Som vi sedan kan leta upp i loadUrl.php. Men först tar vi listtenlatest.php som vi också har i includes.
Här rapar vi helt enkelt upp dom 10 senaste länkarna och presenterar dom med kort länk, lång länk och titel.
<?php
mysql_select_db($db_name, $link);
$sqlTenLatest = "select * from links order by l_id desc limit 10";
$result = mysql_query($sqlTenLatest,$link) or die(mysql_error());$num_rows = mysql_num_rows($result);
if($num_rows >0)
{
$rows = mysql_fetch_array($result) or die(mysql_error());
do
{
extract($rows);
$link = "<p>$l_title<br>$l_url<br><i><a href='/$l_id'>http://localhost/KortUrl/$l_id</a></i></p>";
echo $link;} while($rows = mysql_fetch_assoc($result));
}
else
{
echo "<h1>Kom igen, skapa första länken!</h1>";
}
?>
Om vi nu går in på index.php så får vi kanske följande om vi har matat in några länkar:'
Klickar vi nu på någon av våra korta länkar måste vi ju ta hand om händelsen. Så nu kollar vi på includes/loadUrl.php.
<?php
include 'config.php';
$lid = $_GET['lid'];
mysql_select_db($db_name, $link);
$sqlLink = "select * from links where l_id='$lid' limit 1";
$res = mysql_query($sqlLink, $link) or die(mysql_error());
$numRows = mysql_num_rows($res);
if($numRows == 1)
{
$row = mysql_fetch_array($res) or die(mysql_error());
extract($row);
header("location: $l_url");
}
else
{
echo "<h1>Din länk kunde tyvärr inte hittas</h1>";
}
?>
Smidigt och enkelt va? Så nu har vi hela vägen hur det går till. Hur man lägger till till hur man använder det. Så nu kan jag skicka korta länkar till mina vänner. (netonnet’s länkar är elaka i MSN då aldrig sista ) räknas in i länken)
Finns lite mer saker att ta hänsyn till i vanlig ordning. Men det är mer finlir över hur man ska skydda sin databas osv.
Bifogar filerna och sql-dump.
Man kan ju lätt utöka den här med en slumpa länk funktion t.ex. osv osv.
<?php
include "config.php";
mysql_select_db($db_name, $link);
$sqlRandom = "select l_id from links order by rand() limit 1";
$result = mysql_query($sqlRandom, $link) or die(mysql_error());
$row = mysql_fetch_array($result);
extract($row);
header("location: ../$l_id");
?>
Man kan ju även kolla om länken redan råkar finnas. Isåfall posta den gamla länken. Id behöver inte heller vara en int även om det är smidigt. Kan vara något helt annat.
PS. Någon dag ska jag skaffa ett liv istället för att skriva en guide till korta url:er en lördags-kväll DS.
PHP & MySQL Del IV
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.
Del IV skulle handla om uppdatera poster osv. Men vi börjar med att kolla på vad vi skapat hitills. När man jobbat ett litet tag och inte har planerat precis allt innan kan det hända som har hänt nu. Namnen på filerna är helt i oordning. Med lite tur har ni tänkt på detta redan innan. Vi ska kolla på vad vi har för filer.
- root
- index.php
- laggtillelever.php
- visaKlass.php
- root\includes
- config.php
- CreateDB.php
- CreateTable.php
- CreateEleverTable.php
- CreateKlass.php
- displayKlass.php
- addElev.php
Vad är det då för soppa jag menar? CreateTable skapar en tabell i en databas. CreateKlass.php lägger till en post i databasen. laggtillelever kallar på addelev. displayKlass.php hör ihop med index.php. Dessutom så har visaKlass.php inget med displayKlass.php att göra. Vi har fått en jättesoppa och när man arbetat ett tag med projektet så kommer det bli väldigt förvirrande. Laggtillelever.php påpekar dessutom elever i plural. Jag gör om mitt enligt följande. Kom ihåg att ändra i filerna som kallar på varandra.
- index.php
- nyelev.php
- visaklass.php
- config.php
- CreateDB.php
- CreateTable.php
- CreateEleverTable.php
- nyklass.php
- visaklasser.php
- nyelev.php
Vi bryr oss inte om Create-filerna. Dom är ju bara engångs-filer. Vi har nu namn på svenska som är mer enhetliga och som beskriver vad filen gör. Är kanske inte perfekt, men bättre.
Så efter att ha bytt namn och uppdaterat i filerna så dom pekar rätt så ska vi nu börja med att uppdatera lite elever. Vi börjar med att lägga till ett fält i databasen. Skapa en fil som heter ModifyElever (vi följer namnstandard för engångs-filerna
).
Vi kom ju på att det är bra att ha med om eleven är pojke eller flicka av någon anledning.
Den ser ut enligt följande:
<?php
include 'config.php';
mysql_select_db($db_name,$link);
$sqlModifyTable = "ALTER TABLE `elever` ADD `elev_kon` ENUM( 'pojke', 'flicka' ) NULL AFTER `elev_far` ";
$result = mysql_query($sqlModifyTable,$link);
echo $result;
?>
Vad vi också kan utläsa här är att elev_kon är en enum. Den kan alltså bara anta 2 olika värden. 1 och 0. men här översätts det till pojke/flicka. Hade vi satt den till NOT NULL hade plötsligt vår nyelev.php inte fungerat längre. Vilket är både dumt och bra. Man måste ha allting helt klart på en gång om man sätter not null. Sätter man null kan det ju slinka igenom saker som i man måste gå igenom och uppdatera senare. Men man kan skapa fältet där uppe och införa saker lite långsammare. Med not null blir det tvång eftersom det kan vara massa saker som inte fungerar efter.
Iaf. Nu har vi ett “kön” så nu får vi ju gå in och uppdatera våra elever.
Vi skapar en uppdatera.php och lägger i includes och en som vi lägger direkt i roten. Så öppnar vi den i rot-katalogen. Den ska innehålla gräns-snitt och lite till. Vi matar den så att vi hämtar elevens unika id via uppdateraelev.php?eid=”värde”. Så letar vi upp eleven i databasen. Och lägger ut informationen som vi sedan skickar i ett formulär. Senare kanske ni har ett crud, eller väljer att använda samma fil med olika parametrar från formuläret för insert, update, delete och select. Men nu håller vi isär allt för tydlighetens skull.
<?php
include 'includes/config.php';
$eid = $_GET['eid'];if($eid != null)
{
mysql_select_db($db_name, $link);
$sqlSelectElev = "select * from elever where elev_id=$eid limit 1";
$result = mysql_query($sqlSelectElev, $link);
$rows = mysql_fetch_array($result);
$numRows = mysql_num_rows($result);}
?>
<!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/>
<?php if($numRows>0){ extract($rows); ?>
<form method="post" action="includes/uppdateraelev.php">
<input type="hidden" name="elev_id" value="<?php echo $eid; ?>"/>
<input type="hidden" name="kid" value="<?php echo $klass_id; ?>"/>
<input type="text" name="elev_fnamn" value="<?php echo $elev_fnamn; ?>"/><br>
<input type="text" name="elev_enamn" value="<?php echo $elev_enamn; ?>"/><br>
<input type="text" name="elev_far" value="<?php echo $elev_far; ?>"/><br>
<label>Pojke<input type="radio" name="elev_kon" value="pojke" <?php if($elev_kon == 'pojke'){ echo "checked";} ?>/></label>
<label>Flicka<input type="radio" name="elev_kon" value="flicka" <?php if($elev_kon == 'flicka'){ echo "checked";} ?>/></label><br>
<input type="submit" value="Uppdatera elev"/><input type="reset" value="Rensa"/>
</form>
<?php } else { ?><h1>Elev ej funnen</h1><?php } ?>
</body>
</html>
Såhär ser vårt gränssnitt ut. Som sedan kallar på uppdatera elev. Här matar vi ut informationen i ett formulär. Vi hanterar också en radio-grupp här för vår enum elev_kon.
Så nu kollar vi på uppdateraelev.php som ligger i includes. Den ska se ut enligt följande:
<?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);
$sqlUpdate = "update elever set elev_fnamn='$elev_fnamn',elev_enamn='$elev_enamn',elev_far=$elev_far,elev_kon='$elev_kon' where elev_id=$elev_id";
$result = mysql_query($sqlUpdate,$link) or die(mysql_error());
if($result == 0)
$message = "<h1>Något gick fel...</h1>";
if($result == 1)
$message = "<h1>Elev uppdaterad</h1>";$message .= "<p><a href='../visaklass.php?kid=$kid'>Visa klass</a></p>";
}
$message .= "<p><a href='../index.php'>Gå tillbaka</a></p>";
echo $message;
?>
Så om du nu hoppar in på index.php och klickar runt så inser vi att vi fasiken inte kommer till våran nya fina uppdateraelev.php. Så vi får justera visaklass en aning (den i roten).
Vi ersätter
$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>";
Med:
$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 - <a href='uppdateraelev.php?eid=$elev_id'>Uppdatera elevinformation</a></td>";
$data .= "</tr>";
Nu tittar vi ju bara på elevernas namn här. Men outputen är ju inte så viktig utan hur den kommer dit i detta fall.
Nu stegar vi oss igenom vad vi gjort. Börjar med index.php
Klickar på visa elever på klas 4c eller vilken klass du nu har elever i.
Får något sånthär
Vi klickar på uppdatera elevinformation på Ollette Olsson
Ändrar till Olle som är en pojke
Klickar på uppdatera elev. Så får vi
Vi klickar på Visa klass och det går nu en olle o klassen
Del IV done and done. Vi har kollat lite på namn på filer. Uppdaterat lite data och kors-tänk för vad man ska tänka på när man skapar fält osv. Bifogar filerna och en export av databasen i en ZIP-fil
PHP & MySQL Del III
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 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
Hos min syster
Besökte min syster och tänkte hjälpa till med försäkringar. Man ska ta detalj-foton på viktiga saker man har.
PHP & MySQL Del II
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.
Så nu ska vi göra ett formulär så att vi kan fylla på vår databas. Och vem vet. Kanske något sätt att söka. Men först lite ordning och reda. Först skapar vi en mapp som vi döper till “includes” (för filer vi kommer inkludera). I den mappen lägger vi CreateKlass.php,displayKlass.php, config.php. CreateDB.php har vi använt oss färdigt av och den kan man ta bort eller spara på ett bra ställe. Likaså med CreateTable.
Nu ska vi börja skapa våran fil med ett formulär. Vi lägger den i root-katalogen och låter den heta t.ex. index.php eller något sådant bra.
Där skapar vi ett grovt tillhyxat fult formulär. Så att filen ser ut enligt följande
<?php
//vi includerar vår databaskoppling här så att vi har den i framtiden
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>
<form method="post" action="includes/CreateKlass.php">
<label>Klassnamn: <input type="text" name="klassNamn"/></label><br/>
<label>Årgång: <input type="text" name="argang"/></label><br/>
<label>Antal elever: <input type="text" name="antalElever"/></label><br/>
<input type="submit" value="Lägg till Klass"/><input type="reset" value="Rensa"/>
</form>
</body>
</html>
Som du ser så sätter vi CreateKlass som action på formuläret. Det innebär att man kommer att kalla på CreateKlass.php med datan i formuläret. Så nu får vi skruva lite på CreateKlass så att den tar emot datan. Datan kommer i en array som heter $_POST när man skickar från ett formulär. Man kan även inkludera insert-metoden och ha en if-sats på den att om $_post innehåller något som kör. Men jag försöker alltid separera html och php visning och funktion så att man också så lätt som möjligt kan återanvända delar. Model View Model kallas modellen för hur man lägger upp sitt arbete. Jag följer tanken men kanske inte hela sättet.
Så efter lite ombyggnad har vi en CreateKlass.php som ser ut enligt följande
<?php
include 'config.php';
mysql_select_db($db_name, $link);//vi skapar parametrar för datan vi stoppar in
// $_POST innehåller vår data från formuläret. inom [] anger vi namnet på fältet som vi skickar.
$klassNamn = $_POST['klassNamn'];
$argang = $_POST['argang'];
$antalElever = $_POST['antalElever'];//vi vill att all data ska vara ifylld för att vi ska stoppa in det i databasen
//Vi ställer därför vilkor med if() functionen
//Man kan även kolla detta med ett javascript innan man skickar
if($klassNamn && $argang && $antalElever)
{
// Nu ska vi skapa våran fråga
$sqlInsert = "insert into klasser (klassNamn,argang,antalElever) values('$klassNamn',$argang,$antalElever)";
//vi sätter resultatet av vår fråga till parametern $res. Vid en insert får man tillbaka 1 om det gått bra, annars 0.
$res = mysql_query($sqlInsert, $link) or die(mysql_error());
//Vi måste ju ha möjlighet att veta att allt gått rätt samt komma tillbaka.
$message = "<h1>Klass Tillagd</h1>";
}
// Vi måste ju hantera om något är fel också.
else
{
$message = "<h1>något gick fel</h1>";
//Det är bra att ge info om vilket fält som var tomt
if(!$antalElever)
$message .= "<br>Du hade inte fyllt i antal elever";
if(!$argang)
$message .= "<br>Du hade inte fyllt Årgången";
if(!$klassNamn)
$message .= "<br>Du hade inte fyllt något klassnamn";}
$message .= "<br><a href='../index.php'>Tillbaka</a>";
echo $message;
?>
Detta är ju en grov väldigt basic tutorial. Senare så måste man skydda sig mot fula inmatningar. Vad blir resultatet om någon t.ex. fyller i <h1>3a</h1> som klassnamn? Testa och kolla (displayKlass.php).
är ju inte så roligt….
Detta kan du läsa lite mer om i “Hjälp! någon Lägger in fula saker i gästboken (länk)”
Vi vill ju också validera och kolla så att det som är i antalElever och argang är numeriska värden.
Så nu har vi en fil som har ett formulär. Vi kan fylla i det och få bekräftat att det hamnat i databasen eller gått fel. Om vi skulle ordna så att vi ser vår data lite prydligare.
Under formuläret i index.php lägger vi till att inkludera includes/displayKlass.php.
Så att dom sista 4:a raderna blir
</form>
<?php include 'includes/displayKlass.php'; ?>
</body>
</html>
Sedan öppnar vi displayKlass.php. Som vi ska göra om en hel del. Vi ska skapa en tabell som vi lägger in våra klasser i.
<?php
mysql_select_db($db_name, $link);
//vi skapar en fråga
$sqlSelect = "Select * from klasser";$result = mysql_query($sqlSelect, $link) or die(mysql_error());
//vi stoppar in vårat resultat i en array, så blir den enkel att använda
$rows = mysql_fetch_array($result);
//mysql_num_rows kollar hur många poster vi hittade i vår fråga
$num_rows = mysql_num_rows($result);
//Det är dumt att göra något utan rader
if($num_rows > 0)
{
$table = '<table>';
$table .= "<tr style='background-color:black; color:white;'><th>Klassnamn</th><th>År</th><th>Antal elever</th>";
//Nu ska vi slänga ut raderna i webb-läsaren. Detta kan man t.ex. göra med en do-while loop
do
{
//jag brukar vara bekväm och göra en extract på min array. Det innebär att det skapas enskilda parametrar för allt i array:en.
//t.ex. $rows['klassNamn'] blir $klassNamn. Bra när man inte har allt för mycket parametrar
extract($rows);
$table .= "<tr>";
$table .= "<td>$klassNamn</td>";
$table .= "<td>$argang</td>";
$table .= "<td>$antalElever</td>";
$table .= "</tr>";
}while($rows = mysql_fetch_assoc($result));
$table .= "</table>";
echo $table;
}
else
{
echo "<h1>Inga klasser än</h1>";
}
?>
Outputen för stunden är ju inte så smickrande. Men visst har vi nått vårat mål?
Bifogar för säkerhets skull filerna såhär långt i en zip-fil
Kolla så sakerna hamnar rätt när du zippar upp bara.
I Del III ska vi skapa elever och hänga ihop dom med klasser. Så det kommer bli repetition på det vi gjort i denna delen samt lite till.