PHP $_SESSION not working in function - php

Firstly, I have searched many threads and topics and they all keep saying its function placement but thus far I do not see a issue with my placement. I am desperate to get this is working because I am SICK of looking at 50+ extra lines of repetitive code.
resetpassword.php (RELEVANT CODE):
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/security/sslcheck.php';
$ResetID = $_GET["ID"];
session_start();
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/functionality/error.php';
print_r(array_values($_SESSION));
if(empty($ResetID) && !isset($_SESSION["ERR"]) && !isset($_SESSION["ERR_MSG"])) {
$ResetPassword = "REQUEST";
if(isset($_POST["email-search"]) && !empty($_POST["email-search"])) {
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/functionality/users/request.php';
// Start Request Process
$Request = RequestPasswordReset($_POST["email-search"]);
if($Request === "USER_NOT_FOUND") {
DisplayError("Password Reset Request Failed", "The specified email is not tied to any accounts in our system.", "/account/resetpassword.php");
} else if ($Request === "MAIL_FAILURE") {
DisplayError("Password Reset Request Failed", "Failed to email you the password reset email.", "/account/resetpassword.php");
} else {
DisplayError("Password Reset Request Success", "We have sent a email that contains a link to reset your password.", "/account/resetpassword.php");
}
}
More Relevant Code
<?php
if (isset($_SESSION["ERR"]) && isset($_SESSION["ERR_MSG"])) {
echo '<div id="resetPasswordStatus">';
echo '<h4>' . $_SESSION["ERR"] . '</h4>';
echo '<p>' . $_SESSION["ERR_MSG"] . '</p>';
echo '</div>';
session_destroy();
}
?>
error.php (ALL CODE):
<?php
session_start();
function DisplayError($title, $body, $returnlink) {
$_SESSION["ERR"] = $title;
$_SESSION["ERR_MSG"] = $body;
header("Location: " . $returnlink);
}
?>
I have experiment in many ways with my placement of require_once of error.php, but have found no luck. I understand $_SESSION is a superglobal and require or require_once copy the code right into place where required. However even copying error.php manually into resetpassword.php I was unable to get the function to work. Thank you guys for your help as it really means a lot!
The expected output is after the callback after the request for a password reset, is the alert to display. Code for this alert can be seen under More Relevant Code.

Solution:
In the error.php if you add exit(); after the header redirect it allows for PHP to pause execution while the redirect occurs which prevents the error displaying code from running its code and then wiping the session which leaves the redirect empty in terms of sessions.

You are calling the function after the if statement empty($ResetID)
Your function isn't running if the $_GET['ID'] is not empty so change it to !empty($ResetID)

Related

How to avoid the catch-22 of PHP session_start() vs "headers already sent" warning?

I have an application that works TOTALLY fine on my local server.
It requires two things:
An active $_SESSION so that a number of key data elements are available on every page. (Stuff like user_id, and user_role.)
A couple of "require_once()" calls at the top of my pages, so that I have some constants available and standard messages available and the same header on every page.
Again, on my local server (using php 5.6), this is all fine and dandy.
On my HOST server (also using php 5.6), however, I have a catch-22:
If I call "session_start()" on each of my pages, I get a "headers already sent" warning, due to my use of "require_once()".
If I do NOT call "session_start()" on each of my pages, the $_SESSION variable is empty when it gets to the next page.
The only ideas I have seem very bad:
Don't use sessions and pass all my data in the URL. This seems insecure, clumsy, and like bad practice.
Don't use "require_once()", which seems really stupid as I'll have duplicate code all over the place.
Any ideas about what I should do?
I am on a shared server, so I don't think I can modify the php.ini file. And my host company, who has been very helpful about any other issue, has been totally silent over the past 2 weeks as I've sent them questions about this.
I have created a very simple example that shows the issue. Probably the most informative bit is in the comments for "firstpage.php", specifically the "if" statement under the comment "Under what circumstances is session being started".
Here is the index page (called mytestindex.php).
<?php
// Make sure $_SESSION array is available.
session_start();
//***************************************************
// Print to the screen information about the session
// This sends headers on the host server.
//***************************************************
require_once("printsessioninfo.php");
// Set SESSION variable for later use on other pages
$_SESSION['emp_id'] = 100;
echo "\n\nThe employee id stored in SESSION is: " . $_SESSION["emp_id"] . "\n\n";
// Open next page when button clicked.
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Set the name of the page we are going to next
$filename = "firstpage.php";
// ***************************************************************************************************
// If headers have't been sent (seems to depend on php.ini settings), simply call the header function
// This is the code that has worked on my local machine for years.
// ***************************************************************************************************
if (!headers_sent()) {
$redirect_to = "Location:" . $filename;
exit(header($redirect_to));
// *******************************************************************************************************************
// If headers have already been sent (require_once() above will do that), using the header function
// will generate a "headers have already been sent" warning on the host server. So need to use Javascript to avoid that.
// ********************************************************************************************************************
} else {
echo " Opening page with Javascript. ";
$code = '<script type="text/javascript">';
$code = $code . 'window.location.href="' . $filename . '";';
$code = $code . '</script>';
$code = $code . '<noscript>';
$code = $code . '<meta http-equiv="refresh" content="0;url=' . $filename . '" />';
$code = $code . '<noscript>';
echo $code;
exit;
}
}
?>
<div>
<form action="mytestindex.php" method="post">
<button type="submit">Go to first page</button>
</form>
</div>
Here is the page it links to (called firstpage.php):
<?php
/* First page */
//***************************************************
// Print to the screen information about the session
// This sends headers on the host server.
//***************************************************
require_once("printsessioninfo.php");
//***********************************************************************
// Print out other information before session started again on this page
if (headers_sent()) {
echo "Headers have already been sent.\n";
} else {
echo "No headers have been sent.\n";
}
if (isset($_SESSION)) {
echo "Session variable exists.\n";
} else {
echo "Session variable does not exist.\n";
}
//*****************************************************
// Under what circumstances is session being started
// and does it cause a "headers already sent" warning?
//*****************************************************
// THIS check is what works on my local machine, with no warnings about headers being sent.
if ( (!isset($_SESSION)) && (!headers_sent()) ) {
echo " START SESSION: session var is not set AND headers have not been sent.";
session_start();
} elseif (session_status == PHP_SESSION_NONE) {
echo " START SESSION: session does not exist";
session_start();
// THIS check is what works on my host server, BUT throws the warning about headers being sent.
} elseif (!isset($_SESSION)) {
echo " START SESSION: session var is not set";
session_start();
} else {
echo " No need to start a new session";
}
//******************************************************************************
echo "\n\n The employee id stored in the session variable is: " . $_SESSION["emp_id"] . " .";
if (session_status() == PHP_SESSION_ACTIVE) {
echo "\n\n\n NOW Session is active!";
}
?>
Here is a snippet of code that prints out some session info, so I have demonstrate how "require_once()" affects things (called printsessioninfo.php):
<?php
// Print session info
echo "<pre>";
$sessionfile = ini_get('session.save_path') . '/' . 'sess_'.session_id();
echo 'session file: ' . $sessionfile . ' ';
echo 'size: ' . filesize($sessionfile) . "\n\n\n";
if (session_status() == PHP_SESSION_NONE) {
echo "Session does not exist!\n";
} elseif (session_status() == PHP_SESSION_DISABLED) {
echo "Session is disabled!\n";
} elseif (session_status() == PHP_SESSION_ACTIVE) {
echo "Session is active.";
}
?>
I was able to fix this (thank you "mister martin"), by moving the code for "session_start()" into my config.php file, making sure it was the VERY FIRST bit of code.
Then for every page in the application I made sure this was the first line of code:
<?php
require_once("config.php");
And that did the trick, for both development and host servers.
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
Explanation required as it seems it wasn't clear enough (??):
If the status of the session is NONE then start it.
http://php.net/manual/en/function.session-status.php
http://php.net/manual/en/session.constants.php
Also this should be called BEFORE any require or require_once

My php script outputs a blank page

I have a php page that accepts and processes a form submission, the page displays normally when it is requested, however if the page is submitted and its form validation fails, the page suppose to be re-displayed with the form errors, but on page re-display, php displays a blank page when it reaches the error processing block. Here is the code that processes the validation errors:
<?php if(isset($errorLog) and is_array($errorLog)): ?>
<div class="alert alert-danger">
<?php $output = '';
if($errorLog['message'] == '') {
$output = "<ul class='error-list'>";
foreach($errorLog as $key => $value) {
if ($key != 'has_error_occured') {
$output .= "<li><strong>{html($key)}</strong>
<span>{html($value)} </span></li>";
}
}
$output .= "</ul>";
} else {
$msg = $errorLog['message'];
$output .= "<p>{html($msg)}</p>";
}
echo $output;
?>
</div>
<?php endif; ?>
and here is the code that processes the form submission
if(isset($_GET['transfer']) or
(isset($_POST['action']) and $_POST['action'] == TRANSFER)){
$transfer_type = $_GET['ttype'];
if(isset($_POST['action']) and
$_POST['action'] == TRANSFER){
//process money transfer.
$log = process_transfer();
if(isset($log) and is_array($log)){
if($log['has_error_occured']){
$_SESSION['error_log'] = $log;
//unset log
unset($log);
include_once $docRoot . '/users/temp/tranfer.html.php';
exit();
}else{
$_SESSION['transfer_msg'] = "Your international
transfer was processed successfully";
header('Location: ?summary');
}
}
//reload primary page.
header('Location: .');
}else{
include_once $docRoot . '/users/temp/tranfer.html.php';
exit();
}
}
Note:
I have tried passing the error array as a global variable as
you can see in the code snippet above.
I have also tried passing it in a session.
I also have tried using output buffering by appending the ob_start() at the beginning and ob_end_flush() at the end the form script.
I have also added error_reporting(-1); ini_set('display_errors', true); at the start of the form script so as to know if the page encounters any error during processing, all to no avail.
I am using PhpStorm with XAMPP v3.2.1 for development on windows 7.
Please, any help as to the cause of this nightmare will be appreciated. Thanks.
If you wanna use $_GET and $_POST then better use $_REQUEST, it allows to access both $_GET and $_POST
not TRANSFER but it should be "TRANSFER"
if errorlog is session data then it should be
if(isset($_SESSION['errorLog']) and is_array($_SESSION['errorLog'])):
i didn't find any thing created by name message
if($errorLog['message'] == '')
why u used it, i think it must be 'has_error_occured'
I discovered the problem through the output of php_error_log and through the various suggestions in the comments above, the problem problem was that I didn't check if the $erroLog['message'] was set before accessing it. But shouldn't php have outputted a warning instead of resorting to such indeterminate option of not fully executing the rest of the document?

Header already sent after form redirect

Header already sent after form submission, I'm using a redirect to take my form elements to a new page to process them, but i'm getting the header Headers ALready Sent error and I cannot see why.
Is there an better cleaner way to do this?
if(isset($_POST["associate"])) {
$partner = $_POST['partner'];
$location = $_POST['location'];
$redirect = plugins_url() . "/myremovalsquote/inc/associate.php?partner=" . $partner . "&location=" . $location . "";
header('Location: '.$redirect);
} else {
echo 'Failed';
}
Are you using wordpress? Than the problem is maybe caused by plugins_url (). When the error still occurs please double check that there is no data sent to the client (e.g <html> or even a whitespace) before header () is used.

Unsetting PHP session variable doesnt display error message

I am trying to display an error message when there is a username-password mismatch. I set a php session variable if username and password dont match. Then i header back to the same page, with an if conditioned php statement to display an error if the variable is set. But when i unset the variable after error display, there is no error displayed on the page.
I have seen similar problems mentioned in this forum. But i seem to be doing everything right as suggested in questions.. Please help me out...
This is part of my code flow...
<?php
ob_start();
session_start();
.
.
if ($result = $sth->fetch(PDO::FETCH_ASSOC)){
$_SESSION['admin_user'] = $result['id'];
header('Location: admin_user.php');
} else {
$_SESSION['user_found'] = 0;
header('Location: index.php');
}
.
.
//in html body
<?php
if (isset($_SESSION['user_found'])){
if($_SESSION['user_found'] == 0){
?>
<div>
<p class = "bg-danger text-danger">Username Password Mismatch</p>
</div>
<?php
unset($_SESSION['user_found']);
}
}
?>
Now, if unset is removed..it works fine. If it is there, there is no display of error message.
Try not reloading the same page.. remove the header redirect.
if ($result = $sth->fetch(PDO::FETCH_ASSOC)){
$_SESSION['admin_user'] = $result['id'];
header('Location: admin_user.php');
} else {
$_SESSION['user_found'] = 0;
//header('Location: index.php');
}
When I tried the your code, things seem to work fine. Something should be wrong with the code you've not mentioned here..
To troubleshoot the problem instead of
unset($_SESSION['user_found']);
try changing the value of the variable.. say
$_SESSION['user_found'] = -1;

php message using sessions

I am try to develop flash message using sessions in php
suppose on successfully delete query I am setting
$_SESSION["msg"]="record deleted successfully";
header("location:index.php");
and I have the following script on all pages which checks if msg variable is available it echo its value as below
if(isset($_SESSION["msg"]) && !empty($_SESSION["msg"]))
{
$msg=$_SESSION["msg"];
echo "<div class='msgbox'>".$msg."</div>";
unset($_SESSION['msg']); //I have issue with this line.
}
if I comment
unset($_SESSION['msg']);
message is being displayed, but with this line message is not being displayed
what am I doing wrong, or any alternative.
You are saying that you have that script on every page. So my guess is that after you make header("location:index.php"); your code continues to run - your message is displayed and unset (you don't see it because of redirect to index.php). When you are redirected to index.php your message is already unset.
Try adding exit; after header("location:index.php");.
Edit: I will add two examples with one working and one not. To test you need access test page with following link - /index.php?delete=1
In this example you will never see message. Why? Because header function does not stop code execution. After you set your session variable and set your redirect your code continues to execute. That means your message is printed and variable unset too. When code finishes only than redirect is made. Page loads and nothing is printed because session variable was unset before redirect.
<?php
session_start();
// ... some code
if ($_GET['delete']==1) {
$_SESSION["msg"] = "record deleted successfully";
header("location: index.php");
}
// ... some code
if (isset($_SESSION["msg"]) && !empty($_SESSION["msg"])) {
$msg = $_SESSION["msg"];
echo "<div class='msgbox'>" . $msg . "</div>";
unset($_SESSION['msg']);
}
// ... some code
?>
But this code probably will work as you want. Note that I have added exit after header line.
You set your message, tell that you want redirect and tell to stop script execution. After redirect your message is printed and unset as you want.
<?php
session_start();
// ... some code
if ($_GET['delete']==1) {
$_SESSION["msg"] = "record deleted successfully";
header("location: index.php");
exit;
}
// ... some code
if (isset($_SESSION["msg"]) && !empty($_SESSION["msg"])) {
$msg = $_SESSION["msg"];
echo "<div class='msgbox'>" . $msg . "</div>";
unset($_SESSION['msg']);
}
// ... some code
?>
You clearly said that you have that code (message printing) on all pages. If your code is similar to my example than adding exit should fix your problem.
Another problem might be that you are doing more than one redirect.
You can simply set your session empty or null instead of unset it. Just do:
$_SESSION['msg']=NULL;
Or
$_SESSION['msg']="";

Categories