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]);
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 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;
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 have a custom class I am writing for easier scripting for myself. I generate life spanned sessions and normal sessions (normal life span). So here's my script parts for creating and getting
CREATE
public static function create($session_name,$value="") {
//check if the $_SESSION was started manually without using our functions...
if(!isset($_SESSION)) {
//init this- it creates session_start session_id
self::init(self::$settings["default_name"]);
}
//create array for serialization
$new_session = array();
//if our session is an array means we want this session to have some unique properties compared to others
if( is_array($session_name)) {
//store the session value in the array
$new_session["value"] = $session_name["value"];
//total time is null, this indicates if we want a life expectancy of total 10 hours total or total from current time.
$total = null;
if(isset($session_name["lifeclock"])) { //lifeclock should be a hh:mm:ss format to be exploded
$clock = explode(":",$session_name["lifeclock"]); //we've exploded it now assign it
$hours = $clock[0]; //hours
$minutes = $clock[1]; //minutes
$seconds = $clock[2]; //seconds
$session_add = 0; //variable to be added to total or not technically
if(isset($session_name["concurrent"])) {
$session_add = time(); //if concurrent time is true assign time to the session_add
}
$total = ( $session_add ) + ((int)$hours * 60 * 60) + ((int)$minutes * 60) + (int)$seconds; //broken down math to make all seconds
}
if(!isset($total)) { //this is why total is null
$total = self::$settings["lifetime"]; //if null lifetime we'll use the default lifetime
}
session_set_cookie_params( $total, //assing all data to the session_set_cookie_params
isset($session_name["path"]) ? $session_name["path"] : self::$settings["path"],
isset($session_name["domain"]) ? $session_name["domain"] : self::$settings["domain"],
isset($session_name["secure"]) ? $session_name["secure"] : self::$settings["secure"],
isset($session_name["httponly"]) ? $session_name["httponly"] : self::$settings["httponly"]
);
$new_session["life"] = $total; //we'll also add the time and when it was born
$new_session["born"] = time(); // so the user can use this later in the programming code
$_SESSION[$session_name["name"]] = serialize($new_session); //serialize the array
} elseif(is_string($session_name)) {
$new_session["value"] = $value; //assign value value
$new_session["born"] = time(); //assign born time
$_SESSION[$session_name] = serialize($new_session); //serialize the array
}
session_write_close(); //close the lock
}
GET
public static function get($session_name,$data = false) {
//test if session has been opened via manual or programatically
if(!isset($_SESSION)) {
self::init(self::$settings["default_name"]);
}
//if data argument is true meaning we don't want all the extra information we'll just return value!
if($data === false) {
if(isset($_SESSION[$session_name])) {
$sess = unserialize($_SESSION[$session_name]);
if(isset($sess["value"])){
return $sess["value"];
} else return false;
} else return false;
} elseif($data === true) {
return unserialize($_SESSION[$session_name]);
}
}
Now here is my file for testing this altogether.
<?php
set_include_path(dirname($_SERVER["DOCUMENT_ROOT"]));
require "admininit__autoload.php";
Session::configure(array(
"default_name"=>"boogie",
"lifetime"=> 3600,
));
Session::create( array(
"name"=>"my_session",
"value"=>"boogie all night long",
"lifeclock"=>"00:05:00"
));
$session_value = Session::get("my_session");
var_dump($session_value);
echo "<pre>";
print_r($_SESSION);
echo "</pre>";
?>
So this is what I get in response to the var_dump and print_r
bool(false)
Array
(
)
So this tells me that $session_value is return false from the get function meaning altogether that the darn session is not saving for some strange reason. Here is what I see in google developers resource panel as well
So to me that's telling me a session is being created somewhere. I've also went ahead and checked my /tmp folder and see no file starting with sess_ which is the usual file for sessions. Any hints as to where my issue lies or maybe flat out what the hell is wrong here?
Update
While the creation of the code is uncommented out I get this
array(1) {
["my_session"]=> string(88) "a:3:{s:5:"value";s:21:"boogie all night long";s:4:"life";i:300;s:4:"born";i:1431562088;}"
}
string(21) "boogie all night long"
Array
(
[my_session] => a:3:{s:5:"value";s:21:"boogie all night long";s:4:"life";i:300;s:4:"born";i:1431562088;}
)
But when I comment out the creation part it returns this
bool(false)
Array
(
)
I would like to dedicate this page to handling sessions using procedural php.
I'll begin with how I start most of my projects:
session_name('Easy_App');
session_start();
if (!isset( $_SESSION['ip'] )){
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}
if (!isset( $_SESSION['created'] )){
$_SESSION['created'] = time();
}
if (!isset( $_SESSION['overall_views'] )){
$_SESSION['overall_views'] = 1;
}
else {
$_SESSION['overall_views']++;
}
if (!isset( $_SESSION['username'] )){
$_SESSION['username'] = "";
}
if (!isset( $_SESSION['logged_in'] )){
$_SESSION['logged_in'] = 0;
}
/*A quick method to keep pageviews to < 5 pages per 1 second per session*/
if (!isset($_SESSION['first_action'])){
$_SESSION['first_action'] = time();
}
$first_action = $_SESSION['first_action'];
if (!isset( $_SESSION['action'] )){
$_SESSION['action'] = 1;
}
else{
$_SESSION['action']++;
}
$action=$_SESSION['action'];
if ($action>=5){
unset($_SESSION['action']);
unset($_SESSION['first_action']);
if((time() - $first_action) <=1){
exit("Please Don't Hammer My Site ");
}
}
So We have a starting point:
The Start of a session with a few regularly used parameters
In the last few lines, prevention of hammering by casual users.
My question is this:
Where would you go from here? Improvements of the above code or a brief snippet of how you handle sessions using procedural php would be greatly appreciated.
Your code would not work If you are trying to STOP Hammer or FLOODING if the user doesn't keep cookies your Sessions are useless and the script is a waste ... you should try better approach using storage systems like memcache , mongoDB or redis
See : https://stackoverflow.com/a/10155437/1226894 .... this has been answered before
EDIT 1
Am not sure what you want by procedural PHP but i hope this helps
Objectives
Remove duplicate isset
Remove duplicate if Statement
Create single function to get and set $_SESSION
Trying to make everything a function and hide all variables
Final Code
session_start ();
include("procedural.function.php");
__SESSION ( 'ip', $_SERVER ['REMOTE_ADDR'] );
__SESSION ( 'created', time () );
__SESSION ( 'overall_views', 1 );
__SESSION ( 'overall_views', "++" );
__SESSION ( 'username', "" );
__SESSION ( 'logged_in', 0 );
__SESSION ( 'first_action', time () );
__SESSION ( 'action', "++" );
if (__SESSION ( 'action' ) >= 5) {
__UNSET ( 'action' );
__UNSET ( 'first_action' );
if ((time () - __SESSION ( 'first_action' )) <= 1) {
exit ( "Please Don't Hammer My Site " );
}
}
procedural.function.php
function __SESSION($var, $value = null) {
if ($value === null) {
return isset ( $_SESSION [$var] ) ? $_SESSION [$var] : null;
} else if ($value === "++") {
isset ( $_SESSION [$var] ) ? $_SESSION [$var] ++ : $_SESSION [$var] = 0;
return $_SESSION [$var];
} else {
isset ( $_SESSION [$var] ) ? $_SESSION [$var] = $value : null;
return $value;
}
}
function __UNSET($var) {
unset ( $_SESSION [$var] );
}