Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Sivun latausten lasku

Sivun loppuun

dartvaneri [22.12.2011 21:59:58]

#

Hei!
Tuli pieni probleema kun tein yksin kertaisen latausten laskian. Ongelma on siinä, että se laskee kaksi latausta, kun kerran lataan sivun. Koodi on seuraavanlainen:

<?php
			$kysely = $yhteys->prepare("UPDATE kavijat SET lataukset = (lataukset + 1) WHERE id = 1;");
			$kysely->execute();

?>

Tämä ko. koodi on header osiossa. Mikä menee pieleen?

edit.
Viiden päivitykse jälkeen listaus näytti tältä:

id      aika
1	2011-12-22 22:11:18
2	2011-12-22 22:11:18
3	2011-12-22 22:11:19
4	2011-12-22 22:11:20
5	2011-12-22 22:11:20
5	2011-12-22 22:11:20
7	2011-12-22 22:11:21
8	2011-12-22 22:11:21
9	2011-12-22 22:11:22

Ensin tuli toi id 1. Sitten kaksi kerrallaa noi seuraavat.

Triton [22.12.2011 22:18:58]

#

Jos kerran on tarkoitus tallentaa jokainen sivulataus sinne tietokantaan, niin eikö sillon olisi järkevää käyttää yhtä INSERT-lausetta rivin kirjoittamiseen ja yhtä SELECT-lauseketta rivien lukumäärän hakemiseen? Tuo sun UPDATE-lause vaikuttaa varsin oudolta...

Edit. Ja sillä ei ole mitään väliä, että missä kohtaa tuo sun PHP-skriptisi on HTML:n suhteen, koska PHP suoritetaan ennen HTML:ää...

The Alchemist [22.12.2011 22:20:02]

#

Koodisi ei ole äskeisenlainen. Tuo snippet ei yksinään tee yhtään mitään. Ei muutenkaan edes näytä relevantilta. Laitahan se oikea koodi näkyville.

Metabolix [22.12.2011 22:22:28]

#

Myös tuo debuggauksesi on ehkä huonoin ikinä. On ihan mahdoton analysoida mitään ongelmaa siitä, että viidestä latauksesta tulee yhdeksän riviä (siis keskimäärin 1,8 per lataus!) vieläpä niin tiheästi, ettei niistä näe, mikä on milläkin latauksella.

Ja kuten jo todettiinkin, UPDATE ei luo yhtäkään riviä, joten tuolla tulosteella ei ole mitään tekemistä oman UPDATE-rivisi kanssa.

dartvaneri [22.12.2011 22:30:39]

#

Joo, ei tolla update koodilla saadakkaan tollaista systeemiä, mutta kuten näette se on editoinnin jälkeen laitettu, ja koodi, jolla tallennan sen kantaan on tässä:

<?php
	$kysely = $yhteys->prepare("UPDATE kavijat SET lataukset=(1 + lataukset) WHERE id = 1;");
	$kysely->execute();

	$ip = $_SERVER['REMOTE_ADDR'];
	$kysely = $yhteys->prepare("INSERT INTO kavijat (ip, aika) VALUES (?, NOW());");
	$kysely->execute(array($ip));

?>

Ja tämän tein havainnollistaakseni sen että mitä se tekee ja mihin aikaan.

Ps. selkeyden vuoksi poistin ton ip rivin pois tosta tuloksesta.

Edit.
Ja jos ihmettelette, miksi mulla on myös toi 'lataukset', jota toi update päivittää, niin tarkoitus on tehdä systeemi, joka laskee yhdeltä ip osoitteelta vain yhden käynni päivää kohden, mutta laskee kuitenkin kaikki sivun lataukset.

Triton [22.12.2011 22:49:04]

#

Toi sun logiikkasi menee kyllä aika päin honkia. INSERT-lauseella sä voit lisätä uuden sivulatauksen, mutta ennen sitä sun täytyy tarkistaa, että onko kys. IP jo lisätty kantaan. Jos on, päivität vierailujen lukumäärää, jos ei lisäät sen uuden rivin.

Edit.

Eli tähän tyyliin:

<?php

		$ip = $_SERVER[ 'REMOTE_ADDR' ];

		$select = $pdo->prepare( "SELECT id FROM kavijat WHERE ip = ?" );
		$select->execute( array( $ip ) );

		if ( $select->rowCount() > 0 ) ) {

			$update = $pdo->prepare( "UPDATE kavijat SET lataukset = lataukset + 1 WHERE ip = ?" );
			$update->execute( array( $ip ) );

		}
		else {

			$insert = $pdo->prepare( "INSERT INTO kavijat ( ip, lataukset ) VALUES ( ?, 1 )" );
			$insert->execute( array( $ip ) );

		}

?>

Huom. tuo ei sitten ota tuota päivää huomioon... Sen osaat varmaan tehdä itsekin?

Metabolix [22.12.2011 23:09:31]

#

Tonin ratkaisua järkevämpi tapa olisi ensin ajaa INSERT ja sen epäonnistuessa UPDATE, jotta kaksi samanaikaista sivunlataustakaan eivät voisi aiheuttaa ongelmaa. Jos riittää, että koodi toimii MySQL-kannalla, nämä voi laittaa samaankin lausekkeeseen (INSERT ... ON DUPLICATE KEY UPDATE ...). Taulussa pitäisi tietenkin olla UNIQUE KEY (ip, paiva), jotta koko idea toimii.

dartvaneri [22.12.2011 23:46:29]

#

Kiitos vastauksista, mutta olisi ihan kiva saada selville, mistä moinen johtuu?


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta