Anketní systém v PHP - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



PHP

Anketní systém v PHP

php_anketa

6. března 2001, 00.00 | Chcete nechat návštěvníky svých stránek hlasovat na různá témata? Nechte se inspirovat naším článkem a udělejte si svůj anketní systém!

Anketní systém
Pro vytvoření tohoto jednoduchého anketního systému budeme potřebovat podporu PHP skriptů a databázi (já používám MySQL). Další věcí, kterou si usnaďnuji práci s databází jsou tyto tři soubory, které jsou volně šiřitelné (ct_sql.inc, db_mysql.inc, local.inc) - v souboru local.inc si nastavíme parametry pro připojení k databázi (pro větší bezpečnost si je přejmenujte na *.php :)

Co vytvoříme nejdříve
Jedinou věc, kterou si musíme vytvořit je tabulka v datábazi, ve které budeme mít uložené všechny ankety. Tento způsob je jednoduchý, má však jednu nevýhodu. Má stanovený max. počet možností výběru odpovědí. Z praxe se však ukazuje že 7 je dostatečné množstí. Takže vytvoříme tabulku, ve které bude mít 16 sloupcu. Jeden pro jednoznačnou identifikaci ankety (sloupec id), další pro otázku(sloupec otazka) a 14 (odp1 az idp7 pro odpověd a p1 az p7 pro počet odpovědí). Tabulku vytvoříme pomocí sql dotazu.

create table ankety (id int4 not null default '0' auto_increment primary key, otazka varchar(50), odp1 varchar(35), p1 int2, odp2 varchar(35), p2 int2, odp3 varchar(35), p3 int2, odp4 varchar(35),p4 int2, odp5 varchar(35), p5 int2, odp6 varchar(35), p6 int2, odp7 varchar(35), p7 int2 )

Dále bude potřeba vytvořit údaje o anketě, tedy nějaký systém pro tvoření, úpravu a mazání anket. Tomuto se bude věnovat v druhém díle. Zatím však stačí poslat databázi tento příkaz.

insert into ankety values(0,"Jak často jsi na internetu?", "Jsem na internetu náhodou",0,"Jednou za čas",0,"Jednou za týden", 0,"3x do týdne",0,"Denně", 0, "Je to má droga", 0,"",0 )

Mužete si všimnout že 7.možnost odpovědi není vyplněna, zobrazovací funkce tento sloupec vůbec nevykreslí :)

Jak se s tím bude pracovat?
Způsob jak vkládat ankety je několik. Já doporučuji univerzální způsob, který mi umožní vložit anketu kamkoliv do mých stránek. Nejdříve něco k jeho principu. Do stánek vložím na určené místo anketu pomocí volání "funkce" zobrazanketu(idankety : integer)(z programátorského hlediska to funkce není, protože její výstup není v hodnotě, ale na obrazovku) a vykonání bude provádět soubor delejanketu.php, který se nebude mít žádný výstup na obrazovku, ale na jeho konci nás znovu přesměruje na stánku na které byla anketa zobrazena. Tento pracovní soubor také zajistí pomocí cookies, aby se nemohlo hlasovat dvakrát. (lze to zajistit i pomocí identifikaci IP adresy Poznámka redakce: tomuto problému se budeme věnovat ve speciálním článku)

Pracovní soubor delejanketu.phtml
Na začátku souboru si vložím usnadňující soubory (*.inc) popsané na začátku a definuji objekt ( pokud neumíte objektově programovat, vůbec to nevadí, já také ne :)

Do proměnné chameleon si uložím jméno proměnné pro dannou anketu (tedy hlas1). Pokud existuje takové cookie pak v proměnné hlas1 bude nějaká hodnota, pokud je ovšem jiná od 1 tak ještě nehlasoval. Jestliže neexistuje, tak vytvoř toto cookie a do databáze přičti hlas. Pokud chcete umožnit hlasovat třeba po půl hodinách tak změníme hodnotu proměnné neprijmouthlas
<?php
$chameleon = "hlas".$id;
$neprijmouthlas = 60*60*24*2; // 2dny nehlasovat = nastaví platnost cookie
if (($$chameleon) <> 1) //pokud nehlasoval, tak
{
 setcookie($chameleon,1,Time()+$neprijmouthlas); // nastav cookie
 include("ct_sql.inc"); //vloží "pomocné soubory"
 include("db_mysql.inc"); // pokud jste je přejmenovali, i tady je přejmenujte na *.php
 include("local.inc");
 $db = new mojeDB; // vytvoří z databáze objekt, práci s ním pochopíte níže
Tento soubor budeme volat s parametry(proměnnými) (přesněji uvidíte v popisu funkce zobrazanketu) id=x - která anketa byla zobrazena, a odp=x která odpověď byla vybrána (na kterou se kliknulo).

Takže teď můžeme sestavit dotaz, který upraví(zvýší o jedna) počet odpovědí na kterou se kliknulo.

 $query = "update ankety set p".$odp."=p".$odp."+1 where id=".$id; //sestavim dotaz
 $db->query($query); // pošlu dotaz k vykonání do datábaze
}
Sestavení dotazu by bylo dobré ještě trošku okomentovat. Jelikož soubor delejanketu.php budu volat s parametry tak hodnoty těchto parametrů mi php převede do proměnných. Tedy v proměnné $odp budu mít číselnou hodnotu odpovědi (v rozmezí 1 - 7) a v proměnné $id budu mít id ankety - tedy jednoznačné určení ankety ve které návštěvník hlasoval. Dotaz poté pouze upraví hodnotu sloupce odp1 (odp2, .., odp7) o jedničku pouze ve sloupci kde id rovná se hodnotě proměné id (tedy pouze v jednom sloupci).

A nakonec přesměrujeme návštěvníka zpět na stránku, ze které hlasoval. Provedeme to pomocí HTTP hlavičky a proměnné $HTTP_REFERER ve které je hodnota stránky ze které se přišlo.

header ( "Location: ".$HTTP_REFERER ); // pošle hlavičku k přesměrování
?> // a tento skript můžeme ukončit
Soubor pro vykonání ankety máme hotový.

Teď přijde věc zajímavější, zobrazit údaje z ankety. Vyřešíme to definicí funkcí, kterou si budeme moci vložit kamkoliv do kódu stránek. (Jen ji nevolejte v souboru delejanketa.php ) Ja ji vytvorim treba v souboru stranka.phtml

<?php
function zobrazanketu($id)
{
 include("ct_sql.inc"); //vloží "pomocné soubory"
 include("db_mysql.inc"); // pokud jste je přejmenovali, i tady je přejmenujte na *.php
 include("local.inc"); //Pokud tyto soubory volate na zacatku vaseho souboru zde uz je nevolejte
 $db = new mojeDB; // vytvoří z databáze objekt, tan vsak musite volat (php neumi primo volat promene vne funkce)
Databázi máme inicializovanou vytvoříme dotaz aby nám dal hodnoty (já osobněje preferuji způsob nejdříve si zjistím co nejvíce parametrů a až potom je zobrazím)
 $query = "select * from ankety where id=$id"; //formuluj dotaz
 $db->query($query); // odešli ho
 $db->next_record(); // a přečti data z databáze
Data z databáze mám přečtené teď už je stačí zpracovat, nejdříve si zjistím kolik je odpovědí celkem, abych mohl vypočítat procentuální hodnotu.
 $hlasucelkem = 0; // proměnou hlasu celkem definuji na 0
 for ($i = 1;$i < 8; $i++)
 {
  $hlasucelkem += $db->f("p".$i); //Zvysim pocet hlasu o hodnotu ve sloupcích p1 az p7
 }
 if ($hlasucelkem == 0) $hlasucelkem = 1; //Tuto podmínku vysvětlím níže
Pokud je celkových hlasů 0 tak to změn na 1. Když budeme vypočítávat procentuální hodnotu jednotlivých položek tak dělíme část/celkem a 0 dělit nelze. Je li ale celkem 0 pak i části jsou 0 a výsledku pak bude 0. (platí pouze pro kladné a nulové hodnoty - ty jsou vzdy)

Zobrazovací část funkce
Máme tedy spočítány celkový počet hlasů, jiné hodnoty máme v "databázovém objektu". Můžeme přistoupit k zobrazení ankety. Ještě bych upozornil, že každý si asi zobrazení udělá podle svého, budu se tedy snažit o jednoduché zobrazení,hlavně aby se pochopil jeho princip.

Nejdříve si nastavíme šířku celé tabulky a šířku procentního ukazatale (sloupce) a poté začneme zobrazovat tabulku, všimněte si definice třídy kaskádových stylů (css). Tabulka bude mít dva sloupce, jeden pro možnou odpověd a druhou pro "grafický" sloupec. Anketní otázku však potřebuji zobrazit přes celou tab, proto použiji parametr colspan=2
 $sirkatab = 200; // sirka tabulky v pixelech
 $maxsirkaprocent = 100; //sirka ukazatele v pixelech
 $sirkaotazky = $sirkatab - $maxsirkaprocent;
 echo "<table class=\"anketa\" width=\"$sirkatab\">\n"; //začátek tabulky, třída anketa je zvolena pro snadnější graf. úpravu
 echo "<tr><th colspan=\"2\">"; //nadpisové buňky tabulky přes celou její šířku
 echo $db->f("otazka"); // zobraz otázku ankety
 echo "</th></tr>\n"; //ukonci nadpisové buňky

Otázka je zobrazena a teď můžeme přistoupit k zobrazování jednotlivých položek, využili na to cyklus for. Aby se však při kliknutí na odpověd, hlas započítal musím text odpovědi definovat jako odkaz. Tento odkaz bude ukazovat na náš "pracovni soubor" delejanketu.php . Soubor však musím volat s parametry takže za jeho název přidám ?id=1 tím řeknu že soubor delejanketu.php bude mít přednastavenou hodnoutu proměné id na 1. Já však místo 1 vložím současnou hodnotu proměnné $id. A dále připojím pomoci &odp= a číslo odpovědi (dosazené pomocí proměnné $i)

 for ($i = 1; $i < 8; $i++)
 {
  if (strlen($db->f("odp".$i)) > 0) // je-li nějaké otázka, pak můžeš zobrazit sloupec
  {
   echo "<tr><td class=\"odp$i\" width=\"$sirkaotazky\">"; //zacni řádek tabulky (má třídu odp1 .. odp7)
   echo "<a href=\"delejanketu.phtml?id=$id&odp=$i\">"; // odkaz na pracovni soubor včetně přednastavených proměnných
   echo $db->f("odp".$i); // zobraz otázku ze sloupce odp1 .. odp7
   echo "</a>"; //konec odkazu
   echo "</td><td class=\"p$i\" width=\"$maxsirkaprocent\">"; // a v další buňka pro zobrazení sloupce (má třídu p1..p7)

A teď už zbývá zobrazit "grafický" indikátor procent. Nejdříve si spočítám, procentuální hodnotu a potom nechám zobrazit soubor sloupec.gif, tento soubor má výšku 5 pixelů (tu si zvolte sami dle vašeho estetického cítění :) a šířku 1 pixel. Při zobrazení v html stránce výšku zapíšu takovou jakou soubor má, ale pro šířku vložím hodnotu v proměnné $procent . Tím zajistím proměnlivost tohoto ukazatele. Pak už ukončím tabulku a funkci zobraz anketu.
   $procent = ($db->f("p".$i)/$hlasucelkem)*$maxsirkaprocent; //vypočítá procentuelní hodnotu hlasů
   $procent = round($procent); // a zaukrouhlí na celé číslo
   echo "<img src=\"sloupec.gif\" height=\"7\" width=\"$procent\">";// zobrazení sloupce - vysvětlím níže
   echo "</td></tr>\n"; // ukonči vykreslení tohoto řádku
  }
 }
  echo "</table>\n"; //ukončení tabulky kde je anketa
} //ukončení funkce zobrazanketu
Pokud by jste si přáli každý sloupec zobrazit vlastní barvou tak, místo jména souboru sloupec.gif napište do php kódu sloupec$i.gif, tím se pro každý sloupec bude hledat soubor sloupec1.gif až sloupec7.gif

Jiný způsob zobrazení tohoto "grafu" je pomocí další vložené tabulky, které je prázdná, má definované pozadí a její šířka je proměnlivá. (V Netscapu nutno do ní vložit "tvrdou mezeru")

Zobrazení ankety
Anketu zobrazíme voláním funkce zobrazanketu($id) to znamená v souboru stranka.phtml který je jako příklad doplním tohle

zobrazanketu(1); // zobrazí anketu s identifikačním číslem 1
?>

Elegantnější zobrazení ankety (přehlednější pro tvůrce stránek)
Pokud však nechceme do každého souburu psát definici zobrazovací funkce, tak necháme soubor stranka.phtml jen s definicí funkce (bez jejího volání) a do absolutně jiného souboru vložíme tohle

<?php
include(stranka.phtml); //vlozi funkci
.. // v souboru bude cokoliv
zobrazanketu(1) // na tomto místě zobrazí anketu (zavolá funkci zobrazanketu)
.. // soubor čímkoliv pokračuje
?>
Takže teď umíme zobrazit anketu, která je v tabulce "pod id 1", pokud si do tabulky vložíte další ankety, tak je samozřejmě nebudete volat jedničkou ale jejím odpovídajícím id.

Tento anketní systém má jednu nevýhodu, vždy bude zobrazen odkaz pro hlasování, takže kdokoliv může kliknout třeba 100x, hlas se mu započítá však jenom jeden ten první. Z jiného hlediska to může být výhoda, v domění, že hlasuje vícekrát bude několikrát načítat vaší stránku a tím i zobrazí reklamu výměnného systému ;-)

V příští části si ukážeme, jak udělat "správcovské prostředí" pro tvoření, upravování či mazání jednotlivých anket.

Download popisovaných souborů

Poznámka redakce: Takto popisovaný způsob zobrazení anket je jednoduchý a snadný pro pochopení principu. V praxi je ale lépe při provedení hlasování html kód ankety vygenerovat do statického souboru a ten poté includovat. V případě navštěvovaného serveru to velmi oceníte (srovnejte kolikrát někdo hlasuje a kolikrát je stránka pouze zobrazena - jsou zbytečně vypočítávány parametry ankety). Obecně je nutné vždy myslet na to, co je vhodné zobrazovat on-line a co můžeme předgenerovat, ale o tom možná jindy ve speciálním článku..

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » PHP  

 » Rubriky  » Web  

Poslat článek

Nyní máte možnost poslat odkaz článku svým přátelům:

Váš e-mail:

(Není povinný)

E-mail adresáta:

Odkaz článku:

Vzkaz:

Kontrola:

Do spodního pole opište z obrázku 5 znaků:

Kód pro ověření

 

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: