Reklama

zonerbooks.cz | zoner.cz | czechia.com | regzone.cz | inshop.cz | inmail.cz | zonerpress.cz | zonerantivirus.com | zonerama.cz

interval.cz

Jednoduchá anketa s grafem v PHP a MySQL

18. 03. 2009 | Vojtěch Zíka | PHP | Komentáře: 8

Když jsem začínal s programováním, rád jsem na své weby umisťoval ankety. Bohužel jsem je tenkrát neuměl sám vytvořit a proto jsem využíval služeb jako je BlueBoard. V době, kdy jsem dělal první komerční web jsem si ale uvědomil, že takovéto "externí" prvky vypovídají cosi o mých programátorských schopnostech. Svojí první anketu jsem "opsal" z jedné publikace o PHP, kde ji ale naneštěstí řešili velmi složitě – za pomoci polí, obrázků generovaných v PHP apod. Tato konstrukce mi přišla velmi kostrbatá a pro začínající programátory až nepochopitelná.

Proto jsem se rozhodl publikovat tento článek o vytvoření ankety v jednoduchém PHP a MySql spolu s CSS. Protože se tato úloha skládá z více logických částí, rozhodl jsem se článek rozdělit takto:

  1. příprava - vytvoření tabulky v databázi MySql
  2. teorie - grafické zpracování výsledků
  3. řešení - samotné hlasování a ukládání výsledků

Příklad: Potřebujeme vytvořit anketu, která bude obsahovat tři volby – červený, modrý a zelený tým. Výsledek za kterým míříme, si můžete prohlídnout zde a stáhnout zde.

Příprava - vytvoření tabulky v databázi MySql

Jak již bylo naznačeno v nadpisu tohoto článku, budeme pracovat s databází MySql. Na začátku celého dokumentu se k ní tedy nejdříve musíme připojit.:

mysql_connect("ip serveru", "login", "heslo");
mysql_select_db("nazev databaze");
mysql_query("SET NAMES 'utf8';");

Po úspěšném připojení k DB v ní musíme vytvořit příslušnou tabulku 'anketa' - zde je SQL dotaz pro její vytvoření:

CREATE TABLE 'anketa' (
'ip' varchar(100) collate utf8_bin NOT NULL,
'val_1' tinyint(1) NOT NULL default '0',
'val_2' tinyint(1) NOT NULL default '0',
'val_3' tinyint(1) NOT NULL default '0',
PRIMARY KEY ('ip')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

V této tabulce máme je první sloupec 'ip' definovaný jako PRIMARY_KEY, což nám zajišťuje prvotní ochranu proti dvojitému hlasování z jedné IP adresy.Další tři sloupce jsou pro ukládání hlasů pro jednotlivé subjekty ankety, v našem případě 'val_1' = červený tým, 'val_2' = modrý tým, 'val_3' = zelený tým. Jeden ze tří sloupců bude vždy nabývat hodnotu '1' (hlas pro) a zbylé dva hodnotu '0' (nic).

Teorie – grafické zpracování výsledků

Nejdříve musíme zjistit, kolik hlasů obdržel každý ze tří týmů. K tomu využijeme funkci mysql_num_rows u každého ze tří sloupců (sečteme všechny řádky v jednom sloupci, kde je hodnota '1' (hlas pro). Získané hodnoty uložíme do proměnných $value_1 - 3:

$sql=mysql_query("SELECT * from anketa WHERE val_1 = 1;");
$value_1 = mysql_num_rows($sql);
$sql=mysql_query("SELECT * from anketa WHERE val_2 = 1;");
$value_2 = mysql_num_rows($sql);
$sql=mysql_query("SELECT * from anketa WHERE val_3 = 1;");
$value_3 = mysql_num_rows($sql);

Nyní je nutné zjistit celkový počet hlasů, čehož docílíme jednoduchým sečtením:

$suma = $value_1 + $value_2 + $value_3;

Poté potřebujeme zjistit, kolika hlasům odpovídá jedno procento. Což zjistíme vydělením celkového počtu hlasů stem.

$perc = $suma / 100;

Nyní si přepočítáme hlasy na procenta – počet obdržených hlasů každého týmu vydělíme jedním procentem.

$graf_1 = $value_1 / $perc;
$graf_2 = $value_2 / $perc;
$graf_3 = $value_3 / $perc;

V této fázi se dostáve k části článku, ve které vytvoříme samotný tří sloupcový graf (tři mužstva) pomocí kaskádových stylů. Jediné 3 parametry které budeme potřebovat je výška sloupce – ten nastavíme pevný, barvu sloupce – ta bude stejná jako barva týmu, tedy červená, modrá a zelená. Třetím parametrem je šířka sloupce. Tento parametr nemůžeme samozřejmě určit fixně, protože právě on zařídí vykreslení grafu. Tuto šířku máme ale již vypočítanou – je to počet procent získaných jednotlivými týmy ($graf_1 - 3).

Abychom docílili větší přehlednosti grafu, zvětšíme měřítko grafu 5x a vytvoříme si funkci pro zaokrouhlení výsledného čísla na jedno desetiné místo:

$w_graf_1 = $graf_1 * 5;
$w_graf_2 = $graf_2 * 5;
$w_graf_3 = $graf_3 * 5;
function zaokrouhli($int)
{
return round($int, 1);
}

A zde je CSS kód pro vykreslení grafu:

<style type="text/css">
body{font-family: tahoma;}
#graf_1
{
width:<?=$w_graf_1;?>px;
height:20px;
color: #fff;
background-color: red;
}
#graf_2
{
width:<?=$w_graf_2;?>px;
height:20px;
color: #fff;
background-color: blue;
}
#graf_3
{
width:<?=$w_graf_3;?>px;
height:20px;
color: #fff;
background-color: green;
}
</style>

Řešení - samotné hlasování a ukládání výsledků

V této chvíli již stačí graf pouze zobrazit. Protože však chceme, aby naše anketa byla anketou aktivní, přidáme si rovnou ke grafu i radio-buttony pro vybrání našeho favorita, čímž se plynule přesouváme do poslední části tohoto článku.

<form method="post" enctype="multipart/form-data" action="">
<input type="radio" value="1" name="rb" />Červený tým:
<div id='graf_1'><?=zaokrouhli($graf_1);?>%</div>
<input type="radio" value="2" name="rb" />Modrý tým:
<div id='graf_2'><?=zaokrouhli($graf_2);?>%</div>
<input type="radio" value="3" name="rb" />Zelený tým:
<<div id='graf_3'><?=zaokrouhli($graf_3);?>%</div>
<p><input type="submit" value="Hlasovat" /></p>
</form>

Poslední, co nám ještě zbývá udělat, je "oživit" tento formulář a uložit uživatelův hlas. To s sebou nese různé dílčí malé problémy. Následující kód je poměrně dlouhý a tak pro objasnění jednotlivých kroků použiji komentáře přímo v PHP kódu.

if(isset($_POST['rb'])) // pokud je hlas odeslán, provede se procedura
{
/*
ochrana proti vícenásobnému hlasování pomocí IP (zjistíme IP adresu uživatele a zjistíme zda-li již tato IP adresa není v databázi) a COOKIES (protože IP může být proměnlivá, uložíme si cookie na dobu 1 měsíce - tzn, že uživatel nebude moci měsíc hlasovat ve stejné anketě - POZOR! - pokud anketu změníte, nezapomeňte i na změnu názvu cookie - uživatelé, kteří by hlasovali v posledním měsíci fungování staré ankety, by nemohli hlasovat v anketě nové.)
*/
$ip = $_SERVER['REMOTE_ADDR'];
setcookie( 'protector_1' , 'set' , time() + 3600 * 24 * 31 );
$vysledek = mysql_query("SELECT * from anketa WHERE ip = '$ip';");
$ctrl = mysql_num_rows($vysledek);
if($ctrl != 0 OR isset($_COOKIE['protector_1']))
{
die("<script>window.alert('Váš hlas nemohl být započítán, protože jste již hlasovali.')</script>");
}
else
{
/* převedení hodnot z radio-buttonů – jeden hlas musí mít hodnotu 1 – hlas pro */
switch($_POST['rb'])
{
case 1: $var1 = 1; break;
case 2: $var2 = 1; break;
case 3: $var3 = 1; break;
}
// vložení hlasu do databáze
$sql = "INSERT INTO anketa(ip ,val_1, val_2, val_3) VALUES ('$ip' ,'$var1', '$var2', '$var3')";
if(mysql_query($sql)) //pokud byl hlas uložen
{
echo "<script>window.alert('Děkujeme, Váš hlas byl započítán.')</script>";
}
else // pokud uložen nebyl
{
echo "<script>window.alert('Váš hlas bohužel nebyl započítán z důvodu chyby v systému. Zkuste hlasovat znovu později.')</script>";
}
}
}

Závěr

Graf si samozřejmě můžete upravit podle libosti v CSS – místo horizontálního můžete udělat vertikální, místo barev vložit nějaký obrázkový vzor apod. Podle mého je takto vytvořená anketa s grafem velmi jednoduchá, účelná a variabilní. Doufám, že moje vysvětlení je dostatečně srozumitelné i pro začínající programátory. Pokud není, napište, prosím, do diskuse pod článkem.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.


Další aktuální články na interval.cz

Tematicky související články

Dejte vědět i ostatním o článku

Komentáře ke článku

Přidat nový komentář

Libor Mošna

Autor komentáře: Libor Mošna

Datum vložení: 23. Červen 2009, 19:49:36

Moc hezké řeči, panstvo, ale zkusili jste tedy vše opravit a vložit na server? Docela bych to uvítal, jelikož se zrovínka také Php učím a docela by mi to bodlo, takže kdyby měl někdo chuť, tak ten článek porsím překopejte. Díky

Lamicz

Autor komentáře: Lamicz

Datum vložení: 01. Srpen 2009, 19:25:46

Tahle anketa vypovídá hodně o Vašich schopnostech, to máte pravdu ;)

__const

Autor komentáře: __const

Datum vložení: 09. Září 2009, 15:08:43

Toto je hrůza. Důrazně doporučuji nikomu ani nezkoušet. Nechápu jak něco takového mohlo tady vůbec být zveřejněno. Ostuda

rihot

Autor komentáře: rihot

Datum vložení: 19. Listopad 2009, 14:26:18

Superomlouvám se
za spam

stanley

Autor komentáře: stanley

Datum vložení: 06. Únor 2010, 00:57:39

Tak v této fázi jsem o sobě začal tvrdit, že jsem programátor... nebyla to pravda. Ale byl jsem na dobré cestě a to autor článku je taky. Přeji mno dlaších let učení.

JOHNY

Autor komentáře: JOHNY

Datum vložení: 10. Duben 2010, 21:21:52

Hele nechápu, na co si stěžujete? Funguje to skvěle, na pochopení, hrabání a upravování taky skvělé. Tohle je psáno prosím vás pro začátečníky!

Pavel

Autor komentáře: Pavel

Datum vložení: 17. Květen 2010, 19:32:20

Ahoj ,mám jen otázku, jak to poté vložím na stráínky?:-)

pavelp

Autor komentáře: pavelp

Datum vložení: 03. Únor 2012, 08:05:03

Díky za článek, který mi pomohl při základní orientaci v logice ankety. Rozšížení skriptů o lepší zabezpečení a validitu si už dořeším po svém, pomohlo mi to však začít s jasnou myslí, aniž bych byl pohlcen přemírou "košér vychytávek".

Zpět na začátek komentářů | Zpět na začátek článku

Přidat nový komentář

Jméno a e-mail jsou nepovinné. Příspěvky obsahující odkaz jsou moderovány.

Zoner AntiVirus Free pro Android
zabezpečte si svůj smartphone, zdarma
Profesionální eshop Zoner inShop od 990 Kč.
Zoner Photo Studio 14 – vyzkoušejte ZDARMA

Vybíráme z webu milujemefotografii.cz

Error: Feed has a error or is not valid

Reklama
Reklama
Zoner Photo Studio 14

Syndikace

hledáme nové autory | redakce interval.cz | reklama na interval.cz

© ZONER software, a.s., všechna práva vyhrazena, interval.cz dodržuje právní předpisy o ochraně osobních údajů. Powered by WordPress.