Tabulky v databázi
Ze všeho nejdříve je potřeba navrhnout tabulky v databázi, do kterých budeme ukládat hlasy od uživatelů a odpovědi.
V první tabulce bude seznam odpovědí a počet hlasů, která každá z odpovědí dostala.
Tabulku si pro přehlednost pojmenujeme anketa. Do tabulky se vejde 5 odpovědí.
Její kód vypadá takto:
Tabulka anketa
CREATE TABLE anketa(
id INT auto_increment primary key,
otazka VARCHAR(150),
odpoved_1 VARCHAR(100),
odpoved_1_hlasu INT,
odpoved_2 VARCHAR(100),
odpoved_2_hlasu INT,
odpoved_3 VARCHAR(100),
odpoved_3_hlasu INT,
odpoved_4 VARCHAR(100),
odpoved_4_hlasu INT,
odpoved_5 VARCHAR(100),
odpoved_5_hlasu INT
)
Dál je potřeba nějam ukládat informaci o tom, který uživatel hlasoval (pro případ že by chtěl hlasovat vícekrát).
Tabulka bude vypadat takto:
Tabulka anketa_hlasovali
CREATE TABLE anketa_hlasovali(
id_ankety INT,
ip VARCHAR(16),
key ip(ip)
)
U této tabulky je použit index a to na sloupci ip. Je to kvůli zmírnění zátěže na databázi.
Před započítáním hlasu dojde ke kontrole, jestli už uživatel v anketě nehlasoval.
Jestliže by se index v tabulce nenacházel hledalo by se pokaždé ve všech záznamech o hlasech uživatelů.
S indexem se budou prohledávat pouze záznamy z 1 konkrétní IP.
Pokud bychom měli v tabulce více jak 100 000 záznamů (z 20 různých anket) a u tabulky by nebyl index,
projíždělo by se při každém pokusu o hlasování všech 100 000 záznamů než by se našel ten, který by uživateli zamezil podruhé hlasovat.
S indexem se budou prohledávat pouze záznamy z uživatelovy IP a těch může být pži 20 různých anketách maximálně 20.
Program tedy bude prohledávat pouze 20 záznamů a to je v porovnání s číslen 100 000 docela velký rozdíl nemyslítě ?
Nyní přejdeme na hlavní část celého scriptu, a to na zobrazení samotné ankety.
Zobrazení ankety
Soubor: anketa.php
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="style.css" />
<title>Anketa</title>
</head>
<body>
<?php
require_once("db.php");
// načtení zat z databáze
$query = mysql_query("SELECT *,(odpoved_1_hlasu+odpoved_2_hlasu+odpoved_3_hlasu+odpoved_4_hlasu+odpoved_5_hlasu) as celk
FROM anketa ORDER BY id DESC LIMIT 1") or die(mysql_error());
// data z databáze => pole
$row = mysql_fetch_array($query);
echo'<div class="anketa"><div class="anketa_otazka">'.$row["otazka"].'</div>
<table width="200" cellpadding="3" cellspacing="0">';
// vypsání odpovědí
for($x=1;$x<=5;$x++){
echo'<tr class="anketa_odpoved"><td colspan="2"><a href="hlasuj.php?hlas='.$x.'">'.$row["odpoved_$x"].'</a>
</td></tr>';
$hlasu = $row['odpoved_'.$x.'_hlasu'];
if($hlasu==0){
$width1 = 0;
$procento=0;
} else {
$cis = $hlasu/$row["celk"];
$procento=floor($cis*100);
$width1 = ceil($cis*120);
}
echo'<tr class="anketa_odpoved"><td style="width:160px;">
<div class="pruh" style="width:'.$width1.'px;"></div></td>';
echo'<td align="right">'.$hlasu.'/'.$procento.'%</td>';
echo'</tr>';
}
echo'<tr><td colspan="2" align="center" class="anketa_info">Celkem hlasovalo <strong>'.$row["celk"].'</strong> lidí</td></tr>';
echo'</table></div>';
?>
</body>
</html>
Ze všeho nejdříve se z databáze načtou informce o aktuální anketě (poslední přidaná) a zobrazí se otázka.
Hned potom následuje cyklus pro vypsání odpovědí. Opakuje se celkem 5x (máme 5 odpovědí).
Při každém opakování se vypíše odpověď, počet hlasů, které získala, spočítá se procentuální úspěšnost a šířka barevného proužku.
Pro 100% je šířka 160px. Čim míň procent odpověď získala, tím bude proužek kratší.
Úplně nakonec se nám ukáže celkový počet hlasů.
Hlasování v anketě
Dalším krokem v pořadí je umožnit uživatelům v anketě hlasovat. To obstará soubor hlasuj.php
Soubor: hlasuj.php
<?php
require_once("db.php");
$hlas = sprintf("%d",$_GET["hlas"]);
if($_GET["hlas"]>0 && $_GET["hlas"]<6){
// ip uživatele
$ip = $_SERVER["REMOTE_ADDR"];
$id_ank = mysql_result(mysql_query("SELECT id FROM anketa ORDER BY id DESC LIMIT 1"),0);
// kontorla jestli uživatel nehlasoval v jedné anketě vícekrát
$kontrola = mysql_result(mysql_query("SELECT count(*) FROM anketa_hlasovali WHERE ip='$ip' && id_ankety='$id_ank'"),0);
// pokud uživatel ještě nehlasoval započítáme jeho hlas
if($kontrola==0){
mysql_query("INSERT INTO anketa_hlasovali (id_ankety,ip) VALUES('$id_ank','$ip')");
$sloupec="odpoved_".$hlas."_hlasu";
mysql_query("UPDATE anketa SET $sloupec=$sloupec+1 WHERE id='$id_ank'") or die(mysql_error());
}
}
// přesměrujeme uživatele zpět na úvodní stránku
header("Location:anketa.php");
?>
Řekl bych, že k tomu není moc co dodávat. Script si převezme z adresy informaci o tom, jak uživatel hlasoval ($_GET["hlas"]),
zkontroluje, jestli nehlasuje v jedné anketě víc než jednou a pokud ne, započítá hlas.
Spojení s databází
Spojení s databání obstarává soubor db.php
<?php
$server = ""; // adresa MySQL serveru
$database = ""; // přihlašovací jméno k databázi
$heslo = ""; // heslo
$dbname = ""; // název databáze
$link = mysql_connect("$server", "$database", "$heslo") or die ("Nepovedlo se spojit s databází");
$db = mysql_select_db("$dbname", $link) or die("Nepovedlo se otevřít databázi");
mysql_query("SET CHARACTER SET utf8");
?>
Administrace
Aby anketa správně fungovala, je potřeba do ní nějak přidávat otázky a odpovědi.
K tomu je tady připravené jednoduché administrační rozhraní.
Soubor: admin.php
<?php
session_start();
require_once("db.php");
if($_POST["heslo"]=="auto"){
$_SESSION["vstup"]=1;
}
if($_SESSION["vstup"]==1){
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="style.css" />
<title>Anketa - administrační rozhraní</title>
</head>
<body>
<b>Vyhlásit novou anketu</b>
<?php
if($_POST["submit"]){
mysql_query("INSERT INTO anketa (
otazka,
odpoved_1,
odpoved_2,
odpoved_3,
odpoved_4,
odpoved_5) VALUES(
'".addslashes($_POST["otazka"])."',
'".addslashes($_POST["odpoved1"])."',
'".addslashes($_POST["odpoved2"])."',
'".addslashes($_POST["odpoved3"])."',
'".addslashes($_POST["odpoved4"])."',
'".addslashes($_POST["odpoved5"])."'
)");
echo'Anketa byla aktualizována.
<a href="anketa.php">Zpět</a>';
exit();
}
echo"
<table cellpadding=\"5\" cellspacing=\"1\">
<form action=\"admin.php\" method=\"post\">
<tr>
<td width=\"25%\" align=\"center\"><b>Otázka</b></td>
<td><input type=\"text\" name=\"otazka\" size=\"70\" /></td>
</tr><tr>
<td align=\"center\">Odpověď 1</td>
<td><input type=\"text\" name=\"odpoved1\" size=\"70\" /></td>
</tr><tr>
<td align=\"center\">Odpověď 2</td>
<td><input type=\"text\" name=\"odpoved2\" size=\"70\" /></td>
</tr><tr>
<td align=\"center\">Odpověď 3</td>
<td><input type=\"text\" name=\"odpoved3\" size=\"70\" /></td>
</tr><tr>
<td align=\"center\">Odpověď 4</td>
<td><input type=\"text\" name=\"odpoved4\" size=\"70\" /></td>
</tr><tr>
<td align=\"center\">Odpověď 5</td>
<td><input type=\"text\" name=\"odpoved5\" size=\"70\" /></td>
</tr><tr>
<td colspan=\"2\" align=\"center\">
<input type=\"submit\" name=\"submit\" value=\"Odeslat\" />
</td></tr>
</form>
</table>
</body>
</html>
";
} else{
echo'<form action="admin.php" method="post">
Heslo: <input type="password" name="heslo" />
<input type="submit" value="Prihlasit se" />
</form>';
}
?>
Heslo do administrace se mění na tomto řádku: if($_POST["heslo"]=="auto").
Jak jste si mohli všimnout, tak ve stávající verzi je heslo "auto".
Heslo je samozřejmě možné jakkoli změnit.
Vzhled ankety
Anketu je možné různě barevně nastylovat. Provádí se to změnou barevných kódu v souboru style.css
Soubor: style.css
body, body a, body a:hover{font-family:Verdana; color:#000; font-size:12px;}
.anketa{background:#FFF; border:1px #000 solid; width:200px;}
.anketa_otazka{background:#969696; font-weight:bold; padding:5px;}
.anketa_odpoved{background:#FFF;}
.pruh{height:15px; background:blue;}
.anketa_info{background:#DDD;}
Závěr
To by bylo k dnešnímu článku vše. Případné připomínky, kritiku nebo dotazy směřujte do komentářů.
Celý script je volně ke stažení zde.
|