how to make session_start change on each refresh - php

Im currently using the below code on my wordpress to display posts randomly but not duplicate them. This works apart from when I refresh the page it stays the same as it is. The only way to change what is displayed is to clear my cache and cookie. Is it possible to make it so that on each refresh it changes?
Here is my code:
session_start();
add_filter('posts_orderby', 'edit_posts_orderby');
function edit_posts_orderby($orderby_statement) {
$seed = $_SESSION['seed'];
if (empty($seed)) {
$seed = rand();
$_SESSION['seed'] = $seed;
}
$orderby_statement = 'RAND('.$seed.')';
return $orderby_statement;
}

Remove the if condition, in current situation - rand option set only if the session is empty. So that it working at first time i.e session not set.
$seed = rand();
$_SESSION['seed'] = $seed;
instead of
if (empty($seed)) {
$seed = rand();
$_SESSION['seed'] = $seed;
}

you can try out like
session_start();
session_regenerate_id();
echo session_id();
This returns you with unique session ids on each refresh

Related

Why is my session not working when I try to count IP hits?

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.

Generating a Non-Repeating Random Number - PHP

I'm trying to get a custom function in php to return a random number between 1 and 20 that does not repeat i.e. produce the same number more than once, since I need to subsequently use this number to navigate to one of twenty web pages, and I don't want the same web page displayed.
Here is my code in three steps:
<form action="rand.php">
<p>Click this button to display a random number that does not repeat...</p>
<p><input type="submit" value="Generate"></p>
</form>
Here is rand.php:
require_once('functions.php');
$page = generateNumber();
echo $page;
Here is functions.php:
<?php
$check = array();
function generateNumber() {
global $check;
$page_no = mt_rand(1,20);
$check[] = $page_no;
if (count($check) != 1) {
foreach ($check as $val) {
if ($val == $page_no) {
$page_no = mt_rand(1,10);
continue;
}
}
return $page_no;
}
else {
return $page_no;
}
}
?>
My code seem to be functioning, however, it is repeating numbers so I am obviously doing something wrong. The reason I initially check the count is so that is returns the first number regardless, since it would be a single fresh number.
In order to see the number change I have been refreshing the rand.php page in my browser.
I would keep it simple.
// List numbers 1 to 20
$pages = range(1,20);
// Shuffle numbers
shuffle($pages);
// Get a page
$page = array_shift($pages);
In order to go through all the 20 numbers on each page visit, without repeating, you will need to set a session variable.
<?php
session_start();
if (!isset($_SESSION['numbers'])) {
$_SESSION['numbers']="*"; //---create the session variable
}
function get_number() {
$i = 0;
do {
$num=rand(1,20); //---generate a random number
if (!strstr($_SESSION['numbers'],"*".$num."*")) { //---check if the number has already been used
$_SESSION['numbers']=$_SESSION['numbers'] . $i . "*"; //---add the number to the session variable to avoid repeating
if (substr_count($_SESSION['numbers'],"*")>=21) { //---resets the session variable when all 20 number have been used
$_SESSION['numbers']="*";
}
$i=$num; //---ends the while loop to return the value
}
} while ($i==0);
return $i;
}
?>

PHP Session custom class sessions not being set?

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
(
)

Limit array size in cookie

I have the following function to set a cookie on each indiviual product page a user visits on my website.
function setcookie() {
$entry_id = '787';
if (isset($_COOKIE['recently_viewed'])) {
$currentSession = unserialize($_COOKIE['recently_viewed']);
if (!in_array($entry_id, $currentSession)) {
if (count($currentSession) > 5) {
unset($currentSession[0]);
}
$currentSession[] = $entry_id;
} else {}
$currentSession = serialize($currentSession);
setcookie('recently_viewed', $currentSession, pow(2,31)-1, '/', '');
} else {
$recently_viewed[] = $entry_id;
$currentSession = serialize($recently_viewed);
setcookie('recently_viewed', $currentSession, pow(2,31)-1, '/', '');
}
}
In this function I am trying to limit the number of items stored in the cookies array.
When the cookies array has 6 items in it, I want to remove the first (oldest) item in that array and then add the new item (so there is never more than 6 items, but always adds the new one).
I have used the following, but it doesn't always seem to work. Sometimes it removes the first item when there are more than 5, but other times it just keeps adding them so there are more than 6.
if (count($currentSession) > 5) {
unset($currentSession[0]);
}
Can anyone tell me if there is a better way to achieve this?
You definitely should use session.
session_start();
$entry_id = '788';
if (!is_array($_SESSION['recently_viewed'])) {
$_SESSION['recently_viewed'] = array();
}
// add the item to the begining
array_unshift($_SESSION['recently_viewed'], $entry_id);
// ensure unique entries
$_SESSION['recently_viewed'] = array_unique($_SESSION['recently_viewed']);
// keep first 5 entries
$_SESSION['recently_viewed'] = array_slice($_SESSION['recently_viewed'], 0, 5);
echo 'recent: ' . print_r($_SESSION['recently_viewed'], true);
if (count($currentSession) > 5) {
$arr = array_shift($currentSession);
}

how to generate unique session ID without the use of session_id()?

I want to generate a session ID. This unique sessionId represents some different data for every different user.
My code till now:
onclick and onload of a page I call a function create_session_id();
function create_session_id() {
// This function sends a string to a PHP page using ajax post.
}
On my PHP page, I receive this data and then insert it:
session_start();
$a = session_id();
$object->insert_sessionid($a);
My Question
Is it possible to use only session_start() (no session_id()) and store some unique session ID value that I can use later when I fetch data and throw data to my web page. I don’t want any clicks to register sessionid. It should happen on page load and without any function create_session_id().
I am thinking to bring some cookies in to the picture.
Note: My website doesn’t allow login.
use a function like
function createRandomVal($val){
$chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,-";
srand((double)microtime()*1000000);
$i = 0;
$pass = '' ;
while ($i<=$val)
{
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}
return $pass;
}
and pass return value in session id
The above code is a little bit buggy since user669677 has edited it.
Here is the proper code:
function createRandomVal($val) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,-";
srand((double)microtime() * 1000000);
$i = 0;
$pass = '';
while ($i < $val) {
$num = rand() % 64;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}
return $pass;
}

Categories