I am new to PHP and I am having quite the trouble with using Cookies!
So I am trying to have one cookie that will keep count of the number of times the page has been loaded within a lifetime of 1 minute. Once it has reached its lifetime it needs to be unset and the counter should go back to 0.
So far here is what I have:
At the top of the Php file
<?php
session_start();
$_SESSION['user_start'] = time();
$cookie_name = "counter";
$cookie_value = 0;
setcookie($cookie_name, $cookie_value);
?>
<html>
<body>
<?php
if (time() - $_SESSION['user_start'] < 60) {
$counter = $_COOKIE[$cookie_name] +1;
setcookie($cookie_name, $counter);
echo "Value is: " . $_COOKIE[$cookie_name];
}
else{
unset($_SESSION['user_start']);
unset($_COOKIE[$cookie_name]);
}
?>
It's a little odd - but this should do the trick, I'm storing both the counter value and the expiry time in a cookie in JSON format. That way you can just increment the counter whilst keeping the initial expiry time (e.g. 1 minute after the initial request).
<?php
$counter = 0;
$expires = time()+60;
if(isset($_COOKIE['counter'])) {
$data = json_decode($_COOKIE['counter']);
$counter = ++$data->counter;
$expires = $data->expires;
}
$jsonData = json_encode(['counter' => $counter, 'expires' => $expires]);
setcookie("counter", $jsonData, $expires);
echo $counter;
Related
I am trying to delete a cookie by setting that cookie in past time:
$cookie_name = "user";
$cookie_value = "david";
//subtraction from time causes deletion of cookie
setcookie($cookie_name, $cookie_value, time() - (86400 * 30), "/");
With the below code I try to check whether cookie is enabled or not and it returns if case rather than else part, while I already dell that cookie:
//counting number of cookies
if(count($_COOKIE) > 0) {
echo "<br>Cookies are enabled/exists";
} else {
echo "<br>Cookies are disabled/not exists";
}
But the else part is not working when we delete cookie and I don't know why?
The main problem is you just set user cookie time to past date not all the other cookie in super global $_COOKIE array . Try like this way to set for all $_COOKIE value using foreach() to past date and then check count condition.
<?php
$cookie_name = "user";
$cookie_value = "david";
$past_time = time() - 3600;
//use look set all cookie time to past date.
foreach ( $_COOKIE as $key => $value )
{
setcookie( $key, $value, $past_time, '/' );
}
//counting number of cookies
if(count($_COOKIE) > 0) {
echo "<br>Cookies are enabled/exists";
} else {
echo "<br>Cookies are disabled/not exists";
}
?>
DEMO: https://3v4l.org/jvRXW
I'm trying to create a counter in PHP that will count how many times within a set timeframe an IP can visit a page and when it hits a download counter within that timeframe it re-directs. The approach I've seen recommended was doing this with a session after referencing several Q&As:
PHP function to increment variable by 1 each time
How to not increase page/post view count with refresh?
php increment variable value with 1 when submit
I also looked at:
How do I count unique visitors to my site?
adding counter to php page to count the unique visitors
I do not have much experience with cookies and sessions so I believe that is where I fault in my code. If you have any suggestions on better implementation than what I am doing please advise.
The code:
$jsonFile = 'foobar.json';
$theJSON = file_get_contents($jsonFile);
$jsonArray = json_decode($theJSON, true);
$theIP = "123.123.123"; // $_SERVER['REMOTE_ADDR']
$thisTime = date("H:i");
$addMin = 1; // set value for testing purposes
$addHour = 0; // set value for testing purposes
$downloadHits = 5; // set value for testing purposes
$timeLater = date("H:i", strtotime($thisTime)+(($addMin*60)+($addHour*60*60)));
if (!empty($theIP) && !empty($jsonArray)) {
foreach ($jsonArray as $value) {
if (in_array($theIP, $value, true)) {
echo "yes"; // header('Location: https://www.url/darthvader.com');
exit();
} else {
if ($thisTime <= $timeLater) { // where my issue starts
echo $timeLater; // for testing
session_start();
$counter = $_SESSION['promo_number'];
$counter++;
if ($counter == $downloadHits && file_exists($jsonFile)) {
$currentData = file_get_contents($jsonFile);
$currentArray = json_decode($currentData, true);
$theStuff = array(
'ip' => "123.123.123", // $_SERVER['REMOTE_ADDR']
'date' => date("H:i"),
'time' => date("m.d.y")
);
$currentData[] = $theStuff;
$finishData = json_encode($currentData);
} else {
echo 'bar'; // for testing
session_unset();
session_destroy();
}
}
}
}
} else {
echo '<span style="color:red; font-weight:bold;">empty file</span>';
}
What I am trying to do is count the times an IP visits a post within a set time and if it hits that count redirect the IP. I do know that the IP can be spoofed and I am not worried about that plus I would prefer to not use a database at this time. So how can I properly set a session to count the hits and if the IP hits the post in set count it redirects the IP?
EDIT:
After doing some reading and the help from the comment and answer I've made an edit that I hope explains what I am trying to do. After researching further I ran across:
session_destroy() after certain amount of time in PHP
How do I expire a PHP session after 30 minutes?
which led me to code:
session_start();
$jsonFile = 'foobar.json';
$jsonArray = json_decode(file_get_contents($jsonFile), true);
$theIP = $_SERVER['REMOTE_ADDR'];
$addMin = 2; // set value for testing purposes
$addHour = 0; // set value for testing purposes
$targetedHits = 1; // set value for testing purposes
$timeLater = time() + ($addMin*60) + ($addHour*60*60);
$_SESSION['expire'] = $timeLater;
if (!empty($theIP) && !empty($jsonArray)) {
//look for the $theIP
if (in_array($theIP,array_column($jsonArray,'ip'))) {
echo 'IP found in json';
exit;
}
// look at the time the session was set, add to counter or delete session
if ($_SESSION['count'] = isset($_SESSION['count']) && time() < $_SESSION['expire'] ) {
echo 'adding to count';
$_SESSION['count'] + 1;
// limit reached. Add IP to blacklist
if ($_SESSION['count'] > $targetedHits) {
echo 'session count reached max';
$jsonArray[]=[
'ip' => $theIP,
'date' => date("H:i"),
'time' => date("m.d.y")
];
// save changes
file_put_contents($jsonFile,json_encode($jsonArray));
session_destroy();
exit;
}
} elseif (time() > $_SESSION['expire']) {
echo 'nuking session and counter';
session_destroy();
} else {
echo 'setting count to 1';
$_SESSION['count'] = 1;
}
}
echo '<pre>';
var_dump($_SESSION);
echo '</pre>';
But sadly now the $_SESSION['count'] + 1; no longer increments.
Darth_Vader you're almost there. There are a couple of issues with your script.
You never save the count in session, so you have no way to retrieve it later
You start your session late in the script. This is poor practice because it will break as soon as you echo something higher up or forget and try to use $_SESSION higher up
You read your JSON file and decode it twice unnecessarily, wasting system memory
You never save the changes you make to the JSON
You call session_unset() and session_destroy() after a successful download, so the count would be lost even if you were trying to save it properly
My modifications:
session_start();
$jsonFile = 'foobar.json';
$jsonArray = json_decode(file_get_contents($jsonFile), true);
$theIP = $_SERVER['REMOTE_ADDR'];
$thisTime = time();
$addMin = 1; // set value for testing purposes
$addHour = 0; // set value for testing purposes
$downloadHits = 5; // set value for testing purposes
$timeLater = $thisTime + ($addMin*60) + ($addHour*60*60);
if(empty($theIP)){
echo 'empty file';
exit;
}
//look for the $theIP in the 'ip' column
if(in_array($theIP,array_column($jsonArray,'ip'))){
echo 'IP found in json';
exit;
}
if($thisTime > $timeLater){//not sure what you want to do here
exit;
}
//increment the count, or set it to 1 to begin
$_SESSION['count'] = isset($_SESSION['count'])? $_SESSION['count']+1 : 1;
if($_SESSION['count']>=$downloadHits){//limit reached. Add IP to blacklist
$jsonArray[]=[
'ip' => $theIP,
'date' => date("H:i"),
'time' => date("m.d.y")
];
//save changes
file_put_contents($jsonFile,json_encode($jsonArray));
exit;
}
echo 'good to go!'; //allow the download
Happy coding.
Figured it out after spending some time under the session tag. These two questions were helpful:
How do check if a PHP session is empty?
How can I clear my php session data correctly?
Which led me to code:
session_start();
$jsonFile = 'foobar.json';
$jsonArray = json_decode(file_get_contents($jsonFile), true);
$theIP = $_SERVER['REMOTE_ADDR'];
$addMin = 1; // set value for testing purposes
$addHour = 0; // set value for testing purposes
$targetedHits = 5; // set value for testing purposes
$timeLater = time() + ($addMin*60) + ($addHour*60*60);
if (empty($_SESSION['count'])) {
$_SESSION['expire'] = $timeLater;
}
if (!empty($theIP) && !empty($jsonArray)) {
// look for the $theIP
if (in_array($theIP,array_column($jsonArray,'ip'))) {
$_SESSION['count'] = 0;
session_destroy();
echo 'IP found in json';
exit;
}
if (time() < $_SESSION['expire']) {
echo 'below the time ';
$_SESSION['count'] = isset($_SESSION['count'])? $_SESSION['count'] + 1 : 1;
if ($_SESSION['count'] > $targetedHits) {
echo 'session count reached max ';
$jsonArray[] = [
'ip' => $theIP,
'date' => date("H:i"),
'time' => date("m.d.y")
];
// save changes
file_put_contents($jsonFile,json_encode($jsonArray));
unset($_SESSION['count']);
session_destroy();
exit;
}
} elseif (time() > $_SESSION['expire']) {
echo 'nuking session and counter';
$_SESSION['count'] = 0;
unset($_SESSION['expire']);
}
}
echo '<pre>';
var_dump($_SESSION);
echo '</pre>';
I hope the above helps the next person because I didn't really know anything about sessions and it has been an adventure getting this to work this evening.
I am having a PHP code problem. As you see, I get an id from another page. I want to save these id's in array based on cookies. I was able to do that, but I have a problem with it.
When I set the timeout (for example to 20 seconds) and refresh page: every 20 second it works fine, but if I refresh it in under 20 seconds it gives me the error below.
Fatal error: [] operator not supported for strings
I do not know why; could you please help?
<?php
$ID = is_numeric($_GET['ID']) ? $_GET['ID'] : 1;
$cookie_name = "favoritepost";
if ( isset($_COOKIE[$cookie_name]) ) {
$kookie = $_COOKIE[$cookie_name];
} else {
$kookie = array();
}
if ( ! in_array($ID, $kookie) ) {
$kookie[] = $ID;
}
setcookie($cookie_name, serialize($kookie), time() + (20), "/"); // 86400 = 1 day
?>
<html>
As per my last answer https://stackoverflow.com/a/38307347/2310830
<?php
$ID = is_numeric($_GET['ID']) ? $_GET['ID'] : 1;
$cookie_name = "favoritepost";
if ( isset($_COOKIE[$cookie_name]) ) {
$kookie = unserialize($_COOKIE[$cookie_name]);
} else {
$kookie = array();
}
if ( ! in_array($ID, $kookie) ) {
$kookie[] = $ID;
}
setcookie($cookie_name, serialize($kookie), time() + (86400 * 30), "/"); // 86400 = 1 day
?>
<html>
The array is serialized when it is stored as a cookie. So when you retrieve it, it is a string, not an array. You need to unserialize it before you add more to it:
$kookie = unserialize($_COOKIE[$cookie_name]);
I am currently saving a session in my form page:
$testingvalue = "SESSION TEST";
$_SESSION['testing'] = $testingvalue;
On another page I am calling the session to use the value:
<?php
session_start(); // make sure there is a session
echo $_SESSION['testing']; //prints SESSION TEST???
?>
Now I want to use the
session_destroy();
to destroy the session. But what I would like to do is destroy the session after 2 hours have been passed.
Any idea on how to do it and also where should I put it?
I have something like this:
<?php
session_start();
// 2 hours in seconds
$inactive = 7200;
$session_life = time() - $_session['testing'];
if($session_life > $inactive)
{
session_destroy();
}
$_session['testing']=time();
echo $_SESSION['testing']; //prints NOTHING?
?>
Will that work?
If I am inactive for more than 2 hours this should be blank?:
echo $_SESSION['testing'];
Something like this should work
<?php
// 2 hours in seconds
$inactive = 7200;
ini_set('session.gc_maxlifetime', $inactive); // set the session max lifetime to 2 hours
session_start();
if (isset($_SESSION['testing']) && (time() - $_SESSION['testing'] > $inactive)) {
// last request was more than 2 hours ago
session_unset(); // unset $_SESSION variable for this page
session_destroy(); // destroy session data
}
$_SESSION['testing'] = time(); // Update session
you need a static start time to expire. $session_life > $inactive will always be greater no matter what.
session_start();
$testingvalue = "SESSION TEST";
$_SESSION['testing'] = $testingvalue;
// 2 hours in seconds
$inactive = 7200;
$_SESSION['expire'] = time() + $inactive; // static expire
if(time() > $_SESSION['expire'])
{
$_SESSION['testing'] = '';
session_unset();
session_destroy();
$_SESSION['testing'] = '2 hours expired'; // test message
}
echo $_SESSION['testing'];
or session-set-cookie-params
I want to block visitor between 2 to 5 minutes every 100 view.. if user view 100 page between 2 to 5 minutes then block user, if user view 100 view in 6 minutes then don't block and reset the counter.
I already create the counter script but i have issue with creating the function which can block visitor between 2-5 mint.
I need help to fix this problem... I try to create a if condition but no luck.. help me please...
$sb_current_time = date("Y-m-d H:i:s", Time());
/////////////////// Cookies Encryption //////////////
function encrypt($text)
{
$key = "E4HD9h4DhS23DYfhHemkS3Nf"; // 24 bit Key
$iv = "fYfhHeDm"; // 8 bit IV
$bit_check = 8;
$text_num = str_split($text, $bit_check);
$text_num = $bit_check - strlen($text_num[count($text_num) - 1]);
for ($i = 0; $i < $text_num; $i++) {
$text = $text . chr($text_num);
}
$cipher = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'cbc', '');
mcrypt_generic_init($cipher, $key, $iv);
$decrypted = mcrypt_generic($cipher, $text);
mcrypt_generic_deinit($cipher);
return base64_encode($decrypted);
}
//////////////// Encription end /////////
////// Cookies decription /////
function decrypt($encrypted_text)
{
$key = "E4HD9h4DhS23DYfhHemkS3Nf"; // 24 bit Key
$iv = "fYfhHeDm"; // 8 bit IV
$bit_check = 8;
$cipher = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'cbc', '');
mcrypt_generic_init($cipher, $key, $iv);
if ($encrypted_text != "") {
$decrypted = mdecrypt_generic($cipher, base64_decode($encrypted_text));
mcrypt_generic_deinit($cipher);
$last_char = substr($decrypted, -1);
for ($i = 0; $i < $bit_check - 1; $i++) {
if (chr($i) == $last_char) {
$decrypted = substr($decrypted, 0, strlen($decrypted) - $i);
break;
}
}
}
return $decrypted;
}
///////// Coookies decription end /////////////////
//$sb_check_ban_time = date($sb_current_time, strtotime("+20 minute"));
if ($_COOKIE['spamer_check_time'] == "") {
setcookie('spamer_check_time', encrypt(time()));
}
function time_deff($date2)
{
$date1 = time();
//sleep(2000);
// $date2 = decrypt($_COOKIE['spamer_check_time']);
//echo $date2;
$mins = ($date1 - $date2) / 60;
//echo $mins;
return $mins;
}
//$sb_cookie_expiration = time() + 1200;
//echo $sb_cookie_expiration;
if ($_COOKIE['view2'] != "") {
$explod = explode("-", decrypt($_COOKIE["view2"]));
}
$i_print = $explod[0];
// $i2=$explod[1];
//echo $i2;
$i = 1 + $i_print;
setcookie("view2", encrypt($i . "-123456789")); //// Need to add extra bit to block unwanted text and secure the cookes more..
//
$i = $i++;
// echo $i_print;
//echo "empty".decrypt($_COOKIE["spamer_check_time"]);
$spammer_blocker = decrypt($_COOKIE["spammer_blocker"]);
// or $spammer_blocker==""
$mins = time_deff(decrypt($_COOKIE['spamer_check_time']));
$diff_time = .1; /// User BLock Time
if ($mins >=1 or $mins <=2) {
$block_user=1;
} elseif ($mins >= 2.1) {
$block_user=2;
} else {
}
/* if (.2>$mint) {
// echo "not done";
$block_user=0;
} elseif (.2 <= $mint) {
echo "block User";
$block_user=1;
} elseif ($mins>=1) {
echo "reset cookies";
$block_user=2;
}*/
if ($block_user==1 and $i_print >= 15) {
if ($spammer_blocker == "") {
setcookie("spammer_blocker", encrypt(time()));
header('HTTP/1.1 403 Forbidden');
$time_rev = $diff_block_time - $diff_time;
$round_time = round($time_rev, 2);
$time_reverse = str_replace('-', '', $round_time);
echo "Wait " . $time_reverse . " Minuts before using this site..";
exit(0);
} else {
//$sb_check_ban_time = $spammer_blocker;
$diff_block_time = time_deff($spammer_blocker);
//echo $diff_block_time;
//$sb_check_ban_time = date($spammer_blocker, strtotime("+1 minute"));
if ($diff_time <= $diff_block_time) {
/// echo "Delete the IP and cookies";
setcookie("spammer_blocker", "");
setcookie("view2", "");
setcookie("spamer_check_time", "");
} else {
//echo "Still Block"; /// echo "Still Block";
header('HTTP/1.1 403 Forbidden');
// echo "IP Block for Spaming wait few mint";
$time_rev = $diff_block_time - $diff_time;
$round_time = round($time_rev, 2);
$time_reverse = str_replace('-', '', $round_time);
echo "Wait " . $time_reverse . " Minuts before using this site..";
exit(0);
}
}
} elseif ($block_user==2) {
setcookie("spammer_blocker", "");
setcookie("view2", "");
setcookie("spamer_check_time", "");
echo "cookies reset";
} else {
}
First, you need to know who they are...
For casual users, you can rely on cookies. But if you are having problem with an abuser, then they will simply ignore your attempt to stop them and not send a cookie.
There are various levels of knowing "who" someone is.
ID in URL
Cookies
IP Address
And they can ALL be overcome with different levels of diffulculty...
Way too easy (just spoof a different ID, etc...)
Cookies are the same as #1
IP addresses are harder to overcome unless you have a botnet or similar
For your case, you should likely block the IP address as it's the only reasonable way for you to get done what you are looking for.
--
Next, you need to be able to keep track of their connections. iptables in Linux has a way to track the number of connections and block for a specific number of minutes after a certian threshold is reached.
Using only PHP, you need to record each hit, and the IP address of that hit. An SQL database would be one of the more efficient ways of doing this.
If you don't care about history, then simply (mysql):
INSERT INTO HitTable SET IP=..., Visits=1
ON DUPLICATE KEY UPDATE Visits=Visits+1
A background crontab could run a query like this every minute?
UPDATE HitTable SET Visits = Visits - 10
DELETE FROM HitTable WHERE Visits < 1
Finally, when a visitor visits, you would check the database table for
SELECT Visits<100 WHERE IP=...
AND if that returns True, let them in, else block them.
Hope this helps a bit.
Storing the timeout value in a cookie will be absolutely trivial for a user to change/delete the cookie
Storing it in a session variable is a bit more reliable, but again - the user could just delete the session cookie, get a new session going, and start reading again.
That being said, you'd do something like this:
<?php
session_start();
if (user_should_be_blocked()) {
$_SESSION['blocked_start_time'] = time();
header("Location: timeout.html");
}
if ($_SESSION['blocked_start_time'] > (time() - 300)) {
header("Location: timeout.html");
}
// got here, must not be blocked and/or timeout has expired
$_SESSION['blocked'] = false;
$_SESSION['block_start_time'] = null;
.... continue on
I would use the header funciton to redirect them to another page, either empty or just less bankwidth intensive (assuming that's why you're making this anyway). Soemthing like...
if ($block_user == 1)
header("Location: blockPage.php");
At the top of all pages you need to block.
Edit: actually, come to think of it, (2) is of course not necessary, if 2 people or 2 computers are logged in they'll only consume their alloted amount of views faster..
You can do this provided:
A user needs to be logged in to see the pages.
You don't allow the same user(name) to be logged in twice with different sessions.
You store the count per-user, not per-session or per-ip/whatever.
(2) is not possible with default file based sessions. A custom database or other persistent storage solution is needed in which you can scan for other session-id's of a current user-id. In a database you would just store a user-id field, a custom memcached solution could also be built, etc. To prevent users being locked out of a session they no longer have my solution was always to destroy any old session a user had the moment they log in. Effectively, if it's tried with multiple sessions/ips, they'll have to log in again and again invalidating the previous session.
(3) again some persistent storage with a timestamp+userid+count (in MySQL's case an INSERT INTO tablename (user_id,time,count) VALUES (<id>,NOW(),1) ON DUPLICATE KEY UPDATE count=count+1 comes to mind to easily increment view counts.
And on every view query the database again and again about how many views the visitor had the last X minutes.