I'm trying to do load testing using JMeter 2.5.1. The application is written in PHP, and uses the standard cookie-based session management with a named session. Currently, the test plan is a very simple 2 HTTP request and 1 Cookie Manager within 1 Thread Group. The Cookie Manager's cookie policy is set to compatibility as suggested by the tutorials. However, the session still gets lost on each request.
On the first page call, the session is initialized. I printed the following info before and after the session_start call:
before session start:
session_name() = 'PHPSESSID'
session_id() = ''
$_COOKIE = array (
)
after session start:
session_name() = 'sasExtSMSESSID'
session_id() = 'ihl8svsbl76au7h1ccn3c0ci61'
$_COOKIE = array (
)
On the second page call, the session is supposed to have already been set. But it seems that the cookie that JMeter's cookie manager is corrupted:
before session start:
session_name() = 'PHPSESSID'
session_id() = ''
$_COOKIE = array (
'sasExtSMSESSID' => 'ihl8svsbl76au7h1ccn3c0ci61, sasExtSMSESSID=ihl8svsbl76au7h1ccn3c0ci61',
)
after session start:
session_name() = 'sasExtSMSESSID'
session_id() = '2ro2bkd3t3liq76h7lqn603gm7'
$_COOKIE = array (
'sasExtSMSESSID' => 'ihl8svsbl76au7h1ccn3c0ci61, sasExtSMSESSID=ihl8svsbl76au7h1ccn3c0ci61',
)
So it seems that the cookie array is corrupted somehow, and as the session id is invalid a new one is generated. Beyond calling session_name() and session_start(), there is nothing special in the application that deals with cookies. Accessing the pages using browsers also works. So I guess I didn't configure the JMeter correctly. Any idea what could have caused this? Any help is greatly appreciated.
I'm not sure if this is really an answer, since I still have no idea what is happening, but I guess this is a solution that others may benefit from.
Changing the Cookie Manager's policy from compatibility to default lets me to sidestep this issue, since the corruption apparently happens to another part of the cookie variable:
session_name() = 'sasExtSMSESSID'
session_id() = 'gknq98q7fpecjciti3da9l6mj7'
$_COOKIE = array (
'$Version' => '0',
'sasExtSMSESSID' => 'gknq98q7fpecjciti3da9l6mj7',
'$Path' => '/, sasExtSMSESSID=gknq98q7fpecjciti3da9l6mj7',
)
So far having that $Path corrupted has produced no adverse effect.
Would still appreciate anyone explaining to me exactly what is happening here.
Related
I am trying to store array to cookie. I am storing my array products item in cookie array, but it throws error.
$products = array();
$item = array($id => $name);
print_r($item);
$products[] = $item;
setcookie('products',json_encode($products),strtotime( '+1 day' ));
var_dump($_COOKIE['products']);
The above code prints
Array (
[4] => Rug Rat ) Notice: Undefined index: products in
D:\xampp\htdocs\projects\includes\classes\products.php
on line 43 NULL
Cookies are set when the response is sent to the client. This means that you won't be able to access them from PHP code until the next request. See the documentation for setcookie() function, section Common Pitfalls:
Cookies will not become visible until the next loading of a page that the cookie should be visible for. To test if a cookie was successfully set, check for the cookie on a next loading page before the cookie expires. Expire time is set via the expire parameter. A nice way to debug the existence of cookies is by simply calling print_r($_COOKIE);.
http://php.net/manual/en/function.setcookie.php
So, unless you echo anything, or do anything else that causes the response headers to be sent, you should see var_dumped cookie content after you refresh the page. In your code, there's print_r($item); before setcookie() is called, so you're probably getting a headers already sent warning, and the cookie is never set.
One way or another, it's rarely safe to assume that an array index is set, especially in a superglobal, like $_GET, $_POST, $_COOKIE, etc. You should always check with isset() or array_key_exists if the index is really set.
I have the following basic logout script which I believe to be functioning strangely:
<?php
session_start();
$_SESSION['customerState'] = array("abbr"=>"TX","full"=>"Texas");
$_SESSION['agent']['url'] = "jmarston4";
$fart = isset($_SESSION['customerState']) ? $_SESSION['customerState'] : array();
$url = isset($_SESSION['agent']['url']) ? $_SESSION['agent']['url'] : '';
$_SESSION = array();
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
echo "Fart1: ";
print_r($fart);
session_destroy();
echo "<br>Fart2: ";
print_r($fart);
session_start();
echo "<br>Fart3: ";
print_r($fart);
$_SESSION['fart'] = $fart;
echo "<br>Fart4: ";
print_r($_SESSION['fart']);
#exit;
header('Location: https://'. $_SERVER['HTTP_HOST'] . '/' .$url);
This page redirects to the site homepage (index.php) with a referrer URL (mentioned as $url). This works just as it should. For testing sake, here is a screen shot of ALL of the code on index.php:
http://imgur.com/EmkRAh0
If I allow the exit; to process, the following is outputted to screen:
Fart1: Array ( [abbr] => TX [full] => Texas )
Fart2: Array ( [abbr] => TX [full] => Texas )
Fart3: Array ( [abbr] => TX [full] => Texas )
Fart4: Array ( [abbr] => TX [full] => Texas )
(or visually: http://imgur.com/A6WuRfx)
In this script (logout.php), I want to keep a single SESSION variable from the customers session (and not manually unset 100+ others) so I can pass it back to the homepage for internal purposes. To do this, the script does the following:
Set the SESSION variable 'fart' equal an array
A local variable is then set equal to the SESSION 'fart' before the entire SESSION is destroyed
The session data is cleared
The session cookie is deleted
the session is destroyed
The SESSION 'fart' is created and set back to the $fart array
the page redirects to the homepage.
QUESTION
By design, are PHP SESSIONS expected to behave this way? If so, how can one essentially destory a session (say for logout purposes) while maintaining pieces of session information collected during that user session.
Note: I am using SESSION arrays so passing in the URL for GET purposes is not applicable here.
Update Notes:
I changed the title of this question from "Are PHP sessions behaving according to spec?"
All of this works on the script itself, however, when I try and access $_SESSION['fart'] on the homepage, it is not set. I am able to set, manipulate or alter SESSION variables on the page at any point, INCLUDING after session_destroy() is called. For example, if I want to do the following:
...
session_destroy()
$_SESSION['eatmyshorts'] = "hello!";
echo $_SESSION['eatmyshorts']; // will display hello!
....
however, once the script (page) ends, anything relating to sessions (even $_SESSION['eatmyshorts'] in this case, is not available on any other page and disregarded.
If you call session_destroy, the stored session data is destroyed, $_SESSION is emptied, and the ‘session state’ is reset as before session_start was called. In that state, the data in $_SESSION exists just during runtime. Now if you call session_start after session_destroy, the session handling behaves exactly as if it where the first active session within the runtime: If the client request contains a syntactically valid session ID, it will use it for this session.
This all does work as expected.
However, what you haven’t taken into account is how sessions behave when you delete the session’s cookie containing the ID. Because when you sent the cookie to revoke the session ID for the client, the client won’t send a session ID along the next request and session_id will generate a new one. Since it’s a new session, $_SESSION is empty.
If you want to revoke the current session ID and generate a new session ID, use session_regenerate_id(true) and session_unset.
Once you call session_destroy the session is, well, destroyed and the server-side storage of the session data deleted. Manipulating the $_SESSION viariable after that has no effect as it's not "bound" to an actual session anymore (ie. the data you set don't get written to the session data storage when the script ends).
ALL of this works on the script itself
Then there is nothing wrong with the code you have provided (apart from the missing session_start(), but you said you put this in - you should edit your code above as people are replying based on it being an obvious error)
I tried your code above and confirm it works as stand alone.
To get help, you should explain or (ideally) show the rest of your code so it can be evaluated and the root cause of the issue discovered.
Try changing your bottom bit of code to this and tell us the outcome
echo "Fart1: ".$fart;
session_destroy();
echo "<br>Fart2: ".$fart;
session_start();
echo "<br>Fart3: ".$fart;
$_SESSION['fart'] = $fart;
//header('Location: /'); exit; <-- commented out
echo "<br>session: ".$_SESSION['fart'];
Although you had it working yourself, and are SURE that session_start() is present on the file which it redirects to and is at the top of the file BEFORE any HTML output, also try redirecting to the actual page name just to rule something else out, ie
header('Location: index.php'); exit; //or whatever filename is your homepage
Also to answer your other question about how to do this properly, how you do it is fine, as you set a var to the value, start the session again and set the $_SESSION to the var value.
You can access $_SESSION data directly, eg
$_SESSION['userlogin']['username'] = 'james';
//log me out from the session =
$_SESSION['userlogin']['username'] = '';
When a user returns to my website, it attempts to restore their last session from the $_COOKIE associative array. It's not working as expected. I can look in my browser's cookie manager and see that the cookies are there, but they don't seem to be getting saved to the $_SESSION associative array.
This is essentially the program flow when a user returns to my site:
foreach ( $_COOKIE as $name => $val )
{
$_SESSION[$name] = $val;
}
session_start();
...
$some_var = $_SESSION[$var_name];
Do I have things out of order, or should I not be overwriting PHPSESSID? Any insight as to what I'm doing wrong would be appreciated. Thanks.
You're getting sessions and cookies mixed up. You don't need to put things into the $_COOKIE array. Just use session_start() and then put things into $_SESSION. PHP will automatically then manage the session/cookie for you.
$_COOKIE variables are stored on the users browser, so they aren't secure and can be manipulated by the user => security risk.
$_SESSION variables are stored only on the server. The only thing stored in the cookie is a session_id, so $_SESSION variable can't be manipulated.
Does that make sense?
Put session_start() before anything else; this function initializes the session data that you will be accessing in $_SESSION.
Not exactly sure what you're trying to achieve with the rest of it all, but session_start() first is a starting point...
I'm having trouble setting cookies on the same page. I used cookies on my site and it works fine, I tend to set make the php in separate file. Now, I'm setting a cookie on the same page but it doesn't seem to work.
$expire = time()+5;
setcookie("rb_vote", 1, $expire);
then check if it is set
if(isset($_COOKIE["rb_vote"])) {
echo "IS SET";}
else {
echo "IS NOT SET"; }
It always says is not set. I tried doing this in page load but still doesn't work.
See the manual on setcookie() (emphasis mine):
Once the cookies have been set, they can be accessed on the next page load with the $_COOKIE or $HTTP_COOKIE_VARS arrays. Note, superglobals such as $_COOKIE became available in PHP 4.1.0. Cookie values also exist in $_REQUEST
Here is a workaround suggestion. It's imperfect because it can't guarantee the cookie actually gets set, but might do in your case.
I've just encountered this issue in Vanilla Forum. On the first page load, before a session has been established, a session cookie is created, but then every time the application wants to access the session variables (to add to them) it looks for the current session ID in $_COOKIE, which is not set until the next page load.
My workaround is to set the $_COOKIE element manually when the cookie is created.
// Create a cookie to identify the session.
// This line already exists. $Name is the cookie name.
// $SessionID is a random md5 ID that has just been generated.
setcookie($Name, $SessionID, $Expire, $Path, $Domain);
// Set the cookie for the remainder of the page. This is a workaround.
if (!isset($_COOKIE[$Name])) $_COOKIE[$Name] = $SessionID;
I've raised this as a fault with Vanilla (https://github.com/vanillaforums/Garden/issues/1568), as this workaround feels like a bit of a hack, but it certainly gets around the problem for now.
PHP5.3 Vanilla Forum Version 2.0.18.4
I am trying to implement a login system with a 'remember me' feature . This is my my login page: http://pastebin.com/q6iK0Mgy . In this I am trying to extend the session cookie(PHPSESSIONID) expiration using session_set_cookie_params() . But its not working.
Relevant portion from the code: In this the inner if() loop is being executed , but session_set_cookie_params('3600') is having no effect. I am calling session_name() , as it is supposed to be a requirement for session_set_cookie_params() (according to one of the comments on php manual)
if ( isset($_POST["submit"]) )
{
session_name() ;
echo "calling before checked " ;
if ( $_POST["remember"] == "on")
{
// extend expiration date of cookie
session_set_cookie_params('3600');
echo "<br/>calling after sessions_set_cookie_params" ;
}
}
require_once("includes/session.php"); //session start ?>
I hope I was able to explain what I want to do. Basically what I a trying to do is extend the session_cookie's expiration. is my way of doing completely wrong? is there another way to achieve the same ?
thanks
Never too old for an answer right?
So, PHP is dumb. As in, it doesn't do what you think would make sense.
session_set_cookie_param will not do anything until the exact moment that you call session_start. So if you set cookie params after calling session start, too late. If you set the cookie params but then don't call session_start, nothing happens.
session_start is also a funny beast. It only reads cookie data the first time it is called -well that is unless.... you force it to write, or there is no cookie to begin with. So if there is no cookie, it writes the cookie data and the client saves your session. yay! But when the cookie exists already, how to we force it to write, and therefore update our new expiry date??
So, we have this odd effect of ignoring all of your session_set_cookie_param calls if a cookie already exists on the client. Even better, if you explicitly call setcookie(session_name(),blah blah blah), php will STILL not emit the cookie.
So, let's force php to emit a cookie.
option 1
This works by calling session_id with the only value that won't clobber your existing session. Documentation at http://php.net/session_id states that
Note: When using session cookies, specifying an id for session_id() will always send a new cookie when session_start() is called, regardless if the current session id is identical to the one being set.
session_id($_COOKIE[session_name()]);
So anyways it's 6 in the morning and I haven't slept yet and you probably figured this out months if not years ago, but what the hell, maybe i'll save someone else the 2 or 3 hours of my life i'll never get back. ha ha.
From the documentation:
You need to call
session_set_cookie_params() for every
request and before session_start() is
called.
Also check http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime