Décompte d'un montant avec mise a jour coté server

onHellworld - 19 avril 2013 à 08:56
Gigatrappeur Messages postés 226 Date d'inscription lundi 6 mai 2013 Statut Membre Dernière intervention 3 juillet 2014 - 7 mai 2013 à 09:51
Bonjour,
Je vais vous exposé mon problème car je ne trouve pas de solutions me satisfaisant.

J'aimerai faire un compte d'un montant que l'ont peu arrêter à tout moment. En gros un sorte d'enchère automatique mais à l'envers.
En gros on un a prix (exemple 344.-) et chaque secondes le prix perd 0.05 cts. La page affiche donc un "décompteur" automatique.

En dessous nous avons un bouton qui permet d'arreter le compteur et d'acheter le produit au prix ou le décompte est arrivé. Pour tous les autres visiteurs a partir de ce moment la, l'article est concidèré comme vendu donc le compteur s'arrete et un message "vendu" s'affiche au prochain refresh.

Voila l'idée.

La solution que j'ai reussi a mettre en place c'est un script qui execute une page TOUTE LES SECONDES qui elle va lire dans la DB le montant actuel, l'affiche et fait un update du montant - 0.05. De cette facon lorsque l'article est acheté, je peux mettre a jour la table avec un tag et arreter le compteur pour els autres visiteurs. Sauf que 2 requet (select, puis update) chaque seconde, multipilé par le nombre de visiteur ca fait que ca suit pas ...

Donc ma question est, quelle est la solution pour ce genre de chose ? j'ai penser a bosser avec des timestamp, faire un select la 1ere fois et décrémenter mais je n'ai aucun moyen de cette fois de dire a tous les visiteurs quand l'article est vendu. Il faut bien que j'interoge la DB... je vois vraiment pas comment faire !

Est-ce qu'il y a des personnes qui ont des idées ?

Je met ci-dessous le code que j'ai pour l'instant et qui fonctionne pour que vous voyez plus en détail.
Merci infiniment a celui ou ceux qui me metteront sur la bonne voie !

Bonne journée.
David

SCRIPT QUI EXECUTE LA PAGE SQLRequestEchere.php CHAQUE SECONDE
function getXMLHttpRequest() {
    var xhr =  null;
    if (window.XMLHttpRequest || window.ActiveXObject) {
        if (window.ActiveXObject) {
            try {
                xhr = new ActiveXObject("Msxml2.XMLHTTP");
            } catch(e) {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
        } else {
            xhr = new XMLHttpRequest();
        }
    } else {
       // alert("Erreur : XMLHttpRequest non prit en charge !");
        return null;
    }
    return xhr;
}
 
function ajax(url) {
    this.xhr = getXMLHttpRequest();
    this.xhr.open('GET', url, true);
    this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    this.xhr.send();
}
 
function afficher() {
    var temp = new ajax('modules/SQLRequestEchere.php');
    temp.xhr.onreadystatechange = function() {
        if(temp.xhr.readyState 4 && (temp.xhr.status 200 || temp.xhr.status == 0)) {
            document.getElementById('resultat').innerHTML = temp.xhr.responseText;
        } else if(temp.xhr.status >= 400) {
           // alert('Erreur : Affichage de la page impossible !');
        }
    }
    setTimeout("afficher();", 2000);// Temps rafrechissement --> 5000ms =  5s
}


PAGE SQLRequestEchere.php QUI FAIT SELECT, UPDATE DU MONTANT
<?PHP 
include('../include/connexion_db.php');
   	include('../include/variablesGlobales.php'); 
  
$query   "SELECT ENC_MONTANT, ENC_REMPORTE FROM enchere WHERE ENC_ID '0'";
$result = mysql_query($query);
$row = mysql_fetch_row($result);
$montant = $row[0];
$reporte = $row[1];	

$montantToAffiche = $montant;
$montant = $montant - 0.05;	   

if ($reporte == "")
{
echo "".$montantToAffiche." CHF";	

$queryImage "UPDATE enchere SET ENC_MONTANT '$montant' WHERE ENC_ID = '0'";
$resultImage = mysql_query($queryImage);
}	
else
echo "<script language='javascript' type='text/javascript'>\n
 window.location.replace('index.php?lang=$lang');\n
 </script>";


include('../include/deconnexion_db.php');
?>

1 réponse

Gigatrappeur Messages postés 226 Date d'inscription lundi 6 mai 2013 Statut Membre Dernière intervention 3 juillet 2014 1
7 mai 2013 à 09:51
Bonjour,

Ton code pose un problème :
- A chaque fois que tu execute "SQLRequestEchere.php", tu décrémente le montant. Ce qui veut dire que si 15 clients appellent ta page en même temps, tu va décrémenter de 15*0.05.

Si tu veux que ton système soit un minimum sécurisé, il faut gérer le compteur du côté serveur (donc PHP).
Je pense que l'idée dans timestamp est bonne.

Il faut que tu stocke le timestamp lors de la mise en vente de ton produit.
A chaque fois que l'on te demande le montant, tu le calcul :
$montant = $montant_original - (time() - $timestamp_stocke_en_bdd) * 0.05;



Pour ce qui est du côté client, il faut arriver à avoir le même montant en même temps, sinon cela fausserait le résultat.

Le but serait de :
- une fois la page html chargé dans le navigateur du client, décompter et affiché ce décompte (sans aucun appel serveur).
- lorsque le client clique sur le bouton, on envoie une requête XHR pour indique au serveur d'arrêter le décompte et pour indiquer que le produit est vendu.
- en parallèle, il faut interroger le serveur toutes les X secondes, pour savoir si le produit est vendu.

Tu n'a donc plus de requête update à faire pour savoir si un produit est toujours en vente ou pas.

Cordialement,
Gigatrappeur
0
Rejoignez-nous