Criar Enquete / Votação Com PHP

Uma das formas mais comuns de engajar o usuário na utilização do website é adicionar uma pergunta, de preferência polêmica, e disponibilizar duas ou três opções de resposta.

Neste primeiro tutorial, vou explicar somente a parte PHP da criação da enquete, o server-side. No próximo tutorial explicarei como apresentar o resultado de forma agradável e dinâmica utilizando o javascript.

O cadastro da pergunta e opções não será abordado neste tutorial por ser a parte mais simples. Vamos nos concentrar nos dados submetidos pelo usuário.

Tabela MySQL

Iniciamos criando os campos que receberão as informações.



CREATE TABLE EXISTS ‘enquete’ (
  ‘id’ int(5) NOT NULL auto_increment,
  ‘pergunta’ varchar(50) NOT NULL,
  ‘op01’ char(32) NOT NULL,
  ‘op01_n’ int(5) NOT NULL default '0',
  ‘op02’ char(32) NOT NULL,
  ‘op02_n’ int(5) NOT NULL default '0',
  ‘op03’ char(32) NOT NULL,
  ‘op03_n` int(5) NOT NULL default '0',
  PRIMARY KEY  (‘id’)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

Precisamos de um campo para cadastrar a pergunta, um para cada opção de resposta e um para contabilizar o número de vezes que a opção foi escolhida.

Para agilizar o trabalho, após ter criado a tabela, você pode executar a linha abaixo, que adiciona uma pergunta e as opções.



INSERT INTO ‘enquete’ (‘id’, ‘pergunta’, ‘op01’, ‘op01_n’, ‘op02’, ‘op02_n’, ‘op03’, ‘op03_n’) VALUES
(1, 'Qual linguagem de programação você utiliza?', 'PHP', 0, 'ASP',04, 'Java', 0);

Mostrando A Enquete

Na tela será apresentada a enquete com as informações advindas do banco de dados.



<?php
  mysql_connect("localhost", "usuario", "senha") or trigger_error(mysql_error(),E_USER_ERROR);
  mysql_select_db("bancodedados");
  
  $busca = mysql_query("SELECT * FROM enquete ORDER BY id DESC LIMIT 1") or die(mysql_error());
  if (mysql_num_rows($busca)>0)
  {  
    $enquete = mysql_fetch_array($busca);
    extract($enquete);
?>

<p><?php echo utf8_encode($pergunta);?></p>

<form action="grava-enquete.php" method="post">
  <input type="hidden" name="id_pergunta" value="<?php echo $id;?>" />
  <input type="radio" name="opcao" value="op01" /><?php echo $op01;?><br />
  <input type="radio" name="opcao" value="op02" /><?php echo $op02;?><br />
  <input type="radio" name="opcao" value="op03" /><?php echo $op03;?><br />
    <input type="submit" name="enviar" value="Enviar" />        
</form>

<?php
  } else {
    exit ('<p>Nenhuma enquete cadastrada.</p>');
  }

?>

Como vamos trabalhar com banco de dados, precisamos fornecer as informações para efetuar a conexão. Quando for executar na sua máquina ou outro servidor este código, não esqueça de alterar as informações fornecidas no mysql_connect.

Em seguida é efetuada uma busca na tabela ‘enquete’ e selecionada a última linha. Por isso o “ORDER BY id DESC”. Como o campo ‘id’ é auto incrementável, o último registro será o maior.

Se for encontrado algum registro, sendo assim, maior do que zero, a variável “enquete” recebe uma array com os dados retornados pela busca. A linha de baixo é muito interessante. O extract permite fazer referência às variáveis pelo nome da coluna na tabela de dados.

Desta forma, ao invés de utilizar “$enquete[‘op01’]” podemos utilizar “$op01”.

É mostrada a pergunta e criado o formulário com os valores retornados pela pesquisa. O arquivo que receberá os dados é o “grava-enquete.php” através do método POST.

Um detalhe a observar é o campo com o id da pergunta que esta escondido e será útil no código que grava a opção escolhida pelo visitante. Todos os input radio tem o mesmo nome, mas valores diferentes para que seja possível identificar a opção escolhida.

enquete PHP

Um Voto Por IP

Todo desenvolvedor ao criar uma enquete tem a preocupação de não permitir que um mesmo visitante vote múltiplas vezes e desta forma manipule o resultado. A forma mais comum para evitar este problema é a utilização de cookies.

Os cookies são arquivos que contém alguns dados trocados entre o computador do usuário e o servidor Isso permite identificar o usuário.

A função setcookie permite definir nome, dados e tempo de validade destes dados.



setcookie('enquete_php',$_SERVER['REMOTE_ADDR'],time()+86400);

Criamos um cookie com o nome ‘enquete_php’, que contém o endereço ip do usuário e que permanecerá no computador dele por 24 horas. O 86400 são os segundos que compõem o dia.

Antes que algum de vocês se levante para dizer que o cookie pode ser deletado pelo usuário, lembro que a maioria dos usuários nem sabe que eles existem. E os que sabem como deletar teriam que fazer isso para cada voto. E dificilmente uma enquete merece todo esse trabalho.

Recebendo Os Dados

O código somente executa se os dados estão completos e válidos.



if (isset($_COOKIE['enquete_php']))
{
  exit ('<p>Você já votou nesta enquete.</p>'.$_COOKIE['enquete_php']);  
} else {
  setcookie('enquete_php',$_SERVER['REMOTE_ADDR'],time()+86400);
  $opcao = strip_tags($_POST['opcao']);
  $id_pergunta = $_POST['id_pergunta'];
  $id_pergunta = filter_var($id_pergunta, FILTER_SANITIZE_NUMBER_INT);
}

Se um cookie com o nome “enquete_php” já estiver setado, isso significa que o usuário já votou nas últimas 24 horas. Informamos o usuário sobre isso ao mesmo tempo que paramos a execução naquele ponto.

Se o cookie ainda não foi criado, então isto é feito. Com o nome de “enquete_php”, o ip da máquina e válido por 24 horas.

A opção escolhida é recebida e tratada para evitar a tentativa de inserção de código. O id da pergunta também é tratado, mas de uma forma diferente.

Adicionando O Voto

Incluir diversas verificações durante a execução do código ajuda a evitar processamento desnecessário com dados incompletos. Por isso, garantimos que as variáveis que receberam a opção da enquete e o id da pergunta não estão vazias.

Todo o código abaixo é inserido dentro do else da verificação feita acima.


  if ($id_pergunta!='' and $opcao!='')
  {
  mysql_connect("localhost", "usuario", "senha") or trigger_error(mysql_error(),E_USER_ERROR);
  mysql_select_db("bancodedados");

    $consulta = mysql_query("SELECT * FROM enquete WHERE id='$id_pergunta'") or die(mysql_error());
    if (mysql_num_rows($consulta)>0)
    {
      $query = mysql_fetch_array($consulta);
      extract($query);
      switch($opcao)
      {
        case "op01";
        $voto = $op01_n + 1;
        mysql_query("UPDATE enquete SET op01_n='$voto' WHERE id='$id_pergunta'");
        break;
    
        case "op02";
        $voto = $op02_n + 1;
        mysql_query("UPDATE enquete SET op02_n='$voto' WHERE id='$id_pergunta'");
        break;
    
        case "op03";
        $voto = $op03_n + 1;
        mysql_query("UPDATE enquete SET op03_n='$voto' WHERE id='$id_pergunta'");
        break;
      }
    }

Se os dados foram preenchidos é feita a conexão com o banco de dados e realizada uma consulta que procura na tabela um campo de id que tenha o mesmo valor que o id da pergunta submetida.

A pesquisa retornando alguma linha da tabela, o resultado é extraído de maneira que possamos utilizar o nome das colunas como variáveis e estruturamos uma verificação.

Dentre as diversas declarações condicionais disponíveis, considero o switch a melhor quando necessário mais de duas comparações. No início da verificação fornecemos a informação que será comparada com as contidas nos case.

Se fechar com alguma delas, ao número de votos da opção é adicionado mais um. A linha da tabela é atualizada alterando o valor de votos da opção escolhida e a cadeia de verificação é quebrada. Pula para a continuação do código além da verificação.

O Resultado Na Tela

Com o voto adicionado é preciso apresentar ao visitante os resultados da enquete.



  $busca_total = mysql_query("SELECT * FROM enquete WHERE id='$id_pergunta'");
  
  $resultado = mysql_fetch_array($busca_total);
  extract($resultado, EXTR_PREFIX_ALL, 'e');
  $total = $e_op01_n + $e_op02_n + $e_op03_n;
  echo '<p><strong>Obrigado por votar! Veja o resultado parcial:</strong></p>';
    
  echo '<p>'.$e_pergunta.'</p>';
  
  echo '<p>'.$e_op01. ': '.$e_op01_n. ' votos</p>';
  echo '<p>'.$e_op02. ': '.$e_op02_n. ' votos</p>';
  echo '<p>'.$e_op03. ': '.$e_op03_n. ' votos</p>';
  echo '<p>Total de votos: '.$total.'</p>';

É feita uma busca pelos registros com a id da pergunta submetida e extraído o resultado. Como já utilizamos o extract anteriormente no código, para evitar problemas com as variáveis, é adicionado um prefixo nas variáveis extraídas.

Na linha seguinte é criada uma variável para receber a soma dos votos das três opções. Um agradecimento pelo voto é mostrado e segue a pergunta com as opções e os respectivos votos. Finalizando com o total de votos.

Conclusão

O código completo é este



<?php
if (isset($_COOKIE['enquete_php']))
{
  exit ('<p>Você já votou nesta enquete.</p>'.$_COOKIE['enquete_php']);    
} else {
  setcookie('enquete_php',$_SERVER['REMOTE_ADDR'],time()+8640;
  $opcao = strip_tags($_POST['opcao']);
  $id_pergunta = $_POST['id_pergunta'];
  $id_pergunta = filter_var($id_pergunta, FILTER_SANITIZE_NUMBER_INT);
  
  if ($id_pergunta!='' and $opcao!='')
  {
    include('db.php');
    $consulta = mysql_query("SELECT * FROM enquete WHERE id='$id_pergunta'") or die(mysql_error());
    if (mysql_num_rows($consulta)>0)
    {
      $query = mysql_fetch_array($consulta);
      extract($query);
      switch($opcao)
      {
        case "op01";
        $voto = $op01_n + 1;
        mysql_query("UPDATE enquete SET op01_n='$voto' WHERE id='$id_pergunta'");
        break;
    
        case "op02";
        $voto = $op02_n + 1;
        mysql_query("UPDATE enquete SET op02_n='$voto' WHERE id='$id_pergunta'");
        break;
    
        case "op03";
        $voto = $op03_n + 1;
        mysql_query("UPDATE enquete SET op03_n='$voto' WHERE id='$id_pergunta'");
        break;
      }
    }
      
    $busca_total = mysql_query("SELECT * FROM enquete WHERE id='$id_pergunta'");
    
    $resultado = mysql_fetch_array($busca_total);
    extract($resultado, EXTR_PREFIX_ALL, 'e');
    $total = $e_op01_n + $e_op02_n + $e_op03_n;

    echo '<p><strong>Obrigado por votar! Veja o resultado parcial:</strong></p>';
    
    echo '<p>'.$e_pergunta.'</p>';
    
    echo '<p>'.$e_op01. ': '.$e_op01_n. ' votos</p>';
    echo '<p>'.$e_op02. ': '.$e_op02_n. ' votos</p>';
    echo '<p>'.$e_op03. ': '.$e_op03_n. ' votos</p>';
    echo '<p>Total de votos: '.$total.'</p>';
  }
}
?>

Aprenda a adicionar animação ao resultado da enquete neste tutorial: Adicionar Animação No Resultado Da Enquete / Votação

Download do código usado neste tutorial: Criar Enquete / Votação Com PHP

Be Sociable, Share!

7 Comentários

  1. Emer

    Primeiramente, parabéns pelo site que apresenta um conteúdo de grande valia, principalmente para quem assim como eu está iniciando em PHP. Segui o tutorial passo a passo, os dados estão a ser computados no banco de dados, mas quando a mensagem com o total de votos se revela, abaixo também é puxada a estrutura de meu banco de dados. O que será que estou fazendo errado? Como escondo os dados mostrados abaixo? Agradeço a atenção!

    {"0":"1","id":"1","1":null,"pergunta":null,"2":"Windows XP","op01":"Windows XP","3":"2","op01_n":"2","4":"Windows 7","op02":"Windows 7","5":"4","op02_n":"4","6":"Linux","op03":"Linux","7":"3","op03_n":"3","8":"Mac OX","op04":"Mac OX","9":"0","op04_n":"0","10":"Outro","op05":"Outro","11":"0","op05_n":"0"}

  2. Claudvan

    Como cadastrar a pergunta e as opções que eu nâo acertei

  3. gabriel

    ola…eu gostaria de saber como faço pra fazer tipo um bolão de apostas de resultados de futebol,entao como faço e oque uso? pra saber o nome dos vencedores sabe,colocar 10 jogos e saber qual participante acertou mais. espero ajuda

  4. queria saber o lugar onde bota esse codigo e se da no blogger ??

  5. gostei muito do site….parabéns!

  6. Felipe Thiago

    Boa tarde,fiz a configuração porem como colo para aparecer as fotos,botos e imagem para votação???
    aonde devo cadastrar os votos???
    Não estou entendendo como cadastrar a enquete.
    Obrigado
    Muito bom o tutorial.

Participa! Comenta...