Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]podwójne wykonanie skryptu
Forum PHP.pl > Forum > Przedszkole
lordvanyuri
Witam, w php jestem początkujący i nie znam wielu spraw. Poniższy problem już analizowałem jak sie tylko da i nic. Nie rozumiem gdzie jest błąd.

Chodzi o podwójne wykonanie skryptu. Dotyczy to komentarzy i np. głosowania.

Na stronie A jest OBIEKT, który można skomentować i ocenić na + i -.
Z bazy danych jest odczytywana odpowiednia wartość i wyświetlana.

Głosowanie.
Chcąc zagłosować np. na +. Klika się w link www.nazwa.pl/glosuj.php?id=12&akcja=plus

Na stronie glosuj.php jest prosty skrypt, który ma tylko zwiększyć wartość o jeden, a czasem zwiększa o 2. Dlaczego?
I to tylko zazwyczaj za pierwszym razem, bo dalej poruszając się po stronie, sytuacja się normalizuje i już działa poprawnie.
Oto skrypt na stronie glosuj.php:
  1. <?php
  2. [b]$akcja=$_GET['akcja'];
  3. $id=$_GET['id'];[/b]
  4.  
  5. [b]if ($akcja=='plus') {
  6. $wynik=mysql_query("UPDATE pytania SET glos=glos+1 WHERE id='$id'");
  7. }[/b]
  8.  
  9. [b]if ($akcja=='minus') {
  10. $wynik=mysql_query("UPDATE pytania SET glos=glos-1 WHERE id='$id'");
  11. }
  12. ?>

[/b]Nic prostszego, prawda? Więc dlaczego, gdy skrypt się wykonuje, to zamiast zwiększyć/zmniejszyć wartość w bazie danych o jeden, zmienia ją o dwie jednostki?

Przy głosowaniu to tak źle nie wygląda, ale w systemie komentarzy już tak. Ponieważ dodaje mi dodatkowo jeden pusty komentarz, co już nie wygląda zbyt fajnie i estetycznie wizualnie... i go zlicza w bazie jako normalny.

O co w tym chodzi? gdzie jest błąd? Przecież ze strony z OBIEKTEM przekazuję wartość id przypisująca obiekt w bazie, oraz akcje, która identyfikuje, co ma być zrobione, a pomimo prostoty, gdzieś jest zapętlenie i czasem skrypt wykonuje się podwójne?questionmark.gifquestionmark.gif? Dlaczego?

Z góry będę wdzięczy za rozjaśnienie tej sprawy.

Pozdrawiam
TheaSiX
  1. <?php
  2. glos=glos+1
  3. ?>

CIekawi mnie co tym chcesz osiągnąć w zapytaniu.

p.s. wklej kod w tagi [ php] [ /php]
blooregard
Cytat
CIekawi mnie co tym chcesz osiągnąć w zapytaniu.

Chce inkrementować wartość w polu 'glos' o jeden.
Wyobraź sobie, że w MySQL to działa. Sprawdź, jeśli nie wierzysz.
kkuba
@lordvanyuri: kod, więcej kodu.

Tak na marginesie.. http://pl.wikipedia.org/wiki/DRY

  1. <?php
  2. $akcja = (isset($_GET['akcja']) && $_GET['akcja'] == 'plus') ? '+' : '-';
  3.  
  4. $wynik = mysql_query('UPDATE `pytania` SET `glos`=`glos`'. $akcja .'1 WHERE `id`="'. (int) mysql_real_escape_string($_GET['id']) .'" ');
  5. ?>


Nie ładniej? I zabezpieczone przed sql injection nawet.

Pozdrawiam.


//edit: jednak godzina 02:54 sprawiła, że zapomniałem jednego cudzysłowu. Już poprawione.
golaod
Pytanie właściwe jak ma ustawione przekierowania o ile ma i czy ma jakiś filtr antyfloodowy lub powtórnego oddawania głosu.
lordvanyuri
kkuba , dzięki , wkleiłem ten kod, osobiście jeszcze go nie rozumiem w pełni i dużo mi nie mówi, nie na tym etapie, wątpiłem, że będzie działał, ale działa , tylko wciąż, jeśli pierwszy raz klikam w plus, zwiększa mi o 2jednostki, a jeśłi klikam w minus zmniejsza o 2 jednostki, ale dalej już jest ok, działa o jedną, hmm.

Oto kod ze strony, na której są obiekty do oceny:
  1. <?php
  2. [b] $idget=$_GET['id'];
  3.        $wynik=mysql_query("SELECT * FROM pytania");    
  4.  
  5.        while ($wynik && $rekord=mysql_fetch_assoc ($wynik)) {
  6.        $id=$rekord['id'];
  7.        $pytanie=$rekord['pytanie'];
  8.        $koment=$rekord['koment'];
  9.        $glos=$rekord['glos'];
  10.        
  11.        if ($idget==$id) {
  12.        print '
  13.        <p align="center">
  14.        <font size="6" color="FFFF00"><b>'.$pytanie.'</b></font></p>';
  15.        
  16.        print '
  17.      <p> <center>
  18.      <a href="glosuj.php?id='.$idget.'&akcja=plus">
  19.      <img border="0" src="plus3v.png" width="250" height="85"></a>&nbsp;&nbsp;
  20.      <a href="glosuj.php?id='.$idget.'&akcja=minus">
  21.      <img border="0" src="minusv.png" width="250" height="85"></a></p>
  22.      <p> <font size="4">Głosów: </font> <b><font size="5" color="#FFFFFF">'.$glos.'</font></b></center></p>';
  23.      }
  24. }[/b]
  25. ?>


na stronie glosuj.php jest to co zaproponował kkuba i to co wcześniej zamieściłem - i wciąż przy pierwszym kliknięciu nalicza podwójnie. I jak to wygląda? pewnie zalatuje grafomanią.
peter13135
weź to daj w tagi php, bo nie idzie tego czytać

co do problemu.... to lepiej zrób sobie na sesjach

czyli na samym początku dajesz

  1. <?php
  2. ?>


i po dodaniu rekordu dajesz
  1. <?php
  2. $_SESSION['time']=time();
  3. ?>


no i rekord ma sie dodawać tylko wtedy gdy time() jest większe od $_SESSION['time'] np o 30 sekund, zrobisz to za pomoca if'a w podobny sposób
  1. <?php
  2. if(time()-$_SESSION['time']>30/*lub dowolna inna wartosc*/) {//tutaj kod który zwiększa o 1}
  3. ?>
golaod
Chyba trochę Peter przesadziłeś z wyjaśnieniem tej sesji komuś kto wygląda jakby nic nie rozumiał (co widać po tym jak wstawia kod na forum).

Lord wrzuć oba pliki - tylko CAŁE:
1. ten który wyświetla linki do głosowania czy czego tam
2. to co przyjmuje dane by zagłosować

Powtarzam...CAŁE smile.gif
lordvanyuri
Ok, więc nadrabiając zaległości (już wrzucę kod w tagach)

kod na stronie pytanie.php:
  1. <?php
  2. $idget=$_GET['id'];
  3.        $wynik=mysql_query("SELECT * FROM pytania");    
  4.  
  5.        while ($wynik && $rekord=mysql_fetch_assoc ($wynik)) {
  6.        $id=$rekord['id'];
  7.        $pytanie=$rekord['pytanie'];
  8.        $koment=$rekord['koment'];
  9.        $glos=$rekord['glos'];
  10.        
  11.        if ($idget==$id) {
  12.        print '
  13.        <p align="center">
  14.        <font size="6" color="FFFF00"><b>'.$pytanie.'</b></font></p>';
  15.        
  16.        print '
  17.      <p> <center>
  18.      <a href="glosuj.php?id='.$idget.'&akcja=plus">
  19.      <img border="0" src="plus3v.png" width="250" height="85"></a>&nbsp;&nbsp;
  20.      <a href="glosuj.php?id='.$idget.'&akcja=minus">
  21.      <img border="0" src="minusv.png" width="250" height="85"></a></p>
  22.      <p> <font size="4">Głosów: </font> <b><font size="5" color="#FFFFFF">'.$glos.'</font></b></center></p>';
  23.      }
  24. }
  25. ?>

wyświetlenie pytania o konkretnym id i poniżej tego dwie akcje, głos na plus i na minus.
Poniżej też są komentarze, ale jak się w głosowaniu wyjaśni dlaczego się podwójnie wykonuje, to będzie podobnie w komentarzach.

Po kliknięciu na jedną z akcji, plus lub minus przechodzi się na strone glosuj.php, gdzie jest tylko mały fragment w php:

  1. <?php
  2. $akcja=$_GET['akcja'];
  3. $id=$_GET['id'];
  4.  
  5. if ($akcja=='plus') {
  6. $wynik=mysql_query("UPDATE pytania SET glos=glos+1 WHERE id='$id'");
  7. }
  8.  
  9. if ($akcja=='minus') {
  10. $wynik=mysql_query("UPDATE pytania SET glos=glos-1 WHERE id='$id'");
  11. }
  12.  
  13. $napis="Twój głos został naliczony";
  14. $zobacz="<a href=pytanie.php?id=$id>$napis</a>";
  15. echo ("$zobacz");
  16. ?>


To jest mały portalik, na podstawie którego chce się nauczyć PHP, ale nie mogę przejśc dalej jak ten szczegół siedzi mi na głowie. Najczęściej zdarza się podwójne nabicie, głosu czy też komentarza przy pierwszej podjętej akcji, dalej odbywa się to normalnie.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.