PHP session variable not showing on other page - php

I have a page a to which I am posting the data from a python script. I am processing that data, storing the data into SQL. I want to store the time when this post request is made.
Note that the post request is made continuously. So the session variable keeps on changing. Well here is the little code for that-
<?PHP
session_start();
include 'db.inc.php';
if(isset($_POST['data']){
$data_decode = (array)json_decode($_POST['data']);
$data_var1 = $data_decode['var1'];
$data_var2 = $data_decode['var2'];
$data_var3 = $data_decode['var3'];
$date = date('Y-m-d H:i:s');
$_SESSION['time'] = $date; //Set the session with current time
$sql = "UPDATE `table` SET row1=$data_var1, row2=$data_var2 WHERE row3=$data_var3";
$result = mysqli_query($db,$link) or die('Table could not be updated');
echo "Following data inserted: row1=$data_var1, row2=$data_var2, at $_SESSION['time']"; //Echoing the data and time as expected
?>
Now, I have another page on the same domain, which makes the ajax request and fetches out the data every second from the SQL table I just inserted the data into. So here is the whole scenario- The client python script makes the post request to the webpage, which updates the sql with the received data, sets the session variable. Another page simultaneously fetches that data out using ajax and shows it.
Now I am calling the session variable on another page as shown-
<?php
session_start();
if(isset($_SESSION['time']){ echo $_SESSION['time']; } //Didn't echoes anything
?>
I used <?php print_r($_SESSION) ?> to check whether the session variable is set or not, it echoed "Array()", which means my session variable is not set. So my question is, What I am doing wrong and how can I correct it?

Make sure to call session_start() at the beginning of every page...
You forgot the semicolon after the declaration.
$_SESSION['time'] = $date
should be
$_SESSION['time'] = $date;

You forgot session_start()
<?php
session_start();
if(isset($_SESSION['time']){ echo $_SESSION['time']; } //Didn't echoes anything
?>

I am trying to reconstruct which components are acting in your scenario.
So first you mention a Python script. How does it work together with PHP? Does it actually emit a HTTP request itself, or does it only send HTML to a browser that is then going to PHP? If Python is acting like a HTTP client, this is important, because PHP sessions use cookies, so your Python script has to be able to accept the "Set-cookie" HTTP header and deal with it, especially send it back on later requests.
Second info is that there is some Ajax going on. This points to a browser and some Javascript as a client, and this combo is clearly able to accept any cookie that is set by PHP.
But how do the browser and the Python script communicate? How does the browser know which cookie the Python script got back from PHP so that the session data can be loaded?
I hope you see the hole in your approach. Posting data from Python into the database is one thing, saving the time of this event probably is a global information (date of last DB update), and not a session information (is different per Python client). As such, the session is the wrong location for storage. And the other obstacle is that your Ajax client cannot share the session ID from your Python client! And the last downside to sessions: If it would work, you would constantly interfere with both requests, because sessions use locking to prevent two requests deleting each others data. This is especially bad because a hanging Ajax request might prevent the Python script from writing to the database, and vice versa.
Find a way to store a global information on your server. You already have a database, why not use it for this?

Related

PHP session seems to work only after being called twice

I am quite confused and would appreciate some help. I have an index.php which starts a session at its very beginning (session_start();). From the browser, I see that a cookie PHPSESSID is created with the id of the session.
However, in the folder /var/lib/php/sessions (the session.save_path), nothing is put.
If I declare any session variables in index.php they are not passed over to other php scripts with session_start() (not even with session_id(the-whatever-PHPSESSID); session_start();).
However, if I call session_start() again, I get the session functioning as I thought it ought (and in the session.save_path I can find a reference to the session id created).
It is quite confusing to me and, perhaps, given by befuddlement, I might not be explaining what happens well. Please let me know if you require any more info!
Here is what I have:
index.php
<?php
session_start();
$_SESSION['sessionid'] = session_id();
$sessionid = "'".$_SESSION['sessionid']."'";
$_SESSION['maxQueries'] = 1883; //11*171 + 2
$_SESSION['cCount'] = 0;
$_SESSION['queries'] = 0;
?>
There is a form there (index.php) which has a captcha key created by a php file (captcha code by Simon Jarvis) which also starts with session_start(). The captcha is generated like this:
(index.php)
<div class="field">
<input type="checkbox" id="human" name="human" onclick="captcha();"/>
<label for="human" class="humancb">I am human</label>
</div>
<div id = "captcha"></div>
(javascript)
if(document.getElementById("human").checked){
document.getElementById("captcha").innerHTML = "<img src='./assets
/php/captcha_code_file.php?rand="+ Math.random() +"' id='captchaimg' >
</img>";}
When I load index.php I see a PHPSESSID - nothing in /var/lib/php/sessions. When I click on the captcha checkbox (and the captcha_code_file.php is invoked) I get the session to work. What am I doing wrong? What am I so terribly missing?
Thank you!
Edit1: I think I managed to pinpoint the issue. As #Hans indicated, the culprit was the $sessionid variable. I was using it to pass it as input to a javascript function when the form was being submitted. Then, I was using the javascript var 'sessionid' in a xhr post request to a php page. All php pages had session_start() in the beginning and their session_id was also passed through javascript. In retrospect, I am not at all sure I can provide an argument as to why I did that, but, anyway, when I omitted that part and the javascript was sending in the xhr post all variables unrelated to the session, the issue seemed to go away. Again, I am not sure I phrase this well and I guess I should start slapping myself on the face a couple of times :D...
Edit2: I would have liked if I could choose BOTH answers as very helpful. This would have reflected the truth. However, Hans, please understand that even though you were closer in a sense (showed the culprit here), it all happened for a completely - or so I think - different reason. That is why I choose Walther's answer. If I could, I would have chosen both.
Thank you both so much for helping!!!!!!
From the official documentation:
Sessions follow a simple workflow. When a session is started, PHP will
either retrieve an existing session using the ID passed (usually from
a session cookie) or if no session is passed it will create a new
session. PHP will populate the $_SESSION superglobal with any session
data after the session has started. When PHP shuts down, it will
automatically take the contents of the $_SESSION superglobal,
serialize it, and send it for storage using the session save handler.
=> saving to a file happens between requests when it's finished executing the current script, not on first session_start call.
http://php.net/manual/en/session.examples.basic.php
$sessionid = $_SESSION['sessionid']; is the correct statement not
$sessionid = "'".$_SESSION['sessionid']."'";
Try this adjustment and see what happens

PHP Session Variable not Available

I have a PHP file (approvals.php) that only gets executed on an AJAX call. It has a postgresql query that searches a table and uses a customer id, which is set as a session variable. Problem is, it seems I can't access this session variable in this file. My query is like:
$query = "SELECT merchant_id FROM ndovu_merchant_users WHERE customer_id={$_SESSION['customer_id']}";
$result = pg_query($query);
I have tried to echo the session variable $_SESSION['customer_id'] but nothing. However on passing a fixed value to the query, it returns a result.
In your case, i would have checked if the session is set in the first place.
//this should be put at the header of the page
session_start();
if(isset($_SESSION['customer_id']) && !empty($_SESSION['customer_id'])){
echo $_SESSION['customer_id'];
}else{
echo 'session is not set';
}
You need to place session_start(); above the code section where you use it; the top of the page is usually the best place to place it.
Also, it should be noted; you have what is potentially a large security flaw here, by passing in unescaped data.
You should look into using prepared statements if possible; or at least escape your inputs.
The user session is not accesed when the script is called by an ajax request.
The session token wich php requires to obtain the session data is stored in the client side(user) inside a session cookie.
You can read more here
https://stackoverflow.com/a/1535712/3922692
Just pass the user id with GET or POST in the ajax request.
There is not enough code presented but if you realy need to get the id from the session you can use an iframe (which is not recommended), process fetch data server side and output it in the iframe.

php cookies and session variables and ip address

I posted a similar question before, but never really got an answer that helped me, so I'm looking to try again. As a disclaimer, I know that a lot of the information in here doesn't follow perfect coding practices, but it is for exercise purposes only. I've tried a million things and nothing seems to be working because I'm not really sure where everything should go! I desperately need some (any!) help so thanks in advance if you can offer anything!
I'm trying to create a simple form / page that uses some basic cookie and session stuff to produce some user-specific data. I was moving along good until I came across a few problems that I can’t figure out. On my first page everything is good except for I just want the NAME of the browser the user is using. (for example, I want just the simple title: Firefox instead of the whole long version of the browser.) I've seen this be done so I think it’s possible, I just don’t know how to do it!
My real problems come up right about here, because I'm not exactly sure how to store the IP address, browser info and the current date/time (which I want shown on page 2) as session variables. Tried a few things I found, but I don’t think I was doing it right.
I also worked endlessly on trying to store the username and passwords as two separate cookies each...suggestions? Finally, what do I need to do to have a location header (used to call form_data.php) with output buffering?
(Not sure this will be that helpful, considering I probably did everything wrong! LOL) This is a totally stripped-down version of my code. Tried to post my cleanest version, even though it doesn't have much info, so that you could easily see what I was trying to do.
main file code:
<?php
header('Location: form_data.php');
setcookie('username', $_POST['username']);
setcookie('password', $_POST['password']);
//I know this isn't working.
//honestly I just left this in here as to show where I had been
//trying to save the cookie data. Pretty obvious how bad my
//trial and error with this went!
}
?>
<?php
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
echo " By the way, your IP address is: </b>".$_SESSION['ip']."<br />";
echo " You already know this, but the browser you are currently using
to view this page is:<br/>"; //What is the correct function that I should be using here?
echo "<form action=\"form_data.php\" method=\"post\">";
echo "username:<input type=\"text\" name=\"username\" size=\"20\" value=\"\"><br/>";
echo "password:<input type=\"password\" name=\"password\" size=\"20\" value=\"\"><br/>";
echo "<input type=\"submit\" value=\"Submit, please\" />";
echo "<br /><input type=\"hidden\" name=\"submitted\" value=\"true\" />";
?>
form_data.php
<?php
echo "Hello, ".$username;//I'm trying to get the cookie data for the username
echo "Your password is ".$password; //Samething here (want cookie data)
echo "The date and time you entered this form is: ".date("F j, Y")." -- ".date("g:i a");
echo "<br/>Your IP:".$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
echo "<br/>Your broswer:".;//I want full broswer data here...dont know how to do it.
//Overall, was this the way to get the session variables for IP, date/time and browser?
echo "Thank you for filling out this form!";
?>
To get the browser, use the get_browser() function:
$browserinfo = get_browser($_SERVER['HTTP_USER_AGENT']);
$browsername = $browserinfo['browser'];
Your session and cookie storage will never work because you are making a header("Location"); call before attempting to set cookies. You cannot send any output before setting cookies or establishing a session.
Before any output to the screen, call session_start();
// attach to your session (or create if it doesn't exist)
// You must call session_start() on every page where you intend to access or set session vars
// and it must be called before any output (including whitespace at the top)
session_start();
// Store some stuff...
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
// Store user info in session, not cookie
$_SESSION['username'] = $_POST['username'];
// Set a cookie
// Not a super secure token, but better than user/pass in cookies.
// Point here is just to show that it must be done before any output or before the redirection header.
$_SESSION['token'] = sha1(time() . rand() . $_SERVER['SERVER_NAME']);
setcookie('token', $_SESSION['token']);
// In practice, you'd want to store this token in a database with the username so it's persistent.
// Now do the redirection:
// Supposed to be an absolute URL by the HTTP spec
header("Location: http://example.com/form_data.php");
// exit right after the redirection to prevent further processing.
exit();
ADDENDUM after comments
While you work, make sure PHP displays all errors on screen. Be sure to turn off display_errors when your code goes onto a live public server.
error_reporting(E_ALL);
ini_set('display_errors', 1);
To retrieve values from cookies as you said in your question you didn't know how to do, use the $_COOKIE superglobal:
// On the page that sets it...
setcookie('somename', 'somevalue', expiry, domain);
// On the page that retrieves it...
echo $_COOKIE['somename'];
> I'm trying to create a simple form /
> page that uses some basic cookie and
> session stuff to produce some
> user-specific data.
Sessions do use cookies under the cover(only store session_id inside cookie/set_cookie) and I advice you to use only sessions because cookies can leak information(store all the information inside cookie on that user's computer) which could be dangerous while session uses the server's filesystem/database or whatever you like when you override session_set_save_handler.
> On my first page everything is good
> except for I just want the NAME of the
> browser the user is using.
Like Michael said you can use get_browser for that:
Attempts to determine the capabilities
of the user's browser, by looking up
the browser's information in the
browscap.ini file.
Like the PHP page says it tries to determine and you should NOT rely on this information for anything important because it can be wrong(you can fool the system, if you like). What I mean is you should not use it to validate/proof something.
> My real problems come up right about
> here, because I’m not exactly sure how
> to store the IP address, browser info
> and the current date/time (which I
> want shown on page 2) as session
> variables.
More information to retrieve the IP address can be read here(proxy-server could mislead you a little bit maybe?). To store that information just store it inside a session by first issuing session_start() on top of every page(before outputting anything) that wants to use sessions(only those to not set cookies on every page which makes page a little slower) and next store the current time inside a session variable by doing something along the lines of $_SESSION['time'] = date(DATE_RFC822);. You can read more about retrieving the time at date() page.
So the code on page 1 looks something like:
<?php
session_start();
$_SESSION['ip'] = getRealIpAddr(); # no php function => See http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html
$_SESSION['time'] = date(DATE_RFC822);
Then on page 2 you could retrieve this information using something like:
<?php
session_start();
echo $_SESSION['ip']; // retrieve IP
> I also worked endlessly on trying to
> store the username and passwords as
> two separate cookies
> each...suggestions?
Don't store them inside a cookie(only using set_cookie and not using sessions to store information) but store them inside a session for extra security. But sessions are also vulnerable to session fixation so after storing something critical inside your session you should regenerate session id and never output/show that information to the browser/user to prevent any leakage.
> Finally, what do I need to do to have
> a location header (used to call
> form_data.php) with output buffering?
Like Michael said you should be using header function and exit to terminate script after that
<?php
header("Location: http://www.example.com/"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
?>
P.S: Never store any really sensitive information like creditcard(use paypal or something) numbers or anything in your own database. I also advice you not to store passwords inside your database but use something like openId(Google's) for example to handle your authentication for extra security.

What happens to the $_SESSION array if a PHP session times out in the middle of a request?

I have always wondered, if a PHP session times out during the middle of executing a script, will the contents of the $_SESSION array still be available until script execution ends? For example:
session_start();
if(! isset($_SESSION['name'])) {
echo 'Name is not set';
exit;
}
// imagine there is a bunch of code here and that the session times out while
// this code is being executed
echo 'Name is ', $_SESSION['name']; // will this line throw an error?
Is it practical to copy session variables to the local scope so I can read them later on in the script without having to keep checking for a session time out? Something like:
session_start();
if(isset($_SESSION['name'])) {
$name = $_SESSION['name'];
} else {
echo 'Name is not set';
exit;
}
// bunch of code here
echo 'Name is ', $name;
don't worry about such things. Nothing will happen to the session. It's initialised by sessioni_start() and $_SESSION will be always available within your script.
The default three-hour session lifetime is reset each time you open the session (see session_cache_expire), so the only way a session could time out in the middle of a request is if a request takes three hours to process. By default PHP requests time out after just 30 seconds, so there's no danger of session expiry during a request. Furthermore, the $_SESSION variable won't suddenly change in the middle of a request. It's populated when the session starts, and that's it.
The variables are copied into the $_SESSION global at the initial request, so it has the same effect as copying it to a local variable.
However, for clarity sake, it makes sense to copy it to a local variable. Especially if you plan to use the variable several times. It can be difficult to read code that has $_SESSION['variable'] all over the place.
What you needed to understand is how sessions work. A client accessing a script using a $_SESSION super global only knows the key to the session that belongs to them (Stored in Cookie/URL). This means the session data itself has nothing to do with the client. If you have the key to the session data you want to use then you can use it. Older versions of PHP had some security holes because sessions where stored somewhere that was easily accessible (I don't remember details).
Basically, if you have the session id in a PHP script you have access to that session unless the memory on the machine is flushed/harddrive is corrupt (ie Computer Restart/Device Failure).
Hope this helps, otherwise go to php.net and dive into the details on how sessions work.

PHP Class Scope

I am fairly new to PHP. What is the best way to control access to a class throughout a PHP application and where is the best place to store these classes that will need to be accessed throughout the entire application? Example; I have a user class that is created on during the login process, but each time the page post it appears that the object is reinitialized.
I have tried to set property IsLoggedIn and then check that variable each time before creating the object as new again, but this doesn't seem work. I have also tried to use the isSet function in PHP to see if the class variable already exists
You're right, the state of your application is not carried over from request to request.
Contrarily to desktop applications, web applications won't stay initialized because to the server, every time it can be a another visitor, wanting something completely different. You know who's using the desktop application, but you don't necessarily know who's requesting the page. Imagine 10 users doing different thing simultaneously on your web application? You wouldn't keep the whole application running necessarily for each of those visitors. Imagine with 10,000 visitors...
There are ways to keep some data from request to request though. The application will be reinitialized each time, yes, but you can then reload the state of what you were doing. It always revolve around around the same general methods:
Cookies; Cookies are a small file that is kept on the client side and which content will be available on each request to you. In PHP, this is available using $_COOKIE variable. In all cases, you could serialize your classes instances and reload them afterwards. The problem is, you wouldn't want to put sensitive data there as any(malicious)body can see and modify it.
POST or GET; In each request, you pass a state in the $_GET request (the URL such as http://localhost/myscript.php?iamatstep=4. Or via a $_POST such as using a hidden input field in a form. This data could be encrypted and make sense only to you, but still, you are putting sensitive data back to the client and anybody could fiddle with it.
Database, Disk; Or anything else on the server. Again, you serialize your data in a file for example at the end of a request ready to be used again for the next request. The main advantage is that it stays on your server. The downside is that at this point, you don't know which data to extract back for which request as there might be multiple users on your application at the same time...
And this is where the notion of $_SESSION comes into play. It's just a packaged way of using all of this at the same time. It's not magical as often it's perceived by beginners. When you use a session, the data put into the $_SESSION is stored somewhere on the server (normally a file in a temporary directory although it can be changed to something else like a database) and a unique ID is attributed to this session and passed in a cookie that will follow the visitor from request to request. So the only thing on the client's side is a big number in the cookie. On the next request, the browser tells PHP on the server that it's session number 12345, loads the corresponding file if it exists and then the data is available to you again. If cookies are not enabled, it could be passed in a GET or POST, although it's often better not to go there (see session.use_trans_sid's note).
It often looks like that on each of your pages you need authentication.
<?php
// verify if we have a current session
if (isset($_SESSION['login'])) {
// get data in current session
$username = $_SESSION['login']['username'];
$isLoggedIn = $_SESSION['login']['isLoggedIn'];
} else {
$username = '';
$isLoggedIn = false;
}
// take care of the unauthorized users
if (!$isLoggedIn) {
// maybe a redirection here...
}
// do the things a logged in users has the permission to do
And to set the session, it'll probably look like that:
<?php
// handle the form post of your login page for example
if (isset($_POST['username']) && isset($_POST['password'])) {
$username = $_POST['username'];
$password = $_POST['password'];
// verify the username and password against a database
if ($everythingIsOkay) {
// we can consider this user logged in and create a session
$_SESSION['login']['username'] = $username;
$_SESSION['login']['isLoggedIn'] = true;
// and now maybe redirect the user to the correct page
}
}
// raise an error about an invalid login
And finally, maybe a logout.php page that would do something like that:
<?php
unset($_SESSION['login']);
// redirect the user to the login page
This kind of data is going to have to be stored in a session, the only thing that is carried from page to page is Session data (sessions/cookies/...) so your class initialization is not carried over.
You can add information like the users username to the session with:
$username //username from db
$name //name from db
$_SESSION['username'] = $username;
$_SESSION['name'] = $name;
or if you just want to have easy access to all the information about the user you can do:
$_SESSION['user'] = mysql_fetch_assoc($result); //where $result is the response from the db to your login query
after you do this $_SESSION['user'] will be an array with all the details you selected from the database.

Categories