Arkiv

Arkiv för ‘PHP’ Kategori

form method get eller post?

juli 26th, 2010 rejser Inga kommentarer

Om du har gjort ett formulär i html någon gång så har du säkerligen sett raden

<form method=”post” …>

Det var länge i början som jag bara skrev så och accepterade att man helt enkelt skrev så när man hade med formulär att göra. Speciellt method=”post”. Kom på idag under ett samtal med en kompis som liksom jag, gör lite för skojs skull ibland, fast lite mer sällan, att det inte är självklart. Och absolut inte självklart när man ska använda vad och varför.

Kort och gott finns det 2 alternativ när det gäller method i en form, Post och Get. Men vad är skillnaden? Vad händer när man klickar på submit-knappen på dom?

Vi har ett formulär som är väldigt enkelt.

<form method=”post” action=”dennafil.php”>
<p><label>Förnamn: </label><input type=”text” name=”fnamn” /></p>
<p><labe>Efternamn: </label><input type=”text” name=”enamn” /></p>
<p><input type=”submit” value"=”skicka” />
</form>

2 fält, förnamn och efternamn, och en skicka knapp. Jättenkelt.
Vad som sker när man klickar på skicka, lite förenklat, är att man skapar en publik post-buffert som man hanterar som en array. Därför ska vi kolla också hur dessa arrayer ser ut.
Här nedan visar jag hela min dennafil.php

<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test-fil</title>
</head>

<body>
<form method="get" action="dennafil.php">
<p><label>Förnamn: </label><input type="text" name="fnamn" /></p>
<p><labe>Efternamn: </label><input type="text" name="enamn" /></p>
<p><input type="submit" value"="skicka" />
<p>
$_POST:<br>
<?php print_r ($_POST); ?>
</p>
<p>
$_GET:<br>
<?php print_r ($_GET); ?>
</p>
</form>
</body>
</html>

Som ni ser har jag 2 olika print_r. Print_r står för print array. Så den skriver ut hela arrayen.
Passande här har jag en array som heter $_POST och en som heter $_GET.
Hmmm… Jag kör nu min fil 2 gånger. 1 gång med get i method och en med post så vi kan se vad som skiljer.

get1 post

Men va fasiken, ser ju likadant ut?
Kör jag Post och echo $_POST[‘fnamn’] så får jag Olle, och om jag kör $_GET[‘fnamn’] tillsammans med method Get får jag Olle…

Det finns faktiskt en markant skillnad. Efter att jag klickat Skicka fråga i get-varianten så händer något i adress-fältet.
get2

Våra fältnamn och inmatningar hamnade där uppe.
Faktum är att $_GET hämtar alltid parametrar från adress-fältet. Oavsett om dom kommer från ett formulär eller inte. Första parametern kommer efter ? och sedan avgränsar man parametrarna med &.
Men nu är det inte parametermatning till php som är frågan. Men vi har lite föklaring vad skillnaderna är. Den ena skapar en osynlig post-buffert som är svår att skapa utan formulär. Den andra gör en “synlig” buffert kan man säga.

Är du helt klar på allt nu? Kan jag sluta skriva?

Struntar jag i, fortsätter ändå.

När ska man då använda vilken?

Vi tar två övertydliga exempel.
Vi börjar med en inloggning, tänk om man kör den med Get, kan man få följande i adress-fältet.
get3 
Kanske inte är riktigt bra om vi ska vara ärliga. Där är nog den hederliga gamla POST mycket bättre.

Typ-exempel för GET måste nog ändå vara en sökning.
Man har ett fält där man matar in sök-ord. Sedan klickar man på knappen och länken blir typ

get5

Sedan kanske man har länkar för att kunna sortera resultaten osv på olika saker. Man kanske ska kunna sortera på namn, datum osv. Då kan man helt enkelt lägga på länkar där man stoppar in några extra get-parametrar genom kod.  Som här nedan där vi söker på “Hej Hopp”, och lagt till $_GET[orderby] som säger date (kanske är ett databas-fältnamn), och sedan $_GET[sortorder] där vi här nedan har desc för descending.
get4

Detta skulle göra det väldigt enkelt att bygga en fråga till databasen, samt göra det tydligt vad dom söker på t.ex.

Så, nu är det bara att sätta igång och testa för glatta livet!

Categories: PHP, Web Taggar:

PHP array sortering och hantering

juni 9th, 2010 rejser Inga kommentarer

Jag stod häromdagen inför ett problem, och problem måste ju lösas. Jag hade en tabell i en mysql data-bas som såg ut enligt följande ungefär.

Startnr
(d_Startnr)
Namn
(d_Namn)
Klass
(d_klass)
Klubb
(d_klubb)
Res.1 (r_t1) Res.2
(r_t2)
Res.3 Res.4 Res.5 Res.6
26 Oscar Junior   34 54 23 25 54 50  

Helt enkelt en resultat-tabell från en serie tävlingar. Nu är det så att om det var 6 tävlingar så ska man bara räkna sina 4 bästa resultat, men för att spetsa till det lite så har man genomfört 5 tävlingar är det 3 resultat som räknas. Har man genomfört 4 eller mindre är det 2 som räknas.  Genomförd tävling är en tävling med poäng

Hade jag byggt tabellen annorlunda hade det ju varit en “piece of cake”. Men justeringar när folk mailar om att dom fått 1 poäng för lite på deltävling XX hade blivit lite stökigare. Smidigt att ha allt samlat på en rad tänkte jag.
t.ex.

Startnr Namn Tävling Poäng
26 Oscar 2 54

Och lagt en rad för varje tävling i tabellen. Då hade jag ju först gjort en query mot tabellen som är gruperad på startnr, sedan hade jag i den gjort en query som whileade igenom och sedan tog limit 4, nej vänta nu.  det går ju inte. Blir ju fel om dom kört 0. Man hade kunnat ställa frågan till databasen med count(startnr) where poäng >0, och sedan tagit antal rader och subtraherat gentemot antal rader som returnerats som borde vara tävlingar…. Men det är ju inte intressant för såhär såg ju inte min tabell ut.

Ännu inget om array’s tänker du nu kanske. Lugn, det kommer.

Jag gjorde en do while-loop som snurrade på mitt register som var enligt det första exemplet. Under varje varv byggde jag upp en $resultArray där jag stoppade in alla poängerna, tävlings-id (ex. res1) som nyckel och poäng kopplat. Samtidigt som jag gjorde det räknade jag samtliga poäng som var över 0. Gjorde sedan en arsort (Array Reverse Sorting) på den vilket gjorde att arrayen nu var i fallande skala i poäng-ordning. Så i nuläget om jag hade gjort en print_r på min $resultArray så hade det blivit ungefär ([res2] => 54, [res5] => 54, [res6] => 50……)

Perfekt. Nu har jag Antal tävlingar som har mer än 0. Jag har en sorterad lista.

Nu har jag en liten if-sats som skapar en ny parameter som heter $countedComp som helt enkelt beroende på antal genomförda tävlingar får ett värde hur många tävlingar som räknas.

Jag loopar igenom min array, med en räknare denna gång. När räknaren passerar $countedComp i värde så sätter jag alla värden till “-“ för att markera att efter där så är det dom tävlingar som räknas bort. Samtidigt passar jag på att addera ihop dom som räknas till en $totalPoints.

Nu har jag en array med borträknade poäng och en variabel med totalpoäng för en deltagare. Hur gör vi nu då?

Vad vi gör är att vi snabbt skapar 2 nya arrayer. En som heter resultorder som vi kopplar ihop startnummer med totalpoängen. sedan gör vi en arsort på denna.

Den andra arrayen fyller vi med startnummer och vår resultArray ($allresults).

Sedan kan vi  använda vår resultorder för att hämta ut vår andra array i rätt ordning.

Glasklart?

Då slänger vi in en brasklapp

<?php

$klass = “Junior”;

function countTavlingar($resultArray)
{
    $x = 0;
    if($resultArray["t1"] > 0)
        $x++;
    if($resultArray["t2"] > 0)
        $x++;
    if($resultArray["t3"] > 0)
        $x++;
    if($resultArray["t4"] > 0)
        $x++;
    if($resultArray["t5"] > 0)
        $x++;
    if($resultArray["t6"] > 0)
        $x++;
    if($resultArray["t7"] > 0)
        $x++;
    if($resultArray["t8"] > 0)
        $x++;
    if($resultArray["t9"] > 0)
        $x++;
    if($x == 9)
        return 7;
    else if($x == 8)
        return 6;
    else if($x == 7)
        return 5;
    else if($x == 6)
        return 4;
    else
        return 4;   
}

function adjustArray($resultArray,$antalT)
{
    $x = 0;
    $i = 0;
    arsort($resultArray);
    foreach($resultArray as $key => $val) {
        if($x<$antalHeat)
        {
            $nollArray[$i] = $key;
            $i++;   
        }
        $x++;   
    }
    foreach($nollArray as $key => $val) {
        $resultArray[$val] = "-";   
    }
    return $resultArray;
}

function TotalPoints($resultArray)
{
    foreach($resultArray as $key => $val) {
        if($val != "-")
        {
            $total = $total + $val;
        }
    }

    return $total;   
}

function printResult($klass)
{
    $x = 0;
    include ‘Connections/conn.php’;
    mysql_select_db($database_conn,$conn);
    $sql_tavlande = ""; //vår fråga mot databasen. bara för att rappla upp resultat
    $res_tavlande = mysql_query($sql_tavlande,$conn);
    $r_tavlande = mysql_fetch_assoc($res_tavlande);
    do{
        extract($r_tavlande);
        $resultArray = array("t1" => $r_t1,"t2" => $r_t2,"t3" => $r_t3,"t4" => $r_t4,"t5" => $r_t5,"t6" => $r_t6,"t7" => $r_t7,"t8" => $r_t8,"t9" => $r_t9);
        $antalT = countTavlingar($resultArray);       
        $resultArray = adjustArray($resultArray, $antalT);
        $total = TotalPoints($resultArray);
        $resultArray['tot'] = $total;
        $resultArray['d_startnr'] = $d_startnr;
        $resultArray['d_namn'] = $d_namn;
        $resultArray['d_klass'] = $d_klass;
        $resultArray['d_klubb'] = $d_klubb;
        $totalArray[$d_startnr] = $total;
        $allResults[$d_startnr] = $resultArray;

    }while($r_tavlande = mysql_fetch_array($res_tavlande));
    //array sort reverse arsort
    arsort($totalArray);
    $i = 0;
    foreach($totalArray as $key => $val)
    {
        $boll = extract($allResults[$key]);
        $x++;
        $i++;
        if($i == 2)
        {
            echo "<tr>";
            $i = 0;
        }
        else
            echo "<tr bgcolor=’#B2DFEE’>";
        if($x == 1)
            echo "<td align=’center’><span style=’color:gold;’>$x</style></td>";
        else if($x == 2)
            echo "<td align=’center’><span style=’color:silver;’>$x</style></td>";       
        else if($x == 3)       
            echo "<td align=’center’><span style=’color:#CD7F32;’>$x</style></td>";       
        else
            echo "<td align=’center’>$x</td>";
        echo "<td>$d_startnr</td>";
        echo "<td>$d_namn</td>";
        echo "<td>$d_klubb</td>";
        echo "<td>$d_klass</td>";
        echo "<td align=’center’>$t1</td>";
        echo "<td align=’center’>$t2</td>";
        echo "<td align=’center’>$t3</td>";
        echo "<td align=’center’>$t4</td>";
        echo "<td align=’center’>$t5</td>";
        echo "<td align=’center’>$t6</td>";
        echo "<td align=’center’>$t7</td>";
        echo "<td align=’center’>$t8</td>";
        echo "<td align=’center’>$t9</td>";
        echo "<td align=’center’>$tot</td>";
        echo "</tr>";
    }
}
?>

<table>
<?php printResult(“Junior”); ?>
</table>

Vad tror ni om den rotvälskan?

Reserverar mig för något småfel i koden då det är en snabb-strippad variant av vad jag använde på riktigt.

Den riktiga var lite mer omständig att varje tävling var uppdelad i 2 poänggivande moment. Man räknas som deltagande på tävlingen om man tagit poäng i 1 av 2 moment osv. Men rensade här lite för att förenkla.

Categories: Data, PHP, Web Taggar: ,

Skapa excel-fil från php

maj 25th, 2010 rejser Inga kommentarer

Det är inte jätteovanligt att man har data i databasen som någon t.ex. behöver få ut i en excel-fil.

Enklaste är ju att skapa en komma-separerad fil (csv). Så lyfter man in den i excel.

Jag har ju en del online-anmälningar till olika tävlingar på webben och klubbarna behöver på smidigt sätt få start-listor. Smidigt om man får dom för-formaterade i excel.

Nu är det så smidigt att excel efter millennium-skiftet läser vanliga table-strukturer när man skickar ut dom. Fungerar även att sedan vidare använda på alla olika sätt i excel.

Hur gör man då? Naturligtvis ska vi gå igenom detta.

Filen kommer att ge en liten varning när man öppnar den. Men ett litet pris för att behålla koden smidig och lättarbetad. Men duger ju inte i en företags-miljö med kunder.

Vi börjar med att skapa en fil i vår miljo. excel.php känns väl passande. Här kommer allt du behöver för att komma igång. Kör du den kommer webbläsaren läsa det som en fil som heter excel.xls och fråga om du vill spara eller öppna med excel/openoffice calc/spreedsheet eller vad du nu använder.

<?php
header("Content-Type: application/vnd.ms-excel");
header("Expires: 0");
header("Cache-Control:  cache, must-revalidate");
header("Content-Disposition: attachment; filename=excel.xls");
header (‘Content-Length: ‘.filesize(‘excel.xls’));
header (‘Content-Transfer-Encoding: binary’);
header (‘Last-Modified: ‘.gmdate(‘D, d M Y H:i:s’).’ GMT’);
header (‘Pragma: public’);

?>
<html>
<head>
<title>Excel 2010</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<table border="0">
    <tr align="center" bgcolor="#FFFF00">
        <td colspan="4"><strong>Excel <?php echo date("Y"); ?></strong></td>
    </tr>
    <tr>
        <th>Förnamn</th>
        <th>Efternamn</th>
        <th>Företag</th>
        <th>Titel</th>
    </tr>
    <tr>
        <td>Olle</td>
        <td>Olsson</td>
        <td>Shady Trading Oy</td>
        <td>Konsult</td>
    </tr>
</table>
</body>
</html>

Hela hemligheten är i dom inledande header-raderna där man helt enkelt för webbläsaren deklarerar vad det är för fil som den försöker öppna så att den gör rätt. Här försöker den öppna excel.xls och inte excel.php.

På samma sätt som man gör när man t.ex. läser jpg-filer ur databas som jag avhandlat innan.

Man kan strunta i table-stilen och bara mata ut allting med \t efter som fält-bryt och \n som radbryt. Men varför inte sätta lite formatering på det om man kan?

Categories: PHP, Web Taggar:

Slumpade lösenord med php

april 17th, 2010 rejser 1 kommentar

När det ska skapas användare för kunder t.ex. på jobbet så är det ofta jag som har hand om det. Och varje gång blir jag lite sur att jag måste googla något ställe för att skapa lösenord smidigt.

Så nu skapar jag mina egna där jag kan bestämma själv hur många som genereras, hur långa dom är och vilka tecken som kan ingå. Tänkte visa en rensad variant på hur jag gjorde..

<?php
$res = ”;
if(isset($_POST['leangth']))
{
    extract($_POST);
    $res = "";
    // kom ihåg att inte ha med bokstäver eller siffror som kan misstas.
    // bokstaven l eller siffran 1, bokstaven O siffran 0 osv.
    $chars = "/\-[]@$<>abcdefghijkmnopqrstuvwxyz23456789ABDCDEDFHJKLMNPQRSTUVXYZ";
    $y = 0;
    while($y < $antal){
        $x = 0;
        $pass = ” ;
        $y++;
        while ($x < $leangth) {
            // nu ska vi välja ut en bokstav ur vår långa sträng. Vi väljer ett slumpmässigt nummer och tar bokstaven på den platsen.
            // rand() väljer ett slumpmässigt tal. strlen returnerar en int med längden på strängen. i detta fall antal tecken i vår $chars sträng. sedan plockar vi ut tecknet/bokstaven på den platsen.
            $num = rand() % strlen($chars);
            $tmp = substr($chars, $num, 1);
            $pass = $pass.$tmp;

            $x++;
        }     
        $res .= "L&ouml;senord ".$y.": <strong>".$pass."</strong><br/>";
    }
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
     <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     </head>
    <body>
        <h1>Lösenords-generering</h1>
        <form method="POST" action="<?php echo $PHP_SELF; ?>">
            <label>Antal lösenord:</label><br/>
            <input type="text" maxlength="2" name="antal" size="2" value="1"/><br/>
            <label>Längd på lösenord:</label><br>
            <input type="text" maxlength="2" name="leangth" size="2" value="6"/><br/>
            <input type="submit" value="Skapa lösenord"
        </form>
        <?php echo $res; ?>
    </body>
</html>

Så nu är det bara att köra igång och skapa lösenord på löpande band.

Gör man den till en funktion kan man ju stoppa in den bakom i konto-skapande för mail-utskick med en bekräftelsekod t.ex.

Categories: PHP, Web Taggar:

Skicka html-mail med php

april 14th, 2010 rejser Inga kommentarer

Behövde skicka lite stiliga html-mail med php, och överallt hittade jag bara referenser till pear. Men så har jag ställen där jag behöver använda det på som inte har pear. Och förvisso kan man alltid lägga till, men tänkte det hade varit trevligt med något straight out of the box i php.

Efter mycket letande kom jag slutligen fram till något som jag kände mig ganska nöjd med.

Tricket är att men får ta med Content-type: text/html; Så nedan skickar vi ett exempel-mail.

<?php
   $to     = “till@email”;
    $from     = “från@email”;
    $subject = utf8_decode("Hell&ouml; World");
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
    $headers .= "From: $from\r\n";
    $message = "<html><body>";
    $message .= “<h1>Hello World</h1>";
    $message .= "</body></html>";
// Nu har vi byggt vårat meddelande, då skickar vi det
    if(mail($to, $subject, $message, $headers))
    {
        echo  "Meddelande har skickats ";
    }
    else
        echo  "Nope, något gick fel";
}
?>

I vanlig ordning så enkelt som möjligt. Nu är det bara att klä på den.

Man kan t.ex. bygga upp en snygg mall. Ha ett formulär där du fyller i vad som ska stå för meddelande och använda för t.ex. kundutskick från hemsidan för små företag eller klubbar.

Då behöver man bara en databas med e-mail adresser så kör man. (då lägger man dom som bcc (blind carbon copy) så att inte alla ser allas adresser).

Categories: PHP, Web Taggar:

PHP och lite ajax

februari 28th, 2010 rejser Inga kommentarer

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

image

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.

Categories: PHP, Web Taggar:

Hur får man en sådan där kort url?

februari 21st, 2010 rejser Inga kommentarer

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&auml;nk &auml;r <a href=’../$last_id’>http://localhost/KortUrl/$last_id</a></h1>";
$message .= "<p>Din l&aring;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&ouml;rsta l&auml;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:’

image 

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&auml;nk kunde tyv&auml;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.

Download File – KortURL

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.

Categories: PHP, Web Taggar:

PHP & MySQL Del IV

februari 16th, 2010 rejser Inga kommentarer

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

  1. I Del I så skapar vi en tabell och stoppar in en rad som vi sedan hämtar (länk)
  2. 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)
  3. 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)
  4. I Del IV kommer vi uppdatera data i databasen (länk)
  5. 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.

  • root
    • index.php
    • nyelev.php
    • visaklass.php
  • root\includes
    • 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&aring;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&aring; 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

    image

    Klickar på visa elever på klas 4c eller vilken klass du nu har elever i.

    Får något sånthär

    image

    Vi klickar på uppdatera elevinformation på Ollette Olsson

    Ändrar till Olle som är en pojke

    image

    Klickar på uppdatera elev. Så får vi

    image

    Vi klickar på Visa klass och det går nu en olle o klassen

    image

    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

    Download File – DEL IV
    Categories: PHP, Web Taggar:

    PHP & MySQL Del III

    februari 15th, 2010 rejser Inga kommentarer

    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

    1. I Del I så skapar vi en tabell och stoppar in en rad som vi sedan hämtar (länk)
    2. 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)
    3. 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)
    4. I Del IV kommer vi uppdatera data i databasen (länk)
    5. 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&auml;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&aring;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&aring; tillbaka</a></p>";
        echo $message;
    ?>

    I verkligheten kanske vi hade haft person-nummer på eleven och kollat så att inte eleven finns innan, och om eleven fanns informerat om detta eller uppdaterat informationen på eleven. (vi ska uppdatera lite information senare).
    Nu kan vi skapa elever, men vad ska vi göra med dom?
    Minns ni att vi har ett fält som heter antal elever? Det är ju jättedumt, hade det inte varit bättre att räkna antal elever i databasen istället? Vi ska nu uppdatera displayKlass så att vi använder databasen bättre.

    Vi ersätter

    $sqlSelect = "Select * from klasser”;

    med:

    $sqlSelect = "Select *,count(elev_id) as antal from klasser join elever on klasser.klass_id=elever.klass_id group by klasser.klass_id";

    Den stora nackdelen är att om vi gör det såhär så kommer vi inte få med dom klasserna som inte har några registrerade elever. Men vi kommer få resultatet grupperat per klass med antal elever som antal. count(variabel) as antal gör så att det kommer tillbaka ett fält med värdet den har räknat. count är dock lite meningslöst om man inte gör en group by. För att komma runt detta får vi göra en Left join. En left join tar inte hänsyn till om det finns något att join:a med på andra sidan. Det är inte hela datan som är resultatet utan först och främst huvudtabellen, sedan är det andra en sekundär tabell man kollar på om man hittar något. Så vi gör om den igen så den blir:

    $sqlSelect = "Select *,count(elev_id) as antal from klasser left join elever on klasser.klass_id=elever.klass_id group by klasser.klass_id";

    Nu kan man göra select * i såhär små tabeller, men sedan för man ange Exakt den data man vill ha ut. t.ex.

    $sqlSelect = "Select klassNamn, argang,count(elev_id) as antal from klasser left join elever on klasser.klass_id=elever.klass_id group by klasser.klass_id";

    Om ni kör bägge rader i ett sql-gränssnitt ser man en klar skillnad (exempelvis phpmyadmin).

    Jag visar för säkerhets skull. Jag har 3 klasser, 1 elev.

    Fråga utan left join:
    image

    Fråga med left join:image

    Fråga med left join och bara valda fält:
    image

    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&auml;gg till elev</a></td>";

    Till:

    $table .= "<td>$antal <a href=’laggtillelever.php?kid=$Klass_id’ />L&auml;gg till elev</a></td>";

    Om vi kör index.php så får vi nu

    image

    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&auml;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&auml;gg till elev</a></td>";

    Till:

    $table .= "<td>$antal <a href=’laggtillelever.php?kid=$Klass_id’ />L&auml;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.

    image

    Som leder till:

    image 

    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

    Download File – Del3
    Categories: PHP, Web Taggar:

    PHP & MySQL Del II

    februari 12th, 2010 rejser Inga kommentarer

    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

      1. I Del I så skapar vi en tabell och stoppar in en rad som vi sedan hämtar (länk)
      2. 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)
      3. 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)
      4. I Del IV kommer vi uppdatera data i databasen (länk)
      5. 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&aring;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 &Aring;rg&aring;ngen";
        if(!$klassNamn)
            $message .= "<br>Du hade inte fyllt n&aring;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).

    image  ä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>&Aring;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?

    image

    Bifogar för säkerhets skull filerna såhär långt i en zip-fil

    Download File – Del2

    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.

    Categories: PHP, Web Taggar: