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.

8 Příspěvků v diskuzi

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

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

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

  4. 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!

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