Session lost after form submit in wordpress - php

The session I set is lost after the form is submitted.
I had built the session class to set new session, unset and so on. In function.php of wordpress template.
function.php
if (!session_id()) {
session_start();
}
include get_template_directory() . "/custom/session.php";
Session.php
class session {
function __construct() {
}
function set_flashdata($name, $value) {
$_SESSION[$name] = $value;
}
function flashdata($name) {
if (isset($_SESSION[$name])) {
$str = $_SESSION[$name];
return $str;
} else {
return FALSE;
}
}
function userdata($name) {
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
} else {
return FALSE;
}
}
function set_userdata($name, $value) {
$_SESSION[$name] = $value;
}
function unset_userdata($name) {
if (isset($_SESSION[$name])) {
unset($_SESSION[$name]);
}
}
}
I try to set session as :
<?php
$sess = new session();
$sess->set_userdata('sess_name',"some value");
?>
<form action="get_permalink(212);">
//input buttons
</form>
After submit the form it goes to the permalink(212). Then I tried.
<?php
$sess = new session();
$value = $sess->userdata('sess_name');
var_dump($value); //returns false. That means session is lost after form submit. Why?
?>

You need to move session start/resume into your Session's constructor.
Like so:
class session
{
function __construct()
{
if (! session_id()) {
session_start();
}
}
Another thing to mention, every time you'll do new Session you'll be getting an object of the same functionality working with same global variable $_SESSION.
You don't need more than one $session object, it would be a good time to look into Singleton pattern.

You have to call always session_start() for each request.
The mission of session_start() is:
Creates a new session
Restart an existing session
That means, if you have created a session, and you don't call to the method session_start(), the variable $_SESSION is not going to be fulfilled.
Except: If in your php.ini you have set the option session.auto_start to 1, then, in that case it is not needed to call the session_start() because the variable $_SESSION is fulfilled implicitly.

You need to use wordpress global variable for condition that session is set or not something like :
global $session;
if (!session_id()) {
session_start();
}
include get_template_directory() . "/custom/session.php";

It might be due to www. at the start of your website domain. Make sure that both of pages use the same structure.
Also I faced with the same issue long time ago when the form sends the data to a secured address (https://)
I hope these two items may help you.

Sounds to me like session_start() is not set at the start of the page that get_permalink(212;) refers to.
I have almost no experience with WP itself though, so I might misunderstand the functionality of get_permalink()

I agree with the answer from #rock3t to initialize session in constructor of class, but every time a class object is initiated, it will go to check for session!
Instead, if you are fine, the simplest way to get access to session is by adding following lines to your wp-config.php file before the call to wp-settings
if (!session_id())
session_start();
This will set/initialize session globally and you won't need to set/check for session_start in constructor of a class.
Thank you.

Related

PHP Session Login Controller

I am trying to create a login controller for my website ... in terms of keeping people logged in I've decided to use sessions.
I am currently attempting to create a class that can be referenced when I include the controller file of the sessions. This will allow me to create, authenticate (delete) and update sessions.
<?php
class Session {
static function start($name, $value) {
session_start();
$_SESSION[$name] = $value;
$_SESSION['EXPIRE'] = time() + 10;
}
// checking for expire
static function auth() {
if (isset($_SESSION['EXPIRE']) && $_SESSION['EXPIRE'] < time()) {
$_SESSION = array();
session_destroy();
}
}
static function update($time = 20) {
if (isset($_SESSION['EXPIRE'])) {
$_SESSION['EXPIRE'] = time() + $time;
session_regenerate_id(false);
}
}
}
Currently it does not set sessions properly. When I try to call the sessions on pages once I set them it does not fetch properly.
The session isn't expiring before I call it because I never call the function that expires it inside the class on the document.
You can't call your Session class as you need to include session_start() and you are only having this in the start method.
Option 1: You would have to call session_start() in each page where you want to deal with sessions
Option 2: Add a function to your class and call it after your class is created and add in there session_start() so wherever you include the Session Class session_start would already been initialized
Example:
Sessions.php
class Session {
static function init(){
session_start();
}
//rest of your methods...
}
//initialize it
Session::init();
page-that-uses-session.php
include('Sessions.php');
Session::update();
Better set php session timeout variable in php.ini or from ini_set() function and don't create own $_SESSION['expire'] variable; You can regenerate_session_id() each time when user sent request; Better test user ip address in session. In most projects you have one page on server or only your own pages.
Set user id in session:
$_SESSION['userid'] = $loggoed_id_from_db;
// and test
if((int)$_SESSION['userid'] == 0){
header('Location: logout.php');
exit;
}else{
if(empty($_SESSION['ip'])){
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}else{
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']){
header('Location: logout.php');
exit;
}
}
}
And probably you don't start session from class!

Can the session expire when using a function of an included file?

I've got this session variable, which was initiated in index.php
<?php
$sid = session_id();
if (empty($sid) {
session_start();
}
//value of the variable can be changed and saved before coming back to the index
if(!isset($_SESSION['context'])){
$_SESSION['context'] = 1;
}
//...
?>
Later a script is used to create or update a database entry.
entryupdate.php:
<?php
include_once("template.php");
/*....*/
$sid = session_id();
if (empty($sid)) {
session_start();
}
/*....*/
//Create a new entry, context is not given in the $input_object at this point.
$template = new Template($input_object);
$context = $template->getContext();
?>
template.php is a script where only the Template Object is defined, so I don't call $session_start in it, my rationale being that it would always be called by the scripts including it, as it is in the case I'm describing here. Here is the relevant code:
<?php
class Template
{
private $m_context;
//other private parameters
function __construct($arguments_object){
if(!is_null($arguments_object)){
/*....*/
$this->m_context = $arguments_object->context;
/*....*/
}
}
/*....*/
function getContext(){
if(!empty($this->m_context)){
return $this->m_context;
}else{
//this would be our case, as the parameter was not initialized yet.
return $_SESSION['context'];
}
}
/*....*/
}
?>
Now, a colleague stumbled on an error and upon investigation, I found out that the $context was set to NULL. When I tried to reproduce the issue, the context was correctly initialized. And to be honest, for the few years the tool has been used, it is the first time this kind of issue was encountered.
I've also checked, at no point I am unsetting this particular session variable.
Am I making a false assumption there, in thinking that template.php would find the session variable when the session was started in entryupdate.php where it was included and used?

PHP $_SESSION variables are not being passed between pages

I am working on a school project where I need my .php pages communicating. I have header.php where I set connection to the database and start the session. In order to start the session only once, I've used this:
if(session_id() == '') {
session_start();
}
PHP version is PHP 5.3.10-1 ubuntu3.18 with Suhosin-Patch (cli)
I am trying to pass some $_SESSION variables between pages, but they keep being unset when I try to use them on a page that doesn't set them.
I see many people have complained about this, but I still can't find the solution.
login-form.php
<?php
if (isset($_SESSION["login-error"])) {
echo '<p>'.$_SESSION["login-error"].'</p>';
}
?>
login.php
$_SESSION["login-error"]= "Username or password incorrect";
There is a code snippet of what is not working for me.
Thanks
You can try this.
In your function file put this
function is_session_started()
{
if ( php_sapi_name() !== 'cli' ) {
if ( version_compare(phpversion(), '5.4.0', '>=') ) {
return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
} else {
return session_id() === '' ? FALSE : TRUE;
}
}
return FALSE;
}
Then you can run this in every page you want session started
if ( is_session_started() === FALSE ) session_start();
With this I think you should be good to go on starting your session across pages. Next is to ensure you set a session to a value. If you are not sure what is unsetting your sessions you can try var_dump($_SESSION) at different parts of your code so you be sure at what point it resets then know how to deal with it.
The variables are probable not set, because you haven't activate the session variables with session_start().
session_id() == '' is not a correct conditional . Use instead:
if (!isset($_SESSION)) { session_start();}
if you have session started then you can set a session variable
if (!isset($_SESSION["login-error"])) { $_SESSION["login-error"]= "Username or password incorrect";}
Before you call $_SESSION["login-error"], type session_start(), just for testing, to find when the session signal is missing. You said
PHP $_SESSION variables are not being passed between pages
session_start() and SESSION variables needs to be included at the beginning of EVERY page or at the place where SESSION variables are being called (through a common file, bootstrap, config or sth) at the beginning of EVERY page. ie the command to read those data from the server is needed.
Since my header.php file included "connection.php" file, I put
session_start();
at the beginning of connection.php and deleted it from header.php file. Now it works fine. Thanks all for your help!
PHP sessions rely on components of HTTP, like Cookies and GET variables, which are clearly not available when you're calling a script via the CLI. You could try faking entries in the PHP superglobals, but that is wholly inadvisable. Instead, implement a basic cache yourself.
<?php
class MyCache implements ArrayAccess {
protected $cacheDir, $cacheKey, $cacheFile, $cache;
public function __construct($cacheDir, $cacheKey) {
if( ! is_dir($cacheDir) ) { throw new Exception('Cache directory does not exist: '.$cacheDir); }
$this->cacheDir = $cacheDir;
$this->cacheKey = $cacheKey;
$this->cacheFile = $this->cacheDir . md5($this->cacheKey) . '.cache';
// get the cache if there already is one
if( file_exists($this->cacheFile) ) {
$this->cache = unserialize(file_get_contents($this->cacheFile));
} else {
$this->cache = [];
}
}
// save the cache when the object is destructed
public function __destruct() {
file_put_contents($this->cacheFile, serialize($this->cache));
}
// ArrayAccess functions
public function offsetExists($offset) { return isset($this->cache[$offset]); }
public function offsetGet($offset) { return $this->cache[$offset]; }
public function offsetSet($offset, $value) { $this->cache[$offset] = $value; }
public function offsetUnset($offset) { unset($this->cache[$offset]); }
}
$username = exec('whoami');
$c = new MyCache('./cache/', $username);
if( isset($c['foo']) ) {
printf("Foo is: %s\n", $c['foo']);
} else {
$c['foo'] = md5(rand());
printf("Set Foo to %s", $c['foo']);
}
Example runs:
# php cache.php
Set Foo to e4be2bd956fd81f3c78b621c2f4bed47
# php cache.php
Foo is: e4be2bd956fd81f3c78b621c2f4bed47
This is pretty much all PHP's sessions do, except a random cache key is generated [aka PHPSESSID] and is set as a cookie, and the cache directory is session.save_path from php.ini.

Variables from Session Class not passing to new pages

I defined a session class,which uses values from the $_POST variable in an array called $sessionVars. When a user logs-in a new instance of the session class is created, a construct function sets session variables.I checked that this is working correctly.Problem: When i try to access those variables from a different page the session shows that its not started and those variables are undefined. Confused cause I thought $_SESSION being a super global means its accessible all the time(i.e scope doesn't matter) . I suspect im doing something wrong when I try to access the $_SESSION variables since they are in a class. I appreciate any help..thanks in advance.
class userSession{
public function __construct($sessionVars){
session_start();
$_SESSION['userEmail']=$sessionVars['user'];
$_SESSION['userID']=$sessionVars['userID'];
$_SESSION['userFolder']='users/user_'.$_SESSION['userID'];
}
/*just for housekeeping. not used in application*/
function showvars(){
echo $_SESSION['userEmail'].'<br><br>';
echo $_SESSION['userID'].'<br><br>';
echo $_SESSION['userFolder'];
$sessionID=session_id();
echo '<br><br>'.$sessionID;
}
}//**END USER SESSION
/*This is the login script that calls the session*/
include 'library.php';
$show=new render;
$show->index();
if(!isset($_POST['login']) ){
$show->usrLogin();
} else{
if(!empty($_POST['email'])){
$postVars=array('user'=>$_POST['email'],'pass'=>$_POST['password']);
$user=new user();
$data=$user->loginUser($postVars);
$currSession=new userSession($data);
}else{
die('No data in POST variable');}
}
/*file upload that needs the session[userFolder] variable*/
function file_upload(){
$userFolder=&$_SESSION['userFolder'];
echo '<hr>userFolder is : '.$userFolder;
function do_upload(){
if(!empty( $_FILES) ){
echo $userFolder.'<hr>';
$tmpFldr=$_FILES['upFile']['tmp_name'];
$fileDest=$userFolder.'/'.$_FILES['upFile']['name'];
if(move_uploaded_file($tmpFldr,$fileDest)){
echo 'file(s) uploaded successfully';
}
else{
echo 'Your file failed to upload<br><br>';
}
return $fileDest; //returns path to uploaded file
} else{die( 'Nothing to upload');}
}//END FUNCTION DO_UPLOAD,
/*Perform upload return file location*/
$fileLoc=do_upload();
return $fileLoc;
}
You need to instantiate an object of this class on every page that uses the session (or start the session manually). Also, you'll not want that constructor, instead some other way of setting vars. This is just for illustration of how it works with your current code, there are much better approaches:
class userSession {
public function __construct(){
session_start();
}
function set_login_vars($sessionVars){
$_SESSION['userEmail']=$sessionVars['user'];
$_SESSION['userID']=$sessionVars['userID'];
$_SESSION['userFolder']='users/user_'.$_SESSION['userID'];
}
}
//page1.php
$session = new userSession;
$session->set_login_vars($loginVars);
//page2.php
//you need to start the session, either with the class
$session = new userSession;
//or session_start();
print_r($_SESSION);

PHP session being lost

I'm trying to implement and authentication system with jQuery and PHP. All the php work is made in the controller and datahandler class. There is no php code inside the .html files, all the values in .html files are rendered via jQuery that request the data from php server. So what I'm trying to do is:
When user clicks the login button, the jQuery makes a call to the authenticate() method in my controller class, it checks if the user is correct and stuff, and if it is, start the session and set the user_id on the session so I can access it later, and returns the userId to the jQuery client again.
After that, if everything is fine, in jQuery I redirect it to the html file. On the html file I call a jQuery from the <script> tag that will handle other permissions. But this jQuery will access the method getPermissionString (from the same class of authenticate() method mentioned before), and it will need to get the session value set in authenticate method.
The Problem:
When I try to get the session value inside getPermissionString() it says:
Notice: Undefined variable: _SESSION
I've tried to check if the session is registered in the second method, but looks like it's not. Here is my PHP code.
Any idea? Thanks.
public function authenticate($login, $password)
{
$result = $this->userDataHandler->authenticateUser($login, $password);
if(is_numeric($result) && $result != 0)
{
session_start();
$_SESSION["uid"] = $result;
if(isset($_SESSION["uid"]))
{
echo "registered";
$userId = $_SESSION["uid"];
}
else
{
echo "not registered";
}
echo $result;
}
else
{
echo 0;
}
}
public function getPermissionString()
{
if(isset($_SESSION["uid"]))
{
echo "registered";
$userId = $_SESSION["uid"];
}
else
{
echo "not registered";
}
}
Before you can access $_SESSION in the second function you need to ensure that the program has called session_start() beforehand. The global variable is only populated when the session has been activated. If you never remember to start a session before using it then you can change the php.ini variable below:
[session]
session.auto_start = 1
Further, you said that you're using a class for your code. In this case you can also autos tart your session each time the class in created by using magic methods:
class auth {
function __construct() {
session_start();
}
function yourfunction() {
...
}
function yoursecondfunction(){
...
}
}
If you don't have session.auto_start enabled, and authenticate and getPermissionString are called on two different requests, you need to call session_start() in each function.
If you need more information on how the session ID is passed, just read Passing the Session ID
You should not use that function if session is not started. So throw an exception:
public function getPermissionString()
{
if (session_status() !== PHP_SESSION_ACTIVE)
{
throw new Exception('No active session found.');
}
if(isset($_SESSION["uid"]))
{
echo "registered";
$userId = $_SESSION["uid"];
}
else
{
echo "not registered";
}
}
This ensures the pre-conditions of your functions are checked inside the function so you don't need to check it each time before calling the function.
You will now see an exception if you wrongly use that function and it will give you a backtrace so you can more easily analyze your code.
For php sessions to work you have to call session_start() every time you script is requested by the browser.

Categories