2011-01-07 16 views
10

¿Cómo puedo detectar las últimas actualizaciones realizadas en una base de datos y actualizar silenciosamente una página cuando ocurre un cambio?¿Cómo puedo actualizar una página cuando se actualiza una base de datos?

Digamos que el acceso a la base de datos se parece a:

$host = "localhost"; 
$username = "root"; 
$password = "root"; 
$db = mysql_connect($host,$username,$password) or die(mysql_error()); 
mysql_select_db('ccr') or die(mysql_error()); 

Todas las ideas y las muestras serán bienvenidos. Gracias.

Respuesta

9

Así es como recientemente implementé una solución usando jQuery.

PHP incrementa un campo en la base de datos cada vez que se produce una actualización significativa de .

<?php 

// Call this function when data changes 
function update_clients() 
{ 
    mysql_query("UPDATE pageGen SET id = id + 1 LIMIT 1"); 
} 

// Call this function to get the ID to pass to JavaScript 
function get_update() 
{ 
    $result = mysql_query("SELECT id FROM pageGen LIMIT 1"); 
    $update = mysql_result($result, 0, 'id'); 
    return $update; 
} 

?> 

Cuando se carga inicialmente a la página, rellenar una variable de JavaScript con un número de la base de datos:

<script type="text/javascript"> 
var pageGenID = 25218603 // generated by PHP 
var processUpdate = function(response) 
{ 
    if (pageGenID < response) 
    { 
     replace_current_data_with_new_via_ajax(); 
     pageGenID = response; 
    } 
} 
// Compare our Page Generate ID against that of the server 
var checkUpdates = function() 
{ 
    serverPoll = setInterval(function() 
    { 
     $.get('script_to_return_latest_pageGenID.php', 
      { lastupdate: 1 }, 
      processUpdate, 'html'); 
    }, 10000) 
}; 

// Check for updates every 10 seconds 
$(document).ready(checkUpdates); 

</script> 
+1

En primer lugar, jQuery añade camino demasiada sobrecarga para una tarea tan simple como esta. Si va por la ruta AJAX, simplemente use un objeto 'XMLHttpRequest'. Además, como dije en mi publicación, mantenga cosas como 'pageGenID' * en el lado del servidor * debido a un mayor riesgo de javascript o inyección de MySQL. – Qix

+0

en tu php necesitas repetirlo y no devolver –

+0

@OfirAttia: Sí, el eco fue hecho por el script PHP que generó el JavaScript. Debería haber dejado eso en claro. – Kalessin

0

Creo que tendrías que sondear la base de datos cuando usas PHP, PHP no existe en un proceso de larga ejecución como en el caso de un contenedor Java donde la aplicación web Java podría crear una conexión persistente (en teoría) Es probable que necesite emplear algún tipo de mecanismo de sondeo con lo cual me refiero a configurar un temporizador en Javascript o cualquiera que sea su código de cliente para hacer la solicitud periódicamente, en términos de aumentar la eficiencia para esto, si es necesario, podría crear una bandera en la tabla de usuarios y establece el indicador para indicar que la base de datos ha sido invalidada desde que el usuario realizó la última encuesta, entonces su primera verificación sería si la invalidación ha ocurrido desde que el usuario fue actualizado por última vez en lugar de enviar todo a todos todo el tiempo. Alternativamente, creo que tendrías que abandonar PHP para esta tarea.

0

Ideea:

Cuando se procesa una página con PHP, puede pasar a una bruja variable de js ha mantiene una "revisión de la base de datos actual" (un número). En la página realizas una llamada ajax una vez cada 30 segundos y una bruja recibe una nueva revisión de la base de datos actual, por así decirlo. Usted prueba esos 2 y si el que recibió de la llamada ajax es más alto, significa que necesita volver a cargar la página.

En el servidor necesita una tabla para almacenar la revisión actual, cada vez que realiza una consulta desde php establece la revisión actual +1 (en la tabla de base de datos de revisiones). Cuando recibe una llamada ajax de un cliente, lee ese número de la base de datos y lo pasa al cilent. Puede configurar un cronjob que restablecerá el contador todos los días.

1

Estrictamente hablando, esto no es posible. MySQL no dispara desencadenantes a PHP si algo se cambia. Simplemente no es posible. Además, MySQL opera usando sesiones, por lo que incluso si pudiera informar un cambio en la base de datos, tendría que usar una conexión persistente para que pueda acceder a ese tipo de activador.

Ahora, si desea ejecutar sentencias select para detectar un cambio en la base de datos, eso es diferente. Dependiendo de qué tan "nuevo" desee que sea su código (dependiendo de cuán compatible le gustaría que fuera) puede usar cualquiera de los siguientes para "sondear" una página de PHP para verificar los cambios: Comet, AJAX, a siempre marco, o la nueva clase WebSocket de HTML5.

Mientras que otros dicen usar el cliente para detectar un cambio a través de variables como una versión de base de datos almacenada en javascript, te aconsejo que dejes ese servidor simplemente porque las personas que saben cómo inyectar javascript podrán cambiar ese valor , que puede producir resultados no deseados o incluso maliciosos (incluso, dependiendo de cómo se use ese valor, las inyecciones de MySQL).

2

Esto es lo que hice, y utilicé la respuesta que marcó, pero creo que hay algunas cosas que cambiar allí. en la página principal (que desea actualizar si algo cambia en la base de datos). creé una tabla en mi configuración llamada base de datos, en esta tabla creé una fila que llamaba rowCounter. there rowCounter se está actualizando cuando los números de filas en la tabla que ha marcado han cambiado. así que mi código está en dos bloques. uno que me da el número de la configuración> rowCounter y el otro es la secuencia de comandos que me da el número actual en la tabla. si no son iguales, entonces actualizo la página.

por lo que este es el primer archivo que necesita. llamarlo
script_to_return_latest_pageGenID.php

// here you will make you connection query. 

$result = mysql_query("SELECT rowCounter FROM setting WHERE `id`='2'"); 
$update = mysql_fetch_assoc($result); 
     echo implode($update); 

    $count=mysql_query("SELECT `id` FROM log_".$datestamp."")or die(mysql_error); 
    $number = mysql_num_rows($count); 
//echo $number; 

    $countFromSetting=mysql_query("SELECT `rowCounter` FROM setting WHERE id='2'")or die(mysql_error); 
    $numberFromSetting=implode(mysql_fetch_assoc($countFromSetting)); 

    if($number != $numberFromSetting) 
     { 
      mysql_query("UPDATE setting SET `rowCounter`='$number' WHERE `id`='2'")or die(mysql_error); 

     } 


En la página principal que va a escribir los dos bloques de código que he escrito, lo pones antes del script.

$countFromSetting=mysql_query("SELECT `rowCounter` FROM setting WHERE id='2'")or die(mysql_error); 
     $numberFromSetting=implode(mysql_fetch_assoc($countFromSetting)); 

Después de este código se pone el script que va a consultar cada pocos segundos la página php, comprobar si los números no son iguales que se actualice la página.

var pageGenID = "<?php echo $numberFromSetting; ?>"; 
var processUpdate = function(response) { 


var x=response; 
//console.log(pageGenID); by removing the remarks you will see the compared numbers all the time. 
//console.log(x); 
if (pageGenID != x) 
{ 
    //replace_current_data_with_new_via_ajax(); 
    pageGenID = response; 

    window.location.reload();  
    } 
} 

var checkUpdates = function() 
{ 
    serverPoll = setInterval(function() 
    { 

$.get('script_to_return_latest_pageGenID.php', 
     { lastupdate: 1 }, 
     processUpdate, 'html'); 
    }, 5000) }; 
    $(document).ready(checkUpdates); 
0

Parece que te vendría bien algo como esto, usando un bucle while. Esto no trabajo para grandes cantidades de usuarios (probablemente accidente PHP o SQL), y en algún momento que tendrá que restablecer las variables de recuento en el script .:

<?PHP 
//initialize the variables somewhere before any of the following. do not use these 
//variables for any other purpose other than the refresh routines: 
$a==0; 
$b==0; 
//First design code within a function to refresh the database a single iteration. 
fuction refresh(){ 
    insert code here to output database; 
     } 

//Now, call function refresh in a loop at the spot in the code 
//where we want to refresh the database. where $b here is equal to 
//the number of times you want the database to automatically refresh 
//before having to reset the variables to 0. 

$b==1 
while ($b!==$a){ 
     refresh(); 
     $a==$a+1; 
     } 

?> 
Cuestiones relacionadas