PHP conditional session_destroy not working as expected - php

I am writing code for math problems -- they follow a format, with randomly generated variables, and then I lock in the variables per the code below. What isn't working -- form03 allows the user to finish the page of math problems and to reset for another. I need to destroy the session on that condition. But even when I enter data in form03, so that it isset, the old session values remain.
???
require_once 'random.php';
require_once 'forms-functions.php';
if (isset($_SESSION['z'])) {
$_SESSION['y'] = "";
session_start();
session_destroy();
}
session_start();
if (isset($_SESSION['y'])) {
echo "hello isset<br>";
$x01 = $_SESSION['x01'];
$x02 = $_SESSION['x02'];
$output01b = $_SESSION['output01b'];
$output02b = $_SESSION['output02b'];
} else {
echo "hello else<br>";
ob_start();
random1();
$output01 = ob_get_clean();
$output01b = "single string: ".$output01."";
$x01 = $x;
ob_start();
random1();
$output02 = ob_get_clean();
$output02b = "single string: ".$output02."";
$x02 = $x;
$_SESSION['x01'] = $x01;
$_SESSION['x02'] = $x02;
$_SESSION['output01b'] = $output01b;
$_SESSION['output02b'] = $output02b;
$y = "1";
$_SESSION['y'] = $y;
}
echo $output01b;
$user_input01 = form01('user_input01');
echo $output02b;
$user_input02 = form02('user_input02');
$user_input03 = form03('user_input03');
if(isset($user_input03)) {
$z = 1;
$_SESSION['z'] = $z;
echo "hello \$z";
}

You need to call session_start() before you try to access the session variable z. And you need to set the new session variable y after you destroy the old session and start a new one.
session_start();
if (isset($_SESSION['z'])) {
session_destroy();
session_start();
$_SESSION['y'] = "";
}

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.

dynamically name session isset how to use?

I am trying to get dynamic $_SESSION[$id] on the second page shown below, but its not working (as per the printout):
First page url
https://example.com/test.php?id=1548393
First page code
<?php
session_start();
$id = $_GET['id'];
$_SESSION[$id] = "mysecretstringline";
?>
Second page url
https://example.com/test2.php?id=1548393
Second page code
<?php
session_start();
$id = $_GET['id'];
if(isset($_SESSION[$id])){
echo "working";
}else{
echo "not working";
}
?>
i found problem we can not use numeric index for $_SESSION
but we can use number in $_SESSION by convert number to roman numerals
first page url
https://example.com/test.php?id=1548393
first page code
<?php
session_start();
$roman_id = romanic_number($_GET['id']);
$_SESSION[$roman_id] = "mysecretstringline";
function romanic_number($integer, $upcase = true)
{
$table = array('M'=>1000, 'CM'=>900, 'D'=>500, 'CD'=>400, 'C'=>100, 'XC'=>90, 'L'=>50, 'XL'=>40, 'X'=>10, 'IX'=>9, 'V'=>5, 'IV'=>4, 'I'=>1);
$return = '';
while($integer > 0)
{
foreach($table as $rom=>$arb)
{
if($integer >= $arb)
{
$integer -= $arb;
$return .= $rom;
break;
}
}
}
return $return;
}
?>
second page url
https://example.com/test2.php?id=1548393
second page code
<?php
session_start();
$roman_id = romanic_number($_GET['id']);
if(isset($_SESSION[$roman_id])){
echo "working";
}else{
echo "not working";
}
function romanic_number($integer, $upcase = true)
{
$table = array('M'=>1000, 'CM'=>900, 'D'=>500, 'CD'=>400, 'C'=>100, 'XC'=>90, 'L'=>50, 'XL'=>40, 'X'=>10, 'IX'=>9, 'V'=>5, 'IV'=>4, 'I'=>1);
$return = '';
while($integer > 0)
{
foreach($table as $rom=>$arb)
{
if($integer >= $arb)
{
$integer -= $arb;
$return .= $rom;
break;
}
}
}
return $return;
}
?>
output
working
thanks #gre_gor and #Katie
Could be that in your normal code (this just looks like a quick mockup), you have a space after ?> somewhere. That could cause issues.
<?php
// start.php
session_start();
$id = $_GET['id'];
$_SESSION[$id] = "mysecretstringline";
and
<?php
// next.php
session_start();
$id = $_GET['id'];
if (isset($_SESSION[$id])) {
echo "working";
} else {
echo "not working";
}
works for me. Notice no ?> characters.
UPDATE:
The following might be of interest regarding session name constraints (can a php $_SESSION variable have numeric id thus : $_SESSION['1234’])
You have that issue in your example you could just add an id_ and then do the same check when validating/getting the session.

PHP tables not printing out?

I'm calling a specific function, either getTaskList0, getTaskList1, or getTaskList2, each the same as below, with the number after task referring to the getTaskList number (in TaskManagerDAO):
function getTaskList0(){
$lst=array();
$con=$this->getDBConnection();
$result = $con->query("SELECT name, score FROM task0 ORDER BY score DESC");
$i = 0;
$counter=0;
while (($row =$result->fetch_row()) && ($counter<5)) {
$rec = new Task($row[0],$row[1]);
$lst[$i++]=$rec;
$counter++;
}
return $lst;
}
Task:
<?php
class Task{
public $name;
public $score;
function __construct($name,$score) {
$this->name = $name;
$this->score = $score;
}
}
The function is called in here:
<?php
session_start();
if(!class_exists('Action')){
include_once 'Action.php';
}
if(!class_exists('TaskManagerDAO')){
include_once 'TaskManagerDAO.php';
}
class Action_DisplayList implements Action{
public function execute($request){
if(!isset($_SESSION['functCount']))
$_SESSION['functCount']=0;
$functCount=$_SESSION['functCount'];
$functionName="getTaskList{$functCount}";
echo $functionName;
$dao = new TaskManagerDAO();
$names = $dao->$functionName();
$_SESSION['names'] = $names;
$last = sizeof($names);
$start = 0;
$_SESSION['start'] = $start;
$_SESSION['last'] =$last;
header("Location: tasklist.php");
}
}
?>
I'm trying to call the function by putting a variable at the end of the function name as a string and then calling the function. This works as I don't get any errors, but the list does not show up in the table, which is what this code is supposed to do:
<?php
if(isset($_POST['Add']) && ($_POST['name']!=="") &&!empty($_POST['Add'])){
include 'Action_Add.php';
Action_Add::execute();
}
$functCount=0;
$_SESSION['functCount']=0;
$names = $_SESSION['names'];
$start=$_SESSION['start'];
$last = $_SESSION['last'];
for($count = $start; $count < $last; $count++){
$name=$names[$count];
echo "<tr>";
echo "<td>".($count+1)."</td>";
echo "<td>".$name->name."</td>";
echo "<td>".$name->score."</td>";
echo "</tr>";
}
?>
EDIT:
I restarted my computer and everything and for the first run load of the page it worked perfectly. After that though, it stopped working though.
Use session_start(); before start using $_SESSION. So in your case, try something like
<?php
session_start();
if(isset($_POST['Add']) && ($_POST['name']!=="") &&!empty($_POST['Add'])){
//.... remaining code here
Note: To use cookie-based sessions, session_start() must be called before outputing anything to the browser.

String in php session

How i can put string in a session?
for. e.g. : $_SESSION_[$questioncounter+'question'] = $accepted;
if _$questioncounter = 2_, this mean $_SESSION_['2question']
Use a .(dot) to concat string and variable and remove _ from $_SESSION_ try
$_SESSION[$questioncounter.'question'] = $accepted;
so full code :-
<?php
session_start();
$questioncounter = 2;
$accepted = 'yes';
$_SESSION[$questioncounter.'question'] = $accepted;
echo $_SESSION['2question']; // yes
?>
Well, sometimes concatenation is needed but not in this case. Building variables by concatenating strings in this case would be the worst approach.
This is the way you should do things
// start session
if(!isset($_SESSION)){
session_start();
}
// now, add your questions to the $_SESSION this way
$question = array('Is the sky really blue?', 'Should I stay or should I go?', 'Why I can\'t fly');
$_SESSION['question'] = $question;
// or this way
$_SESSION['question'][0] = 'Is the sky really blue?';
$_SESSION['question'][1] = 'Should I stay or should I go?';
...
// add their status this way
$_SESSION['question'][0]['accepted'] = 1; // or $_SESSION['question'][0]['status'] = 1;
$_SESSION['question'][1]['accepted'] = 0;
// and finally use them like this
echo $_SESSION['question'][0];
// or
if($_SESSION['question'][0]['accepted']){
// say 'Bravo!'
}

is structure of code causing undefined $_SESSION variables?

When I navigate to a page which is locked (in other words when the box which states you have to Continue appears, I am getting undefined $_SESSION variables. Before I included the if (allowed_in()=== "Allowed"){ statement, I was not getting any undefined $_SESSION variables but as now need that if statement, Im starting to get those variable errors.
For the $_SESSION undefined errors, is it because I am placing the $_SESSION variables in the wrong place?
Below is an example QandATable.php order of code looks like:
<?php
ini_set('session.gc_maxlifetime',12*60*60);
ini_set('session.gc_divisor', '1');
ini_set('session.gc_probability', '1');
ini_set('session.cookie_lifetime', '0');
require_once 'init.php';
//12 hours sessions
session_start();
include('steps.php'); //exteranlised steps.php
?>
<head>
<?php
if (isset($_POST['id'])) {
$_SESSION['id'] = $_POST['id'];
}
if(isset($_POST['sessionNum'])){
//Declare my counter for the first time
$_SESSION['initial_count'] = $_POST['sessionNum'];
$_SESSION['sessionNum'] = intval($_POST['sessionNum']);
$_SESSION['sessionCount'] = 1;
}
elseif (isset($_POST['submitDetails']) && $_SESSION['sessionCount'] < $_SESSION['sessionNum']) {
$_SESSION['sessionCount']++;
}
?>
</head>
<body>
<?php
//once session is expired, it should log the user out, but at mo this isn't happening
if ((isset($username)) && (isset($userid))){ //checks if user is logged in
if (allowed_in()=== "Allowed"){
//QandATable.php code:
}else{
$page = allowed_in()+1;
?>
<div class="boxed">
Continue with Current Assessment
<?php
}
}else{
echo "Please Login to Access this Page | <a href='./teacherlogin.php'>Login</a>";
//show above echo if user is not logged in
}
?>
Below is the full steps.php:
<?php
$steps = array(1 =>'create_session.php',2 => 'QandATable.php',3 => 'individualmarks.php',4 => 'penalty.php',5 => 'penaltymarks',6 => 'complete.php');
function allowed_in($steps = array()){
// Track $latestStep in either a session variable
// $currentStep will be dependent upon the page you're on
if(isset($_SESSION['latestStep'])){
$latestStep = $_SESSION['latestStep'];
}
else{
$latestStep = 0;
}
$currentStep = basename(__FILE__);
$currentIdx = array_search($currentStep, $steps);
$latestIdx = array_search($latestStep, $steps);
if ($currentIdx - $latestIdx == 1 )
{
$currentIdx = $_SESSION['latestStep'];
return 'Allowed';
}
return $latestIdx;
}
?>
session_start() must go before any content.
Note:
To use cookie-based sessions, session_start() must be called before
outputing anything to the browser.
http://php.net/manual/en/function.session-start.php

Categories