Въпрос за бисквитки

meleto

Registered
Здравейте,

правя следното нещо
if(!isset($_COOKIE['cookie'])){


setcookie("cookie", $ip, time()+365*24*3600);
}

тоест, правя бисквитка ако не съществува такава.

Логиката е следната: проверявам дали даденото ip е записано в БД с даденото id на артикъла. И ако няма такава комбинация, проверявам дали има записана бисквитка на потр. компютър. Ако това е изпълнено, то се добавя ново посещение на страницата.

Само, че когато опитам същото с различно id се открива бисквитката и не се добавя посещение.

Тоест, ако потребителят влезе да разглежда 10 артикъла, само на първия ще се отчете посещение.

Та, интересно ми е как да направя така, че всеки артикъл да записва индивидуална бисквитка.

Пробвах setcookie("cookie", $id, time()+365*24*3600);
но явно си открива бисквитката, така или иначе.
 
s_gerrard каза:
setcookie("article" . $article_id, $ip, time() + 365*24*3600);

Ще обясниш ли какво прави "article" . $article_id
Това вид конкатенация ли е ? За да се създаде като уникално име?
 
Сега ще ти обясня какво става.
Добре си замислил механизма за броене на прегледите, но си допуснал малка грешка и то доста съществена.

Ето как действа скрипта ти:
Когато потребител влезе в сайта и прегледа статия, сървъра изпраща бисквитка със име article и стойност - ip на потребителя.
Когато потребител отвори друга статия, там се проверява дали потребителя има бисквитка със име article и понеже на предишната статия e била изпратена такава бисквитка, прегледа на статията няма да се отчете.

Едно от решенията на проблема е за всяка една статия да се изпраща отделна бисквитка със име съдържащо id на статията (както ти е предложил @s_gerrard). Но става малко неприятно, ако потребителя разгледа 10-15 статии наведнъж. При всяка заявка ще се влачат всички тези бисквитки по кабела. Това е излишно.

Варианта, който аз ти предлагам е да използваш функцията serialize и масив. В масива ще слагаш id-тата на статиите, които е прегледал потребителя и със serialize ще ги привеждаш в удобен за транспорт формат и ще ги изпращаш с бисквитката.

Ето примерен код.
PHP:
<?php

// .... код ...

$cookieName = 'cookie'; // Името на бисквитката

if ( ! isSet($_COOKIE[$cookieName])) {
	// потребителя няма бисквитка
	// нека създадем такава
	$data = array();
	$data[$article_id] = TRUE; // после при проверката isSet е по-бърз от in_array!
	setcookie($cookieName, serialize($data));
}
else {
	// Имаме бисквитка, нека извадим нейната стойност
	$data = @unserialize($_COOKIE['cookie']);
	
	// Бисквитката валидна ли е?
	if ($data !== FALSE && is_array($data)) {
		// Да!
		if ( ! isSet($data[$article_id])) {
			// Потребителя вижда страницата за пръв път.
			// обновяване на броя гледания
			// ....
			
			// Добавяме id-то в масива и изпращаме новата бисквитка
			$data[$article_id] = TRUE;
			setcookie($cookieName, serialize($data));
		}
	}
	else {
		// Бисквитката НЕ е валидна!!
		// изпращаме нова бисквитка
		$data = array();
		$data[$article_id] = TRUE;
		setcookie($cookieName, serialize($data));
	}
}

Не съм тествал кода, но ми изглежда добре на пръв поглед. Ако имаш въпроси, питай :)
 
F1r3Fl3x каза:
Сега ще ти обясня какво става.
Добре си замислил механизма за броене на прегледите, но си допуснал малка грешка и то доста съществена.

Ето как действа скрипта ти:
Когато потребител влезе в сайта и прегледа статия, сървъра изпраща бисквитка със име article и стойност - ip на потребителя.
Когато потребител отвори друга статия, там се проверява дали потребителя има бисквитка със име article и понеже на предишната статия e била изпратена такава бисквитка, прегледа на статията няма да се отчете.

Едно от решенията на проблема е за всяка една статия да се изпраща отделна бисквитка със име съдържащо id на статията (както ти е предложил @s_gerrard). Но става малко неприятно, ако потребителя разгледа 10-15 статии наведнъж. При всяка заявка ще се влачат всички тези бисквитки по кабела. Това е излишно.

Варианта, който аз ти предлагам е да използваш функцията serialize и масив. В масива ще слагаш id-тата на статиите, които е прегледал потребителя и със serialize ще ги привеждаш в удобен за транспорт формат и ще ги изпращаш с бисквитката.

Ето примерен код.
PHP:
<?php

// .... код ...

$cookieName = 'cookie'; // Името на бисквитката

if ( ! isSet($_COOKIE[$cookieName])) {
	// потребителя няма бисквитка
	// нека създадем такава
	$data = array();
	$data[$article_id] = TRUE; // после при проверката isSet е по-бърз от in_array!
	setcookie($cookieName, serialize($data));
}
else {
	// Имаме бисквитка, нека извадим нейната стойност
	$data = @unserialize($_COOKIE['cookie']);
	
	// Бисквитката валидна ли е?
	if ($data !== FALSE && is_array($data)) {
		// Да!
		if ( ! isSet($data[$article_id])) {
			// Потребителя вижда страницата за пръв път.
			// обновяване на броя гледания
			// ....
			
			// Добавяме id-то в масива и изпращаме новата бисквитка
			$data[$article_id] = TRUE;
			setcookie($cookieName, serialize($data));
		}
	}
	else {
		// Бисквитката НЕ е валидна!!
		// изпращаме нова бисквитка
		$data = array();
		$data[$article_id] = TRUE;
		setcookie($cookieName, serialize($data));
	}
}

Не съм тествал кода, но ми изглежда добре на пръв поглед. Ако имаш въпроси, питай :)

Да, усетих защо не се получава. :twisted:

Схванах смисъла на горния код, но със сигурност нарушава логиката ми и толкова голям код ще се получи, докато го внедря.



Код:
if(!isset($_COOKIE['cookie'.$id])){
 setcookie("cookie".$id,$ip, time()+365*24*3600);
}

Така написано валидно ли е? Щото май има грешка!
.
 
meleto каза:
Схванах смисъла на горния код, но със сигурност нарушава логиката ми и толкова голям код ще се получи, докато го внедря.
ъъм ок, щом ще стане много сложно, не го използвай.

meleto каза:
Код:
if(!isset($_COOKIE['cookie'.$id])){
 setcookie("cookie".$id,$ip, time()+365*24*3600);
}

Така написано валидно ли е? Щото май има грешка!
.

Изглежда ми ок, но защо слагаш IP-то на потребителя като стойност на бисквитката?
Не е много хубаво да разчиташ на IP адреса, защото има потребители, които всяка заявка на страницата я правят със различен IP адрес. За България не знам дали има такива мрежи, но знам че в САЩ и Англия има доста такива. Може и ако е абонат на БТК само да си рестартира модема и хоп - потребителя е с ново IP.

Вместо да записваш IP-то в базата данни и бисквитката, запиши някакъв random token от 20-30 символа. Така няма да се притесняваш дали потребителя е сменил IP-то си или не.

Тук съм постнал една малка функцийка, която може да ти свърши работа
http://web-tourist.net/forum/viewtopic.php?t=114684
:)
 
meleto каза:
F1r3Fl3x каза:

Да, усетих защо не се получава. :twisted:

Схванах смисъла на горния код, но със сигурност нарушава логиката ми и толкова голям код ще се получи, докато го внедря.



Код:
if(!isset($_COOKIE['cookie'.$id])){
 setcookie("cookie".$id,$ip, time()+365*24*3600);
}

Така написано валидно ли е? Щото май има грешка!
.

Ами направи си го на отделна функция и подавай параметри $article_id и име на бисквитката(даже това можеш да го пропуснеш и да подаваш само $article_id).

А това, за което питаш... ще пълниш потребителя с излишни бисквитки. @F1r3Fl3x ти е дал доста добро решение, просто го отдели във функция.
 

Back
Горе