Peršokti į turinį
  • ŽAIDIMAI
  • , ŽAIDIMAI
  • ŽAIDIMAI

PHP - MySQLi - vartotojų lankomumo statistikos rinkimas


NTQ

Ši tema yra neaktyvi. Paskutinis pranešimas šioje temoje buvo prieš 2240 dienas (-ų). Patariame sukurti naują temą, o ne rašyti naują pranešimą.

Už neaktyvių temų prikėlimą galite sulaukti įspėjimo ir pranešimo pašalinimo!

Recommended Posts

Aprašymas:

Forumo narys apleido savo temą („PHP - svetainėje prisijungę svečiai“), todėl nusprendžiau patobulinti jo kodą, galbūt kai kuriems vis dar pravers.

Šis nedidelis papildinys suteikia galimybę rinkti įvairius vartotojų duomenis, sudaryti lankomumo statistiką ar integruoti į naudotojų sistemą. Visa informacija bus saugoma duomenų bazėje.

Tipas: tik unikalūs įrašai išsaugomi, siekiant neapkrauti duomenų bazės, tačiau galite redaguoti ir pasidaryti pagal save.

Pakeitimai:

  • Perrašytas, pataisytas ir patobulintas kodas;
  • našumo patobulinimai;
  • pakeista struktūra, daug kas supaprastinta;
  • pridėta daugiau renkamų duomenų tipų;
  • skriptas automatizuotas, t. y. reikia tik teisingai prijungti prie duomenų bazės ir paleisti. Jeigu reikiamos lentelės nebus, sukurs savaime.

Papildoma informacija:

  • Pagal numatytus nustatymus, didžiausias vartotojų skaičius yra 2,147,483,647 (įskaitant paspaudimų, tai taikoma individualiai). Jeigu Jūsų tai netenkina, galite bet kada pasikeisti;
  • $setting_1“ - nurodo, kiek sekundžių turi praeiti, kai vartotojas bus pažymėtas kaip neaktyvus (atsijungęs). Numatytasis parametras yra 300 sekundžių, t. y. 5 minutės;
  • kada sėkmingai paleisite skriptą, rekomenduoju uždėti komentarą ant tos kodos dalies, kuri atsakinga už lentelės egzistavimo tikrinimą ir sukūrimą (pažymėta specialiu komentaru: „- Patikrinimas prasideda -“);
  • galite sujungti šią lentelę su naudotojų lentele (po pirminio rakto pridėti: „visitor_id“).

 

Ekrano užfiksavimai:

1. Vaizdas, paleidus pirmąjį kartą skriptą: lentelė nebuvo rasta, todėl automatiškai sukuriama.

sg0.png

2. Vaizdas duomenų bazėje: vartotojas apsilanko pirmąjį kartą.

sg1.png

3. Vaizdas duomenų bazėje: vartotojas apsilanko antrąjį kartą.

sg2.png

4. Vaizdas duomenų bazėje: praeina daugiau nei 300 sekundžių, vartotojas atžymimas.

sg3.png

 

Kodas:

*ištraukimas iš duomenų bazės yra integruotas, tačiau pateiksiu dar „SQL“ kodą (po skripto).

<?php

# Duomenų bazės prisijungimo informacija.
define('DATABASE_SERVER', '127.0.0.1');
define('DATABASE_USER', 'root');
define('DATABASE_PASSWORD', '');
define('DATABASE_NAME', 'database');

# Prisijungimas prie duomenų bazės.
$mysqli_connect = new mysqli(DATABASE_SERVER, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME);

# Prisijungimas nepavyko, atvaizduojame klaidą.
if ($mysqli_connect->connect_errno) {
	echo 'Script cannot connect to the MySQL server.';
	exit;
}

# Nustatome prisijungimo koduotę (pasirinkau numatytąją).
if ($mysqli_connect->set_charset('latin1') === false) {
	echo 'Script failed to set MySQL charset.';
	exit;
}

# - Patikrinimas prasideda -

# Patikriname, ar reikiama („visitors“) lentelė egzistuoja.
$mysqli_select = $mysqli_connect->query("SELECT `table_name` FROM `information_schema`.`tables` WHERE `table_schema` = '".DATABASE_NAME."' && `table_name` = 'visitors';");

# Jeigu ne, galime tęsti.
if ($mysqli_select->num_rows === 0) {

# Nurodome „SQL“ kodą, kurį reikės įvykdyti.
$mysqli_code = '
CREATE TABLE IF NOT EXISTS `visitors` (
`id` int(75) PRIMARY KEY AUTO_INCREMENT,
`referer` varchar(250) NOT NULL,
`first_page` varchar(250) NOT NULL,
`last_page` varchar(250) NOT NULL,
`clicks` int(75) NOT NULL,
`online` tinyint(1) NOT NULL,
`language` varchar(150) NOT NULL,
`ip` varchar(150) NOT NULL,
`first_browser` varchar(250) NOT NULL,
`last_browser` varchar(250) NOT NULL,
`browser_language` varchar(250) NOT NULL,
`track_user` tinyint(1) NOT NULL,
`first_visit_time` int(75) NOT NULL,
`last_visit_time` int(75) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
';

# Įvykdome. Komentare parašytas kodas, jeigu norėsite įvykdyti daugiau „SQL“ užklausų negu vieną.
// $mysqli_query = $mysqli_connect->multi_query($mysqli_code);
$mysqli_query = $mysqli_connect->query($mysqli_code);

# Reikia pauzės, jog spėtų sukurti lentelę(-es), jeigu perkrautumėte anksčiau laiko, lentelė nebūtų pabaigta ir skriptas parodytų klaidą. Gali taip ir nenutikti dėl vienos.
sleep(5);

# Patikriname, ar pavyko įvykdyti nurodytą užklausą (nurodome tinkamą pranešimą).
if ($mysqli_query === true) {
	echo 'Required MySQL table was successfully created.';
	exit;
} else {
	echo 'Critical error. Script failed to create a required table.';
	exit;
}

# Atlaisviname atmintį.
unset($mysqli_code);

}

# Uždarome užklausą.
$mysqli_select->close();

# - Patikrinimas baigiasi -

# Įvairūs tikrinimai, siekiant gauti tikslų protokolą adresą.
if (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP'])) {
	$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
	$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
	$ip = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0');
}

# Patikriname, ar gautas protokolo adresas yra teisingas, priešingu atveju - atvaizduojame savo rezultatą. 
$ip = (filter_var($ip, FILTER_VALIDATE_IP) ? '0.0.0.0' : $ip);

# Žemiau ištraukiame, ar vartotojas buvo nukreiptas iš kito puslapio (jeigu ne, rezultatas bus „null“), naršykles informaciją, nurodytą kalbą (ilgesnio ir trumpesnio tipo), apsaugome gautą informaciją.
$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'null');

$referer = $mysqli_connect->real_escape_string($referer);
$browser = $mysqli_connect->real_escape_string($_SERVER['HTTP_USER_AGENT']);
$browser_language_1 = $mysqli_connect->real_escape_string($_SERVER['HTTP_ACCEPT_LANGUAGE']);

$referer = htmlspecialchars($referer, ENT_QUOTES, 'UTF-8');
$referer = strip_tags($referer);
$referer = trim($referer);

$browser = htmlspecialchars($browser, ENT_QUOTES, 'UTF-8');
$browser = strip_tags($browser);

$browser_language_1 = htmlspecialchars($browser_language_1, ENT_QUOTES, 'UTF-8');
$browser_language_1 = strip_tags($browser_language_1);
$browser_language_2 = substr($browser_language_1, 0, 2);

# Patikriname, ar varotojas su naršymo srautu siunčia prašymo nesekti. Galite atsižvelgti į šį prašymą.
if (isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] == 1) {
	$track_user = 0;
} else {
	$track_user = 1;
}

# Kiek laiko turi praeiti, kada vartotojo būsena pasikeis į neprisijungusį. Laikas yra nurodomas sekundėmis.
$setting_1 = 300;

# Failo kelias (pilnasis), apsaugome.
$file_path_1 = $mysqli_connect->real_escape_string($_SERVER['PHP_SELF']);

$file_path_1 = htmlspecialchars($file_path_1, ENT_QUOTES, 'UTF-8');
$file_path_1 = stripslashes($file_path_1);
$file_path_1 = strip_tags($file_path_1);
$file_path_1 = trim($file_path_1);

# Gauname tik failo pavadinimą.
$filename_1 = pathinfo($file_path_1)['basename'];

# Pasirenkame vartotoją pagal interneto protokolo adresą.
$mysqli_select = $mysqli_connect->query("SELECT COUNT(`id`) FROM `visitors` WHERE `ip` = '$ip';");

# Jeigu užklausa pavyko, galima tęsti. Vėliau ištraukiame rezultatą ir jeigu jis yra lygus vienui, informaciją atnaujiname, jei ne - įterpiame vartotojo duomenis.
if ($mysqli_select !== false) {
	if ($mysqli_select->fetch_row()[0] == 1) {
		$mysqli_query = $mysqli_connect->query("UPDATE `visitors` SET `last_page` = '$filename_1', `clicks` = `clicks` + 1, `online` = 1, `language` = '$browser_language_2', `last_browser` = '$browser', `browser_language` = '$browser_language_1', `track_user` = '$track_user', `last_visit_time` = UNIX_TIMESTAMP() WHERE `ip` = '$ip';");
	} else {
		$mysqli_query = $mysqli_connect->query("INSERT INTO `visitors` (`referer`, `first_page`, `last_page`, `clicks`, `online`, `language`, `ip`, `first_browser`, `last_browser`, `browser_language`, `track_user`, `first_visit_time`, `last_visit_time`) VALUES ('$referer', '$filename_1', 'null', 1, 1, '$browser_language_2', '$ip', '$browser', 'null', '$browser_language_1', '$track_user', UNIX_TIMESTAMP(), UNIX_TIMESTAMP());");
	}
} else {
	echo 'Critical error.';
	exit;
}

# Uždarome užklausą.
$mysqli_select->close();

# Atliekame būsenos atnaujinimą, jeigu praėjo 300 arba daugiau sekundžių.
$mysqli_query = $mysqli_connect->query("UPDATE `visitors` SET `online` = 0 WHERE `online` = 1 && `last_visit_time` <= UNIX_TIMESTAMP() - $setting_1;");

# Uždarome prisijungimą prie „MySQL“ duomenų bazės.
$mysqli_connect->close();

?>

 

„SQL“ kodas:

Metodas (visų prisijungusių vartotojų suskaičiavimas):

SELECT COUNT(`id`) FROM `visitors` WHERE `online` = 1;

Metodas (vartotojo duomenų ištraukimas):

Nenaudoti * (žvaigždutės), net jeigu ir norite pasirinkti visus laukelius, priešingu atveju - sumažės našumas.

Laiko pateikimas su įskaitomu formatu:

SELECT FROM_UNIXTIME(`last_visit_time`, '%Y-%m-%d'), FROM_UNIXTIME(`last_visit_time`, '%H:%i:%s') FROM `visitors`;

 

Informacijos iš duomenų bazės ištraukimas (pavyzdys):

<?php

$mysqli_select = $mysqli_connect->prepare("SELECT `id`, `referer`, `first_page`, `last_page`, `clicks`, `online`, `language`, `ip`, `first_browser`, `last_browser`, `browser_language`, `track_user`, FROM_UNIXTIME(`first_visit_time`, '%Y-%m-%d %H:%i:%s'), FROM_UNIXTIME(`last_visit_time`, '%Y-%m-%d %H:%i:%s') FROM `visitors`;");

$mysqli_select->execute();

$mysqli_select = $mysqli_select->get_result();

if ($mysqli_select !== false && $mysqli_select->num_rows > 0) {
	while ($row = $mysqli_select->fetch_row()) {
		echo $row[0].'<br>';
		// $row[1], $row[2] ir t. t.
	}
} else {
	echo 'Rezultatų nėra.';
}

$mysqli_select->close();

?>

 

Redaguota , nario District
Pakeistas pavadinimas.
Nuoroda į komentarą
Dalintis per kitą puslapį

  • Parašė po 1 mėnesio...
Citata

# Reikia pauzės, jog spėtų sukurti lentelę(-es), jeigu perkrautumėte anksčiau laiko, lentelė nebūtų pabaigta ir skriptas parodytų klaidą. Gali taip ir nenutikti dėl vienos.
sleep(5);

Laukti kol kažkas įvyks nežinant kada tai įvyks yra bloga praktika, nes tu arba švaistysi laiką, arba lauksi per trumpai (kas nutiks ant lėtesnių environment'ų paleidus tavo kodą). Išeitis būtų tiesiog blokuoti kodo execute'inimą kol užklausa nebus įvykdyta.

 

Citata

# Atlaisviname atmintį.
unset($mysqli_code);

Kodėl?

Tai pat filtravimą gali pasirefactorint, nes 4 kartus tą patį kodą kartoji...

 

Nuoroda į komentarą
Dalintis per kitą puslapį

2018-02-13 23:37, Reklameris2 parašė:

Laukti kol kažkas įvyks nežinant kada tai įvyks yra bloga praktika, nes tu arba švaistysi laiką, arba lauksi per trumpai (kas nutiks ant lėtesnių environment'ų paleidus tavo kodą). Išeitis būtų tiesiog blokuoti kodo execute'inimą kol užklausa nebus įvykdyta.

 

Kodėl?

Tai pat filtravimą gali pasirefactorint, nes 4 kartus tą patį kodą kartoji...

 

Reklameri, tavo pasiūlymas šiuo atveju nėra tinkamas, kadangi ant šio tikrinimo ir taip reikėtų uždėti komentarą (po reikiamos lentelės sukūrimo), kitaip nuolat ieškos nurodytos duomenų bazės lenteles. Dar kartą patikrinti, ar užklausa buvo įvykdyta yra tiesiog overkill, o tai šioje temoje nelaukiama. Pagal viską, programuotojas turėtų pats rankiniu būdu sukurti lenteles, bet nusprendžiau procesą truputį palengvinti, kadangi pats mėgstu automatizuotus procesus.

Rekomenduojama atlaisvinti atmintį ant didelių kintamųjų, kurių nenaudosi. Pabaigoje, variklis tai padaro pats, tačiau geriau rankiniu būdu.

Dėl filtravimo - esi teisus. Deja, neturiu laiko (kol kas) patobulinti. Galėtum pats patobulinti, bent kažkur naudos būtų nei forume elgtis nerimtai.

Nuoroda į komentarą
Dalintis per kitą puslapį

Ši tema yra neaktyvi. Paskutinis pranešimas šioje temoje buvo prieš 2240 dienas (-ų). Patariame sukurti naują temą, o ne rašyti naują pranešimą.

Už neaktyvių temų prikėlimą galite sulaukti įspėjimo ir pranešimo pašalinimo!

Prisijungti prie diskusijos

Palikti atsakymą galite iš karto, o užsiregistruoti vėliau. Jeigu jau turite paskyrą mūsų forume, Prisijunkite.

Svečias
Atsakyti šioje temoje...

×   Įklijuotas tekstas turi teksto formatavimą.   Pašalinti teksto formatavimą

  Galimi tik 75 veidukai.

×   Nuoroda buvo automatiškai įterpta.   Įterpti nuorodą paprastai

×   Jūsų ankstesnis pranešimas buvo atkurtas.   Išvalyti redaktorių

×   Jūs negalite įkelti nuotraukas tiesiogiai.Įkelkite arba įdėkite nuotraukas iš URL.

Skelbimai


×
×
  • Sukurti naują...