Autor Zpráva
nigdo
Profil
Zdravím,
mám takový pokusný php script na počítání návštěvnosti (lépe řečeno počet zobrazení), ale vždy když chci přičíst další zobrazení, tak se mi přičtou 3 místo 1. Měl jsem to v udělané jen v PHP se zápisem do souborů, tam to dělalo tuto chybu, tak jsem to zkusil v mysql, ale chyba stále přetrvává. Zkoušel jsem tam dát +2, pak to přičetlo 6; když jsem dal -1, tak to odečetlo 3. Nevíte někdo, co dělám špatně? ($b je název, který zjišťuji nad tím)
mysql: (tabulka se jmenuje pocet_zobrazeni a má 2 sloupce: název a počet)
mysql_query ("USE mojedatabaze") or exit ("Chyba v dotaze: ".mysql_error());
$vypis = mysql_query("SELECT * FROM pocet_zobrazeni"); 
while ($polozka = mysql_fetch_array($vypis)) {
if ($polozka["nazev"] == $b)  {$nova = $polozka["pocet"]+1; mysql_query("UPDATE pocet_zobrazeni SET pocet = '$nova' WHERE nazev = '$b' LIMIT 1") ;};
echo $polozka["nazev"]." - ".$polozka["pocet"]."<br>\n"; };
mysql_query ("exit");

php:
$jmeno2 = "pocitadlo/".$b.".txt";
$soubor2 = fopen($jmeno2, "a"); 
fclose($soubor2); 
$soubor2 = fopen($jmeno2, "r+"); 
$pocet2 = fread ($soubor2, 10);
$pocet2++ ; //zkoušel jsem i normálně +1
echo $pocet2;
rewind ($soubor2);
fwrite($soubor2, $pocet2);
fclose($soubor2); 
Taps
Profil
nigdo:
pokud se skript týká jen jedné aktualizace řádku tak nesmíš používat cyklus
zkus to nějak takto
mysql_query ("USE mojedatabaze") or exit ("Chyba v dotaze: ".mysql_error());
$vypis = mysql_query("SELECT * FROM pocet_zobrazeni where nazev='$b'"); 
$polozka = mysql_fetch_array($vypis);
if ($polozka["nazev"] == $b) 
  {
mysql_query("UPDATE pocet_zobrazeni SET pocet = pocet+1 WHERE nazev = '$b' LIMIT 1") ;}
echo $polozka["nazev"]." - ".$polozka["pocet"]."<br>\n";
 }
mysql_query ("exit");

nigdo
Profil
Taps:
problém stále přetrvává
zkoušel jsem to na serveru i na localhostu, ale není mezi tím rozdíl
zkusil jsem to znovu od nuly a šlo to takhle: 1,2,5,8, ... , 14, 16, 18, 21, 24 - takže si to dělá co chce, ale nakonec se to ustálí na +3
Keeehi
Profil
$b = 'nějaký text';
$kolik = 1; // kolik se má přičíst
mysql_select_db('mojedatabaze', $link) or exit ("Chyba v dotaze: ".mysql_error());
mysql_query("UPDATE pocet_zobrazeni SET pocet = pocet+$kolik WHERE nazev = '$b' LIMIT 1") ;
okolojdouci
Profil *
nigdo:
Hledáš nějakou složitost tam, kde není.

$pocet = mysql_result(mysql_query("UPDATE pocet_zobrazeni SET pocet = pocet+1 WHERE nazev = '".$b."'"), 0);


Toto k započítání stačí. Jestli to započítá víckrát, tak to prostě znamená, že to víckrát voláš.
Taps
Profil
nigdo:
tak kod jsem ještě trošku upravil
okolojdouci
Profil *
ech, pardon. Keeehi byl jednak rychlejší a jednak to moje není úplně ideální.
nigdo
Profil
je to divný, pořád to blbne
tohle je jediné místo, kde pracuji s databází
kdysi jsem už měl problém se jquery, tak jsem ji zkusil odmazat, a bez ní to přičítá 2, když jsem ji přidal, tak znovu +3; pak jsem zkusil smazat úplně všechny scripty a přičítalo to 2
celý kód vypadá takhle:
$b = "nějaký text";
define ("DB_HOSTITEL", "*hostitel*");
define ("DB_UZIVATEL", "*uživatel*");
define ("DB_HESLO", "*heslo*");
define ("DB_NAZEV", "mojedatabaze");
$sql1 = mysql_connect(DB_HOSTITEL, DB_UZIVATEL, DB_HESLO); 
$sql2 = mysql_select_db(DB_NAZEV); 
if (!$sql1 or !$sql2) echo "Nelze se připojit k databázi.";

mysql_query ("USE mojedatabaze;") or exit ("Chyba v dotaze: ".mysql_error());
$vypis = mysql_query("SELECT * FROM pocet_zobrazeni where nazev='$b'"); 
$polozka = mysql_fetch_array($vypis);
if ($polozka["nazev"] == $b) 
  {
mysql_query("UPDATE pocet_zobrazeni SET pocet = pocet+1 WHERE nazev = '$b' LIMIT 1") ;}
echo $polozka["nazev"]." - ".$polozka["pocet"]."<br>\n";

mysql_query ("exit");


Edit: ještě jsem zkusil smazat úplně celou stránku a nechat tam jen tohle, pak to přičítá 2
Keeehi
Profil
řádky 10-18 nahraď řádky 2-4 z [#4]
Kalda
Profil
[#8] nigdo

Asi moc nevyřeším problém, ale mám pár poznámek k danému kódu:

Otevření a zavření MySQL
Řádek 9 - to dělá prakticky dtto jako řádek 6, a proto není řádek 9 potřeba
Řádek 17 - lepší použít: if($sql1) mysql_close($sql1) - v tom případě i PHP totiž ví, že se už spojení uzavřelo

Podmínka u MySQL:
Řádek 11 vrátí ty řádky v Mysql, kde je nazev rovny $b. Přitom řádek 12 může vrátit chybu, pokud v databázi chybí název $b. Řádek 13 pak kontroluje, zda je to opravdu vráceno - doporučoval bych tu celou podmínku nějak upravit třeba na počet řádků vrácených z MySQL - mysql_num_rows

Řádek 16 - asi víš, ale jen pro upřesnění - vrací to hodnotu PŘED přičtením toho počítadla...

Tj. upravil bych to asi takto:
$b = "nějaký text";
define ("DB_HOSTITEL", "*hostitel*");
define ("DB_UZIVATEL", "*uživatel*");
define ("DB_HESLO", "*heslo*");
define ("DB_NAZEV", "mojedatabaze");
$sql1 = mysql_connect(DB_HOSTITEL, DB_UZIVATEL, DB_HESLO); 
$sql2 = mysql_select_db(DB_NAZEV); 
if (!$sql1 or !$sql2)
{
  echo "Nelze se připojit k databázi.";
} else
{
  $vypis = mysql_query("SELECT * FROM pocet_zobrazeni where nazev='" . mysql_real_escape_string($b) . "' LIMIT 1"); 
  if (mysql_num_rows($vypis) > 0) 
  {
    $polozka = mysql_fetch_array($vypis);
    mysql_query("UPDATE pocet_zobrazeni SET pocet = pocet+1 WHERE nazev = '" . mysql_real_escape_string($b) . "' LIMIT 1") ;
    echo $polozka["nazev"]." - ".$polozka["pocet"]."<br>\n";
  } else
  {
    echo "Položka: '" . HTMLSpecialChars($b) . "' není v počítadle";
  }
}
if($sql1) mysql_close($sql1);


Pokud Ti to i stále bude připočítávat více jak 1, tak si někam hoď nějaké ECHO, které Ti bude logovat vůbec spuštění této části skriptu, protože je možné, že to přes nějaký include apod. spouštíš opakovaně.
nigdo
Profil
Tak jsem to vyzkoušel vše, co jste mi poradili. Na stránce mám pouze tento script. Původně jsem to do indexu includoval (byl tam jen ten include); teď jsem to zkusil přímo v indexu, ale stále se přičítají 2, pouze když použiju tohle:
$sql1 = mysql_connect(DB_HOSTITEL, DB_UZIVATEL, DB_HESLO); 
$sql2 = mysql_select_db(DB_NAZEV); 
if (!$sql1 or !$sql2)
{
  echo "Nelze se připojit k databázi.";
} else
{
  $kolik = 1;
  mysql_select_db('mojedatabaze', $link) or exit ("Chyba v dotaze: ".mysql_error());
  mysql_query("UPDATE pocet_zobrazeni SET pocet = pocet+$kolik WHERE nazev = '$b' LIMIT 1") ;
  echo "funguju"; //nevypíše se
};
if($sql1) mysql_close($sql1);

tak se na localhostu přičte 1, ale vyskočí mi tam notice a warning:
Notice: Undefined variable: link in D:\Programy\EasyPHP-5.3.3\www\index.php on line 12
Warning: mysql_select_db() expects parameter 2 to be resource, null given in D:\Programy\EasyPHP-5.3.3\www\index.php on line 12
Chyba v dotaze:

ale na serveru (wz.cz) vyskočí warning a nic se nepřičte:
Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link resource in /3w/wz.cz/c/---/index.php on line 32
Chyba v dotaze:

Zřejmě se ten script přeruší, ale na serveru bude jiné nastavení.

Edit: když tam odstraním ten exit, tak to projde celý skript a přičtou se 2 a vypíše mimo jiné funguju
Keeehi
Profil
$link zaměňte za $sql1

A teď k logice - ve scriptu nemáte žádný cyklus, nebo goto, takže se každý řádek může provést pouze jednou. Dále v tom dotazu je na konci LIMIT 1 - Provede se pouze jeden update.
Takže buď ho vícekrát includujete (třeba v cyklu a ani si to neuvědomujete), nebo je o ten soubor vícekrát požádáno (např. ajaxem) a nebo máte v DB nějaký trigger. nic jiného mě nenapadá.
nigdo
Profil
Mám pouze soubor index.php, v něm tohle a nic jiného:
<?php $b = "text";
define ("DB_HOSTITEL", "*hostitel*");
define ("DB_UZIVATEL", "*uživatel*");
define ("DB_HESLO", "*heslo*");
define ("DB_NAZEV", "mojedatabaze");
$sql1 = mysql_connect(DB_HOSTITEL, DB_UZIVATEL, DB_HESLO);
$sql2 = mysql_select_db(DB_NAZEV);
if (!$sql1 or !$sql2)
{ 
  echo "Nelze se připojit k databázi.";
} else
{ 
  $kolik = 1;
  mysql_select_db('mojedatabaze', $sql1);
  mysql_query("UPDATE pocet_zobrazeni SET pocet = pocet+$kolik WHERE nazev = '$b' LIMIT 1") ;
};
if($sql1) mysql_close($sql1);
?>

Tím myslím odpadají všechny možnosti kromě trigger (což jsem jsem do teď nevěděl, co je, našel jsem si to na wiki, z čehož vyplývá, že jsem ho vědomě nevytvořil a myslím, že ani nevědomě, protože jsem nic takového nedělal) používám phpmyadmin, jde tam nějak zjistit, jestli je něco takového vytvořeno?
Edit: ještě jsem to zapomněl vyzkoušet na severu a tam to funguje tak jak má, tedy +1; na localhostu mi to stále přičítá 2
nigdo
Profil
Malý dotaz: můžou být v názvu ($b) čárky a pomlčky?
okolojdouci
Profil *
nigdo:
můžou být v názvu ($b) čárky a pomlčky?

Můžou, i když není košér používat takový sloupec jako klíč.
Ale zpátky k chybě. The truth is out there. Hledej chybu jinde, tady není.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0