Jednoduchá anketa s grafem v PHP a MySQL

18. března 2009

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.

Předchozí článek extensions.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

8 komentářů

  1. Libor Mošna

    Čvn 23, 2009 v 19:49

    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

    Odpovědět
  2. Lamicz

    Srp 1, 2009 v 19:25

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

    Odpovědět
  3. __const

    Zář 9, 2009 v 15:08

    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

    Odpovědět
  4. rihot

    Lis 19, 2009 v 14:26

    Superomlouvám se
    za spam

    Odpovědět
  5. stanley

    Úno 6, 2010 v 0:57

    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í.

    Odpovědět
  6. JOHNY

    Dub 10, 2010 v 21:21

    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!

    Odpovědět
  7. Pavel

    Kvě 17, 2010 v 19:32

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

    Odpovědět
  8. pavelp

    Úno 3, 2012 v 8:05

    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“.

    Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *