[PHP] Onbedoelde updates

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MuddyMagical
  • Registratie: Januari 2001
  • Laatst online: 17:32
Zit hier nu al twee dagen naar te kijken maar ik kom er echt niet achter:

Ik heb een function gemaakt die het aantal views update van een bericht.
PHP:
1
2
3
4
5
6
7
    function AddHit($id, $views) {
        $idnews = intval($id);
        $newViews = intval($views) + 1;
        
        # Updating the views
        $this->pDatabase->run_query( "UPDATE news SET views = $newViews WHERE idnews = $idnews" );
    }


Simpeler zou niet kunnen zou je denken, maar het lijkt wel of deze functie meerdere malen wordt aangeroepen bij het openen van de pagina.
Nu heb ik mijn volledige source al doorzocht op het gebruik van deze functie, maar hij wordt echt alleen maar in de index.php gebruikt.
PHP:
1
$pNews->AddHit($idnews, $NewsMessage[0][views]);

Hier wordt het id van het bericht samen met het huidige aantal views uit de database de functie ingeschopt.

Nu is het zo dat ik de query die wordt uitgevoerd bij het lezen van een bericht heb gecheckt, maar die is goed. Hierin staat netjes het gewenste aantal views en de query geeft ook geen fout. Zelfs alle queries laten echo'en, maar ook daar staat de update maar 1 keer tussen.

Nu verdenk ik mijn .htaccess van het veroorzaken van dit probleem:
code:
1
RewriteRule ^(news)/([1-9]+)/([a-z1-9-]+) index.php?news=$1&idnews=$2&title=$3 [nc]


Deze leest de URLs zoals http://URL/news/8/Bericht-2.html en pakt hieruit de 8 welke het ID van het nieuwsbericht is.
In de index wordt het bericht opgepakt zoals hieronder (nogmaals) te zien is.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
if( isset($_REQUEST['idnews']) ) {
    # Getting the id of the news requested.
    $idnews = intval($_REQUEST['idnews']);

    $NewsMessage = $pNews->GetNews($idnews);
    $pNews->AddHit($idnews, $NewsMessage[0][views]);
    ?>
    <h3><?php echo($NewsMessage[0][title]);?></h3>
    <p><?php echo($NewsMessage[0][message]);?></p>
    <?php
}
?>


De reden dat ik de .htaccess verdenk is het feit dat als ik een bericht bekijk er netjes 1 view wordt bijgezet, maar zodra ik de pagina herlaad is dat nummer opeens met nog 2 views geupdate.

[ Voor 0% gewijzigd door MuddyMagical op 19-01-2012 22:03 . Reden: Rare uitleg gewijzigd. ]


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
$NewsMessage[0][views] is altijd nog $NewsMessage[0]['views']. -> notice errors aanzetten, dan had je dat gezien.

Je kunt gewoon de query aanpassen naar:
$this->pDatabase->run_query( "UPDATE news SET views = views + 1 WHERE idnews = ". $idnews );

Als de update dan nog niet goed werkt moet je kijken of $idnews wel bevat wat jij denkt dat het zou moeten bevatten.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
MuddyMagical schreef op donderdag 19 januari 2012 @ 21:34:
Nu is het zo dat ik de query die wordt uitgevoerd bij het lezen van een bericht heb gecheckt, maar die is goed. Hierin staat netjes het aantal views+1 en de query geeft ook geen fout.
Dus hier tel je er 1 bij op en vervolgens doe je dat ook in addHit()? Goh, zou je dan vaker optellen...

Gewoon SET views = views+1 doen inderdaad, lost bovendien ook meteen een race condition op.

{signature}


Acties:
  • 0 Henk 'm!

  • MuddyMagical
  • Registratie: Januari 2001
  • Laatst online: 17:32
ReenL schreef op donderdag 19 januari 2012 @ 21:37:
$NewsMessage\[0][views] is altijd nog $NewsMessage\[0]['views']. -> notice errors aanzetten, dan had je dat gezien.

Je kunt gewoon de query aanpassen naar:
$this->pDatabase->run_query( "UPDATE news SET views = views + 1 WHERE idnews = ". $idnews );

Als de update dan nog niet goed werkt moet je kijken of $idnews wel bevat wat jij denkt dat het zou moeten bevatten.
:$
Inderdaad even gewijzigd in ['views']. Ook even de query aangepast met je suggestie. Dit verhelpt het probleem niet terwijl de inhoud van $idnews correct is. Het id van het betreffende nieuwsbericht staat hier netjes in.
Voutloos schreef op donderdag 19 januari 2012 @ 21:42:
[...]
Dus hier tel je er 1 bij op en vervolgens doe je dat ook in addHit()? Goh, zou je dan vaker optellen...

Gewoon SET views = views+1 doen inderdaad, lost bovendien ook meteen een race condition op.
Sorry, dit is een stomme zin in mijn uitleg.
Ik bedoelde te zeggen dat in de update query het stukje SET views netjes het juiste aantal views bevat. Ik zal het even aanpassen in mijn TS.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Ok, maar dan nog moet je gewoon lekker in dit soort queries altijd views=views+1 doen. Eenvoudiger en geen race conditions dus bovendien gewoon meer correct.

Wat er mis is met hoe je nu de nieuwe waarde bepaalt wordt echt in de eerste 5 minuten behandeld zodra je iets over concurrency leert. Aka (tikje bot, maar meen het wel) : als je dit advies niet opvolgt kan je beter een andere hobby/baan zoeken. ;)

{signature}


Acties:
  • 0 Henk 'm!

  • MuddyMagical
  • Registratie: Januari 2001
  • Laatst online: 17:32
Voutloos schreef op donderdag 19 januari 2012 @ 22:35:
Ok, maar dan nog moet je gewoon lekker in dit soort queries altijd views=views+1 doen. Eenvoudiger en geen race conditions dus bovendien gewoon meer correct.

Wat er mis is met hoe je nu de nieuwe waarde bepaalt wordt echt in de eerste 5 minuten behandeld zodra je iets over concurrency leert. Aka (tikje bot, maar meen het wel) : als je dit advies niet opvolgt kan je beter een andere hobby/baan zoeken. ;)
Ja zeker wel mee eens. Het is gelukkig ook niet mijn baan maar een hobby waar ik lekker aan het prutsen ben om te kijken of ik een idee werkelijkheid kan laten worden. Tis niet dat ik een cursus gedaan heb. (Zoals je merkt.. ;) )

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Gebruik je output buffering of een framework dat output buffering gebruikt en wordt je template/view meerdere keren doorlopen?

Acties:
  • 0 Henk 'm!

  • icyx
  • Registratie: Januari 2007
  • Niet online

icyx

chown -R us ./base

Voutloos schreef op donderdag 19 januari 2012 @ 22:35:
Ok, maar dan nog moet je gewoon lekker in dit soort queries altijd views=views+1 doen. Eenvoudiger en geen race conditions dus bovendien gewoon meer correct.
Ik ken PHP niet zo goed, maar is dat wel atomic?

When you think you’ve succeeded / but something’s missing / means you have been defeated / by greed, your weakness.


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
icyx schreef op vrijdag 20 januari 2012 @ 08:55:
[...]

Ik ken PHP niet zo goed, maar is dat wel atomic?
Het zit in de query, dus het is MySQL, maar ja: dat is atomair.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Misschien moet je ook eens even in je accesslog van apache kijken. Je rewrite rule is redelijk ruim waardoor een request voor bijvoorbeeld een plaatje of een favicon er ook voor kan zorgen dat dit naar je index.php gestuurd wordt. Als dat relatief tov de huidige pagina gebeurt zal ook gewoon weer de id meegestuurd worden (aangezien dat als een mapje gedefinieerd staat) en zal je code per opvragen van de pagina meerdere keren aangeroepen worden.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • icyx
  • Registratie: Januari 2007
  • Niet online

icyx

chown -R us ./base

HuHu schreef op vrijdag 20 januari 2012 @ 09:04:
[...]

Het zit in de query, dus het is MySQL, maar ja: dat is atomair.
8)7 Niet goed gelezen; ik dacht dat het PHP code was.

When you think you’ve succeeded / but something’s missing / means you have been defeated / by greed, your weakness.


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37

TheNephilim

Wtfuzzle

Ook header('Location: <url>'); kan zorgen voor extra hits waar ze niet horen. Bijvoorbeeld een redirect na het inloggen of iets dergelijks.

Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 11-09 14:44
Kan zijn dat je plaatjes hebt met een lege url. Dan doen sommige browsers een request naar de huidige pagina.

Acties:
  • 0 Henk 'm!

  • MuddyMagical
  • Registratie: Januari 2001
  • Laatst online: 17:32
Bingo.

Naar aanwijzen van Janoz even in de access log van Apache zitten kijken en daar kwam inderdaad naar voren dat er twee extra hits kwamen door de regels
HTML:
1
2
<script src="javascript/jquery-1.6.1.js"></script>
<script src="javascript/java_functions.js"></script>


Hier even bij beide /javascript van gemaakt en probleem opgelost.

Nu zit ik wel even te kijken hoe ik mijn .htaccess wat stricter kan maken zodat ik dit probleem niet meer ga hebben. B)
Pagina: 1