For months I've been using the following code without a problem to track unique sessions on my site, but it has recently just stopped working for an unknown reason. If I test the code in a separate file, it works as I originally intended.
The code checks to see if a session exists, and if not it creates it and sets it to TRUE. It then performs a second check to see whether or not the session is TRUE, whereupon it is changed to FALSE and the hit stored in the database. This happens ONCE per session.
The code to achieve this is:
<?php
session_start();
// If the session DOES NOT EXIST, make it and set it to TRUE.
if(!isset($_SESSION['new_visit']))
{
$_SESSION['new_visit'] = true;
}
// If the session is TRUE, make it false.
if($_SESSION['new_visit'] == true)
{
$_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
$_SESSION['new_visit'] = false;
}
echo $_SESSION['unique_session_id'];
When I run this code, as expected, no matter how many times I refresh the page, the output never changes. The 'unique_session_id' variable is always unchanged because each of the if statements are only executed once. However, my production code contains this exact code, but has suddenly stopped working. My production code is this:
<?php
if(empty($article_data))
{
$no_article = true;
}
$options = $this->db->get_options();
$server_options = $this->db->server_options();
// Check site status (on/off).
if($options['status'] == "off")
{
echo $options['offline_message'];
exit(); // Equal to die.
}
if($server_options['force_ssl'] == "on")
{
if($_SERVER["HTTPS"] != "on")
{
header("HTTP/1.1 301 Moved Permanently");
exit(header("Location: https://" . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]));
}
}
$this->db->store_hit();
$this->db->store_ip();
//----------------------------------------------------------------------------------------------------------
// Store visits (individual sessions). Visits are not unique hits. Visits are the number of unique sessions,
// so a single person may accumulate many visits (sessions), i.e., returning users.
//----------------------------------------------------------------------------------------------------------
// If the session DOES NOT EXIST, make it and set it to TRUE.
if(!isset($_SESSION['new_visit']))
{
$_SESSION['new_visit'] = true;
}
// If the session is TRUE, make it false.
if($_SESSION['new_visit'] == true)
{
$this->db->store_visit();
$_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
$_SESSION['new_visit'] = false;
}
?><!DOCTYPE html>
<html>
...
</html>
As you can see this code is identical, yet every time I refresh the page the unique_session_id variable changes, which is impossible if the logic is unaffected. My only conclusion is that the session is being deleted or lost between page refreshes.
Notes:
I'm using the MVC pattern which I've written from scratch.
session_start() is being called before any other line of PHP in
index.php.
I've tried moving session_start() to various locations in the file,
including right before the sessions are created. This does nothing.
I've tried using session_write_close(), it does not work.
The 2 logical statements should only ever be executed once per session no matter how many page refreshes take place, and have been working this way for 2-3 months. Why have they suddenly started executing after every single page refresh? What is happening to my session vars that the logic is being evaluated to TRUE every time the page refreshes?
EDIT
The session issue has now been fixed by requesting a new php.ini file from the web host.
Your code works as you wrote
please look at code comments.
if(!isset($_SESSION['new_visit'])) //1st time is not set so enter's to statement
{
$_SESSION['new_visit'] = true; //making $_SESSION['new_visit'] true
}
if($_SESSION['new_visit'] == true) //1st time its true
{
$this->db->store_visit();
$_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
$_SESSION['new_visit'] = false; //You make it false
}
but when $_SESSION['new_visit'] is false, that mean $_SESSION['new_visit'] is set. now second or more times :
if(!isset($_SESSION['new_visit'])) //variable is set, and it will not enter here
{
$_SESSION['new_visit'] = true; // variable stays false
}
if($_SESSION['new_visit'] == true) //variable is false !!!
{
$this->db->store_visit();
$_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
$_SESSION['new_visit'] = false;
}
// Finally $_SESSION['unique_session_id'] stays same.
You can use unset($_SESSION['new_visit']); or if it only for this statement or to checking in one page, use variable like $new_visit don't use session for that.
Updated:
Save this specific session handling code in a separate file which you require in the beginning in all of your files.
I noticed that you HAVE TO reload at least once to get a session id, instead you could do this, also simplifying the complexity:
if(!isset($_SESSION['new_visit']))
{
$_SESSION['new_visit'] = true;
$_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
}
echo $_SESSION['unique_session_id'];
I'm also taking a wild guess that you're not using session_start() properly and in the beginning of ALL files which you ever go into. Once you enter a single page that doesn't have it or is using it incorrectly then things screw up.
Note: You can use
session_destroy();
to delete every set session there is. You can also use
unset($_SESSION['new_visit']);
to unset a certain session.
Related
Hi,
I need to create a session as soon as the visitor enters my page. Then by clicking on a link that takes to an URL like this example.org/page?no_redirect=true the session must be destroyed but the session should be created again if they click on a link to this URL example.org/page?no_redirect=false.
I did it like this:
session_start();
$_SESSION['redirect'] = "false";
if($_GET['no_redirect'] == "true")
{
$_SESSION['redirect']="true";
} elseif ($_GET['no_redirect'] == "false") {
$_SESSION['redirect']="false";
}
if ($_SESSION['redirect']!=true) {
$redirect = <<<EOF
<script type='text/javascript'>DM_redirect("mobile/$page");</script>
EOF;
}
but its not working. What could it be?
Thank you.
The check if ($_SESSION['redirect'] != true) makes no sense, because you are comparing a non-empty string to a boolean. Non-empty strings always evaluate to true, so your check is really if (true != true), which means the content inside the block will never be executed.
A more sensible approach would be to unset your session once its purpose has been served instead of setting it to "true" / "false".
Code:
session_start();
# Check whether the session should be unset.
if ($_GET['no_redirect'] == "true") {
unset($_SESSION['redirect']);
}
# Check whether the session should be set.
else if ($_GET['no_redirect'] == "false") {
$_SESSION['redirect'] = "true";
}
# Check whether the session is set.
if (isset($_SESSION['redirect'])) {
$redirect = <<<EOF
<script type='text/javascript'>DM_redirect("mobile/$page");</script>
EOF;
}
I have a problem with cookies. In my login script i have the following line of code:
if($_GET['keep'] == "true"){
setcookie('id',$id,time()+3153600);
}
The problem I'm facing is that the cookies are not saving at all ( not even if i don't quit the browser). I'm quite a beginer in this respect and I think I'm not doing it right.
EDIT:
If i print_r all the Cookies it only gives me PHPSESSID after the cookie is set. I printed on index.php and i set the cookie on login.php
SOLUTION: Cookies are saved by default with the path of the file they were created in. To change the path there is another atribute. So by setcookie('id',$id,time()+3153600,'/'); you make the cookie available for the entire domain.
There is no issue in your code
if($_GET['keep'] = "true"){
setcookie('id',$id,time()+3153600);
}
This will may cause to
No data passing to $_GET['keep']
Or if data passing $_GET['keep'] value in not Matched ("true").
Both Works then $id is empty in setcookie method
Improve your code
if(isset($_GET['keep']){
if($_GET['keep'] == "true"){
if(isset($id))
{
#all perpect
$cokkie_id = 'id';
setcookie('id',$id,time()+3153600);
echo "I'm Set. And My value is ".$cokkie_id;
}
else
{
echo "Opzz My ID is also empty";
}
}
else
{
echo 'Get method is Set. But Value is not "true". Actual value is '. $_GET['keep'];
}
}
else
{
echo 'I cant reach Get method Buddy';
}
I think you miss "=" sign
if ($_GET['keep'] == "true") {
if (!isset($_COOKIE['id'])) {
setcookie('id',$id,time()+3153600);
}
}
use isset or ==
if (isset($_GET['keep']) && $_GET['keep'] == "true") {
setcookie('id', $id,time()+3153600);
}else{
echo 'keep is empty';
}
I'm currenting busy coding a registration page. The page has three steps and every step has its own cookie value. What I'd like to do is checking for the cookies value and transfer the user to the correct page upon visiting the website
Example:
if the value of $_COOKIE['step'] is 'step_two' it should redirect to: www.domain.com/register.php?step=your_details. If the cookie's not set, it should not redirect and stay on the register.php page.
The redirecting is working 'fine', but it gets into an infinite loop. I really cant think clear anymore as I've been awake for almost 24h now. Therefor I would appreciate it if anyone could push me into the right directions.
Piece of code:
$cookie_value = 'step_2';
setcookie("step",$cookie_value, time()+3600*24);
$cookie_not_set = true;
$cookie_step_two = false;
if (isset($_COOKIE['step'])) {
if ($_COOKIE['step'] == 'step_2') {
$cookie_not_set = false;
$cookie_step_two = true;
header('Location: ?step=your_details');
exit();
}
} else {
$cookie_not_set = true;
}
Thank you.
Nowhere are you actually setting your cookie value, so it won't change. That's why you have an infinite loop.
$_GET and $_COOKIE have nothing to do with each other. It looks like you want:
if ($_GET['step'] === 'your_details')`
...which would be better than using a cookie anyway.
You are going to constantly enter your if condition as there is no other manipulations going on to your cookie data.
if your cookie is set to "step_2" you will enter the loop. No changes are in place, so on the refresh to the page. You will re-enter the step_2 condition and be into a redirect.
I'm also assuming that you understand that your $_GET & $_COOKIE requests are completely different. If not, see #Brads answer
A solution to stop this infinite loop would be:
if (isset($_COOKIE['step'])) {
if ($_COOKIE['step'] == 'step_2') {
$cookie_not_set = false;
$cookie_step_two = true;
$_COOKIE['step'] = 'step_3';
header('Location: ?step=your_details');
exit();
}
But also take note, your true/false validations/changes are local changes and will not be absolute on page refresh
I believe your issue is the redirect is not changing your cookie, so you need to look at the GET var you a re passing if the cookie is set to step_2 thus;
$cookie_not_set = true;
$cookie_step_two = false;
if (isset($_COOKIE['step'])) {
if ($_COOKIE['step'] == 'step_2') {
if( !empty($_GET['step']) && $_GET['step'] == 'your_details' )
{
... you have redirected and now can continue ...
}
else
{
// redirect and set the get var to signal to this script.
$cookie_not_set = false;
$cookie_step_two = true;
header('Location: ?step=your_details');
exit();
}
}
} else {
$cookie_not_set = true;
}
I am setting a cookie on one page with below code
setcookie(codeDone,true);
This works but then I reset it to false on another page
setcookie(codeDone,false);
But then, when I go back to the first page, before the part that sets it to true I have
if($_COOKIE['codeDone'] == true){
$cookie = $_COOKIE['codeDone'];
$done = false;
echo"cookie set to $cookie";
}
setcookie(codeDone,true);
For some reason the ocokie is set to true because the contents of this if are always executed
Why is the cookie returning true (1) if in the previous page i set it to false?
Cookies are only string-values.
The code below is an example for your case to handle string as boolean:
ob_start();
if (isset($_COOKIE['codeDone'])) {
//this is your magic
$result = filter_var($_COOKIE['codeDone'], FILTER_VALIDATE_BOOLEAN);
if ($result === true) {
$cookie = $_COOKIE['codeDone'];
$done = false;
echo "Current Cookie Status: ".$_COOKIE['codeDone'];
}
}
setcookie('codeDone', 'true');
ob_end_flush();
BTW: You cannot modify the header (setcookie) after executed echo. this is the reason why i use the output buffer (ob_start/ob_end_flush)
I have this code that makes sure your are logged in, and then making sure you are on the right page by checking a cookie set at login. This code works on a page in a directory underneath the login in script, however in a page in a directory below that it always takes you to accessdenied. Any ideas?
<?php
session_start();
if(!isset($_SESSION['SESS_MEMBER_ID']) || (trim($_SESSION['SESS_MEMBER_ID']) == '')) {
header("location: http://mywebsite.com/member/accessdenied.html");
exit();
}
$_COOKIE["verify"] = $verify;
if( $verify != file_get_contents("name.txt")) {
header("location: http://mywebsite.com/member/accessdenied.html");
} else { }
?>
And it seems like just the bottom part, the part that checks the cookie, isn't working. Again, any ideas?
I think you have your cookie assignment backwards:
$_COOKIE["verify"] = $verify;
Should be
$verify = $_COOKIE["verify"];
And that should be:
$verify = isset($_COOKIE["verify"])?$_COOKIE["verify"]:false;
As if the cookie was not previously set, well it would give a notice error.
<?php
$verify = $_COOKIE["verify"];
if( $verify == file_get_contents("name.txt")) {
echo $verify . 'is equal to the content of name.txt'
} else {
echo $verify . 'is NOT equal to the content of name.txt'
}
?>
Try debugging the code with this. See if the content of your variable is what you want. But I find it unusual that a variable would be a file.
are you sure you always get the content from file_get_contents? I could imagine it's found in one directory but not in the other!
antoher idea: cookies can be set to be relevant for a particular directory only. I just realize, what we're missing here, is the part where you set the cookie in the first place.