• Compra una licencia de Windows 10/11 (10€) u Office (18€) al mejor precio u Office al mejor precio. Entra en este post con las ofertas
  • ¡Bienvenid@! Recuerda que para comentar en el foro de El Chapuzas Informático necesitas registrar tu cuenta, tardarás menos de 2 minutos y te dará valiosa información además de ayudarte en lo que necesites o pasar un rato agradable con nosotros.

Sitema de votacion, ajax , php y msql

urbon

Nuevo
Registrado
30 Jun 2015
Mensajes
41
Puntos
0
Buenas,

Estoy haciendo un sistema de votacion en ajax , php y msql ,ya que soy un poco inexperto en tema de programar .Quisiera saber si me podriaís ayudar.

Esto lo que tengo hecho:

Un botón:

<input type="button" id="boton" value="Cojinudo" onClick="javascript:contador()" />
<div id="countDiv"></div>

Luego un script en ajax :

function contador(){
$.ajax({
url:'contador.php',
type: 'get',
success: function (response) {
$(".countDiv").html(response);
}
});

}


También un archivo en php para contar los datos de la base de datos:

<?php
include('conf.php');

# Saber si el voto es negativo o positivo
$voto = htmlentities($_GET['voto']);

# Tomamos el id de nuestro post y vemos todas las ip que pusieron megusta
$id = (int) $_GET['id'];
$query = mysql_query("SELECT id,ips FROM post WHERE id='".$id."'",$link);
$row = mysql_fetch_assoc($query);
$ip = $row['ips'];


# Obtenemos la ip de nuestro visitante
if ($HTTP_X_FORWARDED_FOR == "") {
$ipp = getenv(REMOTE_ADDR);
}
else {
$ipp = getenv(HTTP_X_FORWARDED_FOR);
}

# Me gustas
switch($voto)
{
case "positivo";
if($query)
{
$var = explode(",", $ip);
$arr = in_array($ipp, $var);
if(!$arr)
{
mysql_query("UPDATE post SET megusta=megusta+1, ips=CONCAT(post.ips,'".$ipp.",') WHERE id='".$id."'",$link);
}
}
break;
}



?>


Y por último la bases de datos.


Esto lo que tengo yo hecho , pero si teneís una ídea mejor .


Saludos.
 
Yo la parte de BBDD la haría diferente...

Una tabla con la encuesta: ID, nombre, etc.
Una tabla con cada voto, que tiene que ser una entrada nueva: ID, ID_encuesta, IP

Es más eficiente y escalable...

Por cierto, de donde coges el voto? No veo la variable get en tu js...
 
Por la parte de HTML, no necesitas utilizar el atributo onClick, con jQuery puedes enganchar código en ese evento directamente:

Código:
$('#boton').click(function () {
	$.ajax({
		url:'contador.php',
		type: 'get',
		success: function (response) {
			$(".countDiv").html(response);
		}
	});
});

En Javascript, ¿por qué utilizas GET? Se tiende a utilizar los verbos HTTP según su significado literal: con GET lees información, con POST envías. En tu caso, aunque la funcionalidad sea la misma, la gente esperará que uses POST para enviar algo al servidor.

En PHP, puedes mejorar bastantes cosas. Primero, estas líneas te pueden dar errores en forma de "Notice: undefined index":

PHP:
$voto = htmlentities($_GET['voto']);
PHP:
$id = (int) $_GET['id'];

¿Y si los índices id y voto no están definidos? Es decir, si no se envían esas variables mediante GET, ¿qué hace tu programa? Comportamiento inesperado. Haz esto:

PHP:
$voto = null;
if (isset($_GET['voto'])) {
	$voto = htmlentities($_GET['voto']);
} else {
	exit;
}

Por ejemplo. Sin entrar a valorar que htmlentities() sea una buena forma de validar o filtrar una variable.

Segundo, la extensión mysql está deprecated desde hace tiempo. En su lugar, utiliza PDO.

Luego, ¿por qué estás recogiendo la IP del visitante como variable de entorno? ¿No te resulta más fácil acceder a ella mediante la variable superglobal $_SERVER? Además, al hacer la consulta, no estás validando ni escapando la dirección de IP que obtienes y te recuerdo que cualquier valor no escapado y/o validado puede ser utilizado para atacar tu software mediante inyección SQL. La dirección de IP no necesariamente es una dirección de IP, se pueden forjar peticiones para enviar un valor arbitrario en ese parámetro. Échale un ojo a esto: http://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php

Por otro lado, al final sólo contabilizas votos positivos. ¿No incluyes los negativos?

En cuanto a la base de datos, haz lo que te dice pabs11. CONCAT() es una operación lentísima: ¿y cuando tengas 10.000 votos? La concatenación es una operación cuyo tiempo de ejecución depende de la longitud de las cadenas que quieres concatenar. Más largo = más tiempo tarda en hacerse. Funcionará deprisa con pocos votos, pero cuando tengas muchos...

Las bases de datos relacionales funcionan mejor tratando la información de forma relacional: un voto pertenecerá a una encuesta, ergo tendrá un campo id_encuesta, un campo ip y lo que tú consideres a mayores. Pero tener un campo concatenado es una locura, y no es en absoluto relacional. Cuando quieras comprobar si una dirección de IP ya votó... Matarás al servidor.
 
Buenas,
Gracias por las ideas que me proponeis , las pondré en práctica.
 
Buenas,

He encontrado este, archivo hecho en php con esta base de datos:

<?php

/* Setting the error reporting level */
error_reporting(E_ALL ^ E_NOTICE);
include 'conf.php';

if(!$_GET['url'] || !filter_input(INPUT_GET,'url',FILTER_VALIDATE_URL)){
exit;
}

$pageID = 0;
$appreciated = 0;
$jsonArray = array();
$hash = md5($_GET['url']);
$ip = sprintf('%u',ip2long($_SERVER['REMOTE_ADDR']));


$result = $mysqli->query("SELECT id,appreciated FROM appreciate_pages WHERE hash='".$hash."'");

if($result)
{
list($pageID,$appreciated) = $result->fetch_row();
}

// El parámetro a presentar indica que hay que escribir en la base de datos

if($_GET['submit'])
{
if(!$pageID)
{

//Si la página no se ha apreciado, sin embargo,
//insertar un nuevo registro a la base de datos.

$mysqli->query("
INSERT INTO appreciate_pages
SET
hash='".$hash."',
url='".$mysqli->real_escape_string($_GET['url'])."'"
);

if($mysqli->affected_rows){

//La propiedad insert_id contiene el valor
// de la clave primaria. En nuestro caso este es también el identificador de página.

$pageID = $mysqli->insert_id;
}
}

// Escribe el voto para la DB, por lo que el usuario puede votar una sola vez

$mysqli->query("
INSERT INTO appreciate_votes
SET
ip = ".$ip.",
pageid = ".$pageID
);

if($mysqli->affected_rows){
$mysqli->query("UPDATE appreciate_pages SET appreciated=appreciated+1 WHERE id=".$pageID);

// Incrementamos el campo
}

$jsonArray = array('status'=>1);
}
else
{
// imprimimos sólo los resultados

$voted = 0;

// Ha votado el usuario?
$res = $mysqli->query("SELECT 1 FROM appreciate_votes WHERE ip=".$ip." AND pageid='".$pageID."'");

if($res->num_rows){
$voted = 1;
}

$jsonArray = array('status'=>1,'voted'=>$voted,'appreciated'=>$appreciated);
}

// Mostrar en el navegador para interpretar la respuesta como JSON:
header('Content-type: application/json');

echo json_encode($jsonArray);

?>


--
-- Estructura de tabla para la tabla páginas
--

CREATE TABLE `visitas` (
`id` int(10) unsigned NOT NULL auto_increment,
`hash` varchar(32) NOT NULL default '',
`url` text NOT NULL,
`appreciated` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `hash` (`hash`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;




--
-- Estructura de tabla para la tabla votos
--

CREATE TABLE `votos` (
`id` int(10) unsigned NOT NULL auto_increment,
`ip` int(10) unsigned NOT NULL default '0',
`pageid` int(10) unsigned NOT NULL default '0',
`dt` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `vote` (`ip`,`pageid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


Mi pregunta es la siguiente: ¿Me servirá la base de datos y el archivo php?

Saludos
 
¿Copiar y pegar? Pensaba que estabas haciéndolo por tu cuenta :uis:
 
Buenas,
No exactamente copiar y pegar , sino tener un patrón para hacerme yo mi propia base de datos y mi archivo PHP. Que he explicado mal.
 
Hola,

He hecho las bases de datos:


--
-- Estructura de tabla para la tabla `encuestas`
--

CREATE TABLE IF NOT EXISTS `encuestas` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`nombre` varchar(32) NOT NULL DEFAULT '',
`fecha` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`num_votos` int(20) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `hash` (`nombre`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;



--
-- Estructura de tabla para la tabla `votos`
--

CREATE TABLE IF NOT EXISTS `votos` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ip` int(10) unsigned NOT NULL DEFAULT '0',
`id_encuesta` int(10) unsigned NOT NULL DEFAULT '0',
`votos` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `vote` (`ip`,`id_encuesta`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Si me podrían ayudar más o menos a realizar el archivo php para contabilizar los votos.

Gracias.
 
El campo numvotos te sobra. Lo puedes contar despues.

Cuando llegue a casa te echo una mano.

Enviado desde mi X5pro mediante Tapatalk
 
La idea es que hagas una consulta primero, con un SELECT tipo esto:

"SELECT ip FROM votos WHERE ip LIKE $ip and id_encuesta = $encuesta" /* LA IP LA SACAS COMO QUIERAS, ES ALGO QUE HE USADO POCO */

Si esto devuelve null, pues insertas un nuevo voto.

INSERT id, id_encuesta,votos VALUES($ip,$id_encuesta,$voto)

Y poco más... Disculpa la sintaxis, ahora mismo no estoy centrado, estoy de vacaciones y hasta el dia 1 no me pongo a currar de nuevo :p
 
pabs11 no pasa nada, lo único era que me echarás una mano como tendría que hacer el archivo php. Una pregunta ¿ delante del SELECT tengo que poner algo?.¿ Y lo del INSERT eso lo tengo que hacer en la base de datos o en el archivo php?

Muchas gracias , por ayudarme. :)
 
¿Por qué me parece que ninguno estáis utilizando PDO? Aquí un tutorial: https://phpdelusions.net/pdo

El campo num_votos lo puedes mantener porque siempre es más rápido hacer un SELECT sobre dicho campo que un COUNT() con WHERE, especialmente si tienes muchos votos. Desnormalización por rendimiento está bien, pero para aprender olvídate de ello y hazlo mejor como te dice pabs11.

Te veo un poco pez, especialmente tras tu duda de si el INSERT lo tienes que hacer en el fichero PHP o en la base de datos... ¿Por qué no empiezas por algo aún más básico y vas ampliando? Por ejemplo, haz un script que reciba una variable por GET y que te añada, cada vez que se accede a dicho script, el valor de esa variable en una fila nueva en una tabla en la base de datos. Esto es fundamental y no lo tienes claro todavía.

Por ejemplo, deberías tener TODO claro sobre este código antes de continuar:

PHP:
<?php

if (! isset($_GET['numero'])) {
	die('Falta la variable número.');
}

$n = $_GET['numero'];

// Base de datos

$db_host = 'localhost';
$db_user = 'root';
$db_pass = '';
$db_name = 'db_prueba';

$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8", $db_user, $db_pass);

$stm = $pdo->prepare('INSERT INTO numeros VALUES (DEFAULT, :numero);');
$stm->bindValue(':numero', $n, PDO::PARAM_INT);

$stm->execute();

En tu proyecto estás metiendo muchos conceptos que si acabas de empezar se te escapan, y vas a terminar copiando y pegando sin entender nada. Si es lo que quieres yo no digo nada, pero si quieres aprender... Reitero mi consejo.
 
Uff, hace meses que no he tocado PDO en serio, y fue para un ejercicio de clase... Ni me acordaba, por eso he puesto lo primero que se me ha ocurrido, que ha sido poner la query a pelo, para que no quedara abstracto...

Enviado desde mi X5pro mediante Tapatalk
 
Pues PDO hoy en día es básico. Entiendo que utilizarlo ya introduce términos como "objetos", "métodos" y demás, pero es fundamental, porque entre otras cosas todo lo que hagas con bindParam(), bindValue() y los métodos estándar de PDO estará escapado para evitar inyección SQL. Sí, sé que puede hacerse con mysql_real_escape_string(), pero aparte de que hay que molestarse en hacerlo manualmente, como digo la extensión mysql está deprecated desde hace eones, como mínimo usad mysqli o algo :canta:
 
Pues PDO hoy en día es básico. Entiendo que utilizarlo ya introduce términos como "objetos", "métodos" y demás, pero es fundamental, porque entre otras cosas todo lo que hagas con bindParam(), bindValue() y los métodos estándar de PDO estará escapado para evitar inyección SQL. Sí, sé que puede hacerse con mysql_real_escape_string(), pero aparte de que hay que molestarse en hacerlo manualmente, como digo la extensión mysql está deprecated desde hace eones, como mínimo usad mysqli o algo :canta:
Si si, si la he usado... Pero entre que nos metimos pronto con symfony en clase (Doctrine es Dios) y que en el trabajo usamos sobretodo Magento, y me he dedicado sobretodo a la parte visual, lo tengo un poco apartado, y he tirado a poner directamente la query...

Enviado desde mi X5pro mediante Tapatalk
 
oMega_2093, yo sé que muy pez en php . Yo solo he pedido que ayuden como tengo que hacerlo, ya que nunca he usado php y es la primera vez que hago un sistema de votación para implementarlo en una página web.
 
Y te estamos ayudando, ¿no? Si he comentado que estás muy verde es precisamente para centrarnos en los conceptos que debes controlar a tu nivel, que no son ya "hacer un sistema de votos", sino que son del tipo "insertar un valor en una base de datos", o "recoger valores pasados en la URL". Es decir, de lo más básico, pero nadie nace aprendido evidentemente ;)

Sobre lo que hemos tocado hasta ahora, los enlaces que se han puesto, las técnicas que se han mencionado... plantea tus dudas y dínos en qué podemos ayudarte, pero decir que necesitas ayuda para "hacer un sistema de votos"... Es como pedir que te lo demos hecho. Así que insisto: con todo lo que se ha tocado hasta ahora, ¿qué necesitas saber? ¿Qué código tienes ahora?
 
Si claro, y yo os lo agradezco. Pero no se por dónde empezar y como empezar. :)
 
Vale ;) veamos, creo que necesitas comprender lo básico, mírate el script que escribí unos posts más arriba (#13) y trata de entenderlo. Son los conceptos mínimos que necesitas para hacer lo que quieres. ¿Trabajamos sobre ese script? Plantéanos las dudas que tengas.
 
Arriba