Link to home
Start Free TrialLog in
Avatar of snowplank
snowplank

asked on

Session problem when I hit browser back button

Hi,

I have a problem with using the browser's back button.  I select an article via a link and view that article. If I then hit the back button and select a different article, the same one is displayed.  I am sure it is an easy problem but it's now driving me nuts.  Can anyone tell me what I am doing wrong?

Here are the two pages of code:

articles.php:
<?php
 error_reporting(2047); // 1 = suppress warning messages, 2047 = E_ALL all error messages
 //$sid = session_id();
 session_start();
 include("banner.php");
 require("connect.php");
 //header("Cache-control: private"); // allow the back button to function
 if (!isset($_SESSION["id"])) {
      echo '<center><br /><br />';
      print "You have not logged in to the system. Please login. <br><br>";
      echo '<meta http-equiv="Refresh" content="2; url=login.php" />';
      session_destroy();
      exit();
 }
 //unregister $_SESSION["articleid"]
 session_unregister($_SESSION["articleid"]);
 // get category name for title of page
 // set variable for query from articleschoosecat.php
 $catid = $_POST["category"];
 $sql = "SELECT * FROM categories WHERE id = '".$catid."'";
 $result = mysql_query($sql) or die("Sql error : " . mysql_error());
 $num = mysql_num_rows($result);
 $result_arr = mysql_fetch_array($result);
 $category = $result_arr['name'];
 $description = $result_arr['description'];
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns =" http://www.w3.org/1999/xhtml">

<head>
<title><? echo $category; ?></title>
</head>
<body>
<center>
<h3><? echo $category; ?></h3>
</center>
<table>
      <tr>
            <th align="left">Description</th>
      </tr>
      <tr>
            <td align="left"><? echo $description; ?></td>
      </tr>
</table>
<br />
<br />
<?php
      //create the SQL statement to get articles
      $sql = "SELECT articles.id AS articleid, articles.publisher, articles.category, articles.author, articles.title, articles.article, categories.id AS categoryid, categories.name, users.id AS userid, users.username FROM articles, categories, users WHERE articles.category = categories.id AND articles.publisher = users.id AND categories.id = '".$catid."' AND articles.deleted = 'N'";
      $result = mysql_query($sql) or die("Sql error : " . mysql_error());
      $num = mysql_num_rows($result);
?>
<!-- build table per article -->
<?
      if($inf = mysql_fetch_array($result)){
         do{
                   //print_r($inf); // insert this line to view array of fileds being posted
                   $articleid=$inf["articleid"];
                   $_SESSION["articleid"] = $articleid;
             $author=$inf["author"];
             $title=$inf["title"];
             $publisher=$inf["username"];
             $article=$inf["article"];
?>  
            <table id="messageboard" border=1 cellpadding=4 width=100% style="border-collapse: collapse">
                  <tr class="toprow">
                        <th width="15%">Author: <? echo $author; ?></th>
                        <th width=75%>Title: <a href="individualarticle.php?article=<? echo $articleid; ?>" class="toprow"><? echo $title; ?></a></th>
                        <th class="userinfo">Publisher: <? echo $publisher; ?></th>
                  </tr>
<?
            }
            while($inf = mysql_fetch_array($result));
    }
?>
</table>
<hr>
<center>
<br>
<?
      if ($_SESSION["admin"] == "Y") {
            echo '<a href="addarticle.php">Add Article</a><br />';
            echo '<a href="adminmenu.php">Admin Menu</a><br />';
      }
      else{
            echo '<a href="usermenu.php">User Menu</a><br />';
      }
?>
<a href="logout.php">Logout</a>
</center>
</body>
</html>

individualarticle.php:
<?php
 error_reporting(2047); // 1 = suppress warning messages, 2047 = E_ALL all error messages
 //$sid = session_id();
 session_start();
 include("banner.php");
 require("connect.php");
 header("Cache-control: private"); // allow the back button to function
 if (!isset($_SESSION["id"])) {
      echo '<center><br /><br />';
      print "You have not logged in to the system. Please login. <br><br>";
      echo '<meta http-equiv="Refresh" content="2; url=login.php" />';
      session_destroy();
      exit();
 }
 //echo $_GET["articleid"];
 //create the SQL statement
 $sql = "SELECT articles.*, users.id, users.username FROM articles, users WHERE articles.publisher = users.id";
 $result = mysql_query($sql) or die("Sql error : " . mysql_error());
 $num = mysql_num_rows($result);

      $inf = mysql_fetch_array($result);
    $author=$inf["author"];
    $title=$inf["title"];
    $publisher=$inf["username"];
    $article=$inf["article"];
      $articleid=$_SESSION["articleid"];
      
      //pass article id to editarticle.php if edit button is pressed
      //$_SESSION["articleid"] = $articleid;
      
?>  

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns =" http://www.w3.org/1999/xhtml">

<head>
<title><? echo $title; ?></title>
</head>
<body>
<center>
<h3><? echo $title; ?></h3>
</center>
<br />
<?// echo $_SESSION["articleid"]; ?>
<table border=1 cellpadding=4 width=100% style="border-collapse: collapse">
      <tr>
            <th width="10%">Author: <? echo $author; ?></th>
            <th width=80%>Title: <? echo $title; ?></th>
            <th>Published By: <? echo $publisher; ?></th>
      </tr>
      <tr>
            <td colspan=3><? echo $article; ?></td>
      </tr>
</table>
<hr>
<center>
<br>
<form name="gotoeditarticle" method=POST action="editarticle.php?article=<? echo $articleid; ?>">
<input type="submit" name= "submit" value=" Edit Article ">
</form>
<br />
<?
      if ($_SESSION["admin"] == "Y") {
            echo '<a href="articles.php">Articles</a><br />';
            echo '<a href="adminmenu.php">Admin Menu</a><br />';
      }
      else{
            echo '<a href="usermenu.php">User Menu</a><br />';
      }
?>
<a href="logout.php">Logout</a>
</center>
</body>
</html>
Avatar of snowplank
snowplank

ASKER

Can anyone help?
Hmm, this code looks familiar :)

I think you're missing the point of $_SESSION, $_GET and $_POST - I'll try and explain and see if it helps...

$_SESSION is supposed to be used to store data that's persistent over one visit to the site. This "visit" might involve several pages, for instance going to the homepage, logging in, viewing some content, performing some operations and then logging back out again. So it's useful for storing information like, "is this visitor currently logged in, and if so who as?", that several pages might be interested in knowing.

$_GET and $_POST contains data relating to one particular *request*, that is, if you have a page (e.g. individualarticle.php) that is supposed to display an article, this tells it which article to display.

The difference between $_GET and $_POST lies in how the data arrives at the page:

$_GET comes from the URL query string, which is the bit of the URL after the ?, so for instance if I had a page called article.php containing the following:

<?php

print $_GET["filetype"]."<br />";
print $_GET["id"]."<br />";

?>

and browsed to:

http://some.example.com/article.php?id=500&filetype=html

I'd get the output:

500
html

$_POST on the other hand is transmitted separately to the URL, and usually arises as the result of forms that have method="post".

I hope the above made some kind of sense. Here's a couple of (untested) scripts that are probably the sort of thing you're after. They're simplified (articles only have an ID, title and text, no categories or authors) but should give you an idea of how and where $_SESSION and $_GET are used.

Also a couple of notes:
1) You don't need session_unregister if you're using $_SESSION - to unset a session variable just use unset($_SESSION["some_variable"]);
2) I'm assuming you've got magic_quotes_gpc switched on... if you're not sure what that means and these scripts are for something "real", I strongly suggest you look it up :)

-----------------------------------------------------------------------------

articles.php:
<?php

session_start();

if(!isset($_SESSION["id"])) {
    die("Not logged in");
}

$sql="SELECT articleid, title FROM articles WHERE deleted='N'";
$result=mysql_query($sql) or die(mysql_error());
?>
<table>
  <tr>
    <th>Article title</th>
  </tr>
  <? while($inf=mysql_fetch_array($result)): ?>
    <tr>
      <td>
        <!-- this generates a URL like:
                 ...individualarticle.php?article=5 -->
        <a href="individualarticle.php?article=<?=$inf["articleid"]?>">
          <?=$inf["title"]?>
        </a>
      </td>
    </tr>
  <? endwhile; ?>
</table>

-----------------------------------------------------------------------------

individualarticle.php:
<?php

session_start();

if(!isset($_SESSION["id"])) {
    die("Not logged in");
}

// this is where we pick up the article number from articles.php
$artid=$_GET["article"];

if(!is_int($artid)) { die("Invalid article ID"); }

$sql="SELECT article, title FROM articles WHERE articleid=$artid";
$result=mysql_query($sql) or die(mysql_error());
if(!($inf=mysql_fetch_array($result))) {
    die("Article not found");
}

$title=$inf["title"];
$article=$inf["article"];

?>
Article title: <?=$title?><br />
Article text: <?=$article?><br />
<? if(isset($_SESSION["admin"]) && $_SESSION["admin"]=="Y"): ?>
  <a href="editarticle.php?article=<?=$artid?>">Edit article</a>
<? endif; ?>
Also note that at the start of editarticle.php in my example, you would check *again* if the user is an admin, otherwise anyone could edit articles if they guessed the URL of editarticle.php...
Thanks for your reply,  I think I understand $_GET a little better now.  I have made the changes you suggest but I now get a different error.  I have some really strange behaviour going on.  

1) Firstly when I hover over the first article link in articles.php (which should be id=5) it shows id=1 in the URL which is an invalid article id.

2) The second article (there are only two in the db) should have id=6 but it outputs the actual article into the URL!?!  
e.g. ..individualarticle.php?articleid=Blah blah blah. Blah blah blah. Blah blah blah...

Sorry to keep pestering but I am sure that I nearly have it working.

Here is articles.php:
<?php
 error_reporting(2047); // 1 = suppress warning messages, 2047 = E_ALL all error messages
 //$sid = session_id();
 session_start();
 include("banner.php");
 require("connect.php");
 //header("Cache-control: private"); // allow the back button to function
 if (!isset($_SESSION["id"])) {
      echo '<center><br /><br />';
      print "You have not logged in to the system. Please login. <br><br>";
      echo '<meta http-equiv="Refresh" content="2; url=login.php" />';
      session_destroy();
      exit();
 }
 // get category name for title of page
 // set variable for query from articleschoosecat.php
 $catid = $_POST["category"];
 $sql = "SELECT * FROM categories WHERE id = '".$catid."'";
 $result = mysql_query($sql) or die("Sql error : " . mysql_error());
 $num = mysql_num_rows($result);
 $result_arr = mysql_fetch_array($result);
 $category = $result_arr['name'];
 $description = $result_arr['description'];
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns =" http://www.w3.org/1999/xhtml">

<head>
<title><? echo $category; ?></title>
</head>
<body>
<center>
<h3><? echo $category; ?></h3>
</center>
<table>
      <tr>
            <th align="left">Description</th>
      </tr>
      <tr>
            <td align="left"><? echo $description; ?></td>
      </tr>
</table>
<br />
<br />
<?php
      //create the SQL statement to get articles
      $sql = "SELECT articles.id AS articleid, articles.publisher, articles.category, articles.author, articles.title, articles.article, categories.id AS categoryid, categories.name, users.id AS userid, users.username FROM articles, categories, users WHERE articles.category = categories.id AND articles.publisher = users.id AND categories.id = '".$catid."' AND articles.deleted = 'N'";
      $result = mysql_query($sql) or die("Sql error : " . mysql_error());
      $num = mysql_num_rows($result);
?>
<!-- build table per article -->
<?
      if($inf = mysql_fetch_array($result)){
         do{
                   //print_r($inf); // insert this line to view array of fileds being posted
                   $articleid=$inf["articleid"];
                   //$_SESSION["articleid"] = $articleid;
             $author=$inf["author"];
             $title=$inf["title"];
             $publisher=$inf["username"];
             $article=$inf["article"];
?>  
            <table id="messageboard" border=1 cellpadding=4 width=100% style="border-collapse: collapse">
                  <tr class="toprow">
                        <th width="15%">Author: <? echo $author; ?></th>
                        <th width=75%>Title: <a href="individualarticle.php?articleid=<?= $inf["$articleid"] ?>" class="toprow"><?= $inf["title"] ?></a></th>
                        <th class="userinfo">Publisher: <? echo $publisher; ?></th>
                  </tr>
            </table>
<?
            }
            while($inf = mysql_fetch_array($result));
    }
?>
<hr>
<center>
<br>
<?
      if ($_SESSION["admin"] == "Y") {
            echo '<a href="addarticle.php">Add Article</a><br />';
            echo '<a href="adminmenu.php">Admin Menu</a><br />';
      }
      else{
            echo '<a href="usermenu.php">User Menu</a><br />';
      }
?>
<a href="logout.php">Logout</a>
</center>
</body>
</html>

individualarticle.php:
<?php
 error_reporting(2047); // 1 = suppress warning messages, 2047 = E_ALL all error messages
 //$sid = session_id();
 session_start();
 include("banner.php");
 require("connect.php");
 header("Cache-control: private"); // allow the back button to function
 if (!isset($_SESSION["id"])) {
      echo '<center><br /><br />';
      print "You have not logged in to the system. Please login. <br><br>";
      echo '<meta http-equiv="Refresh" content="2; url=login.php" />';
      session_destroy();
      exit();
 }
 //pick up articlid from URL
 $articleid=$_GET['articleid'];
 print $articleid;

 if(!is_int($articleid)) { die("Invalid article ID"); }

 //create the SQL statement
 $sql = "SELECT articles.*, users.id, users.username FROM articles, users WHERE articles.publisher = users.id AND articles.id = '" . $articleid . "'";
 $result = mysql_query($sql) or die("Sql error : " . mysql_error());
 $num = mysql_num_rows($result);

      $inf = mysql_fetch_array($result);
    $author=$inf["author"];
    $title=$inf["title"];
    $publisher=$inf["username"];
    $article=$inf["article"];
      
      //pass article id to editarticle.php if edit button is pressed
      //$_SESSION["articleid"] = $articleid;
      
?>  

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns =" http://www.w3.org/1999/xhtml">

<head>
<title><? echo $title; ?></title>
</head>
<body>
<center>
<h3><? echo $title; ?></h3>
</center>
<br />
<table border=1 cellpadding=4 width=100% style="border-collapse: collapse">
      <tr>
            <th width="10%">Author: <? echo $author; ?></th>
            <th width=80%>Title: <? echo $title; ?></th>
            <th>Published By: <? echo $publisher; ?></th>
      </tr>
      <tr>
            <td colspan=3><? echo $article; ?></td>
      </tr>
</table>
<hr>
<center>
<br>
<form name="gotoeditarticle" method=POST action="editarticle.php?article=<? echo $articleid; ?>">
<input type="submit" name= "submit" value=" Edit Article ">
</form>
<br />
<?
      if ($_SESSION["admin"] == "Y") {
            echo '<a href="articles.php">Articles</a><br />';
            echo '<a href="adminmenu.php">Admin Menu</a><br />';
      }
      else{
            echo '<a href="usermenu.php">User Menu</a><br />';
      }
?>
<a href="logout.php">Logout</a>
</center>
</body>
</html>
The problem lies here:

<th width=75%>Title: <a href="individualarticle.php?articleid=<?= $inf["$articleid"] ?>" class="toprow"><?= $inf["title"] ?></a></th>

$articleid has already been set to the ID of the current article. So for the two articles with ID 5 and 6, $inf["$articleid"] becomes $inf[5] and $inf[6]. These will correspond to columns 5 and 6 in your query, which are "article text" and "category ID", which I'm betting is 1? :)

So either change $inf["$articleid"] to $inf["articleid"], or just use $articleid and $title like all the other fields use:

<th width=75%>Title: <a href="individualarticle.php?articleid=<?= $articleid ?>" class="toprow"><?= $title ?></a></th>

You do seem to have figured out all the $_SESSION and $_GET stuff though, which is good :) The only other bit you might have problems with is the form with the edit button - is editarticle.php using $_GET or $_POST to retrieve the article to edit? If it's $_GET, you could rewrite the form as:

<form name="gotoeditarticle" method="get" action="editarticle.php">
  <input type="hidden" name="article" value="<? echo $articleid; ?>" />
  <input type="submit" name="submit" value="Edit article" />
</form>

If it uses $_POST, just replace method="get" with method="post".

The difference between the two is:

* If you submit the form with method="get", the browser will go to editarticle.php?article=5 (or whatever the hidden "article" value is set to) and so the article ID will be found in $_GET
* If you submit the form with method="post", the browser will go to editarticle.php, the article ID will be sent later in the request (i.e. not part of the URL) and so the article ID will be found in $_POST.

Whether to use method="get" or "post" depends on what you're submitting... a general guideline is that if the target page performs some modification to the database then use "post" - that way the user will be warned if they try to refresh the page (clearly we don't want to accidentally modify the database twice, e.g. in an online store, clicking "checkout" and then refreshing the resulting page might result in being charged twice as much). If the target page just retrieves some data (e.g. displays an article, or performs a search) then it does no harm to use "get" - also this has the advantage that the user can bookmark the URL (including the article ID, or search criteria) for future use.
Thanks for the quick reply.  

Ok now I am passing the correct articleid through the URL but my individualarticle.php is displaying the error "Invalid article ID".  I think it is this line that is giving the problem:  

 if(!is_int($articleid)) { die("Invalid article ID"); }

I haven't used is_int before.  I assume it checks to see if the article id is an integer.  If I print $articleid it gives the correct id as an integer, so why is it giving an error?
You were correct about me having problems with passing articleid from individualarticle.php to editarticle.php.  I get an error:

Notice: Undefined index: articleid in /home/hp208/public_html/editarticle.php on line 64

And the article isn't displayed in the editarticle.php form.

This is starting to spin me right out!

:o(

I've upped the points because I realise I am taking up your time.
I've just gone my individualevent.php and editevent.php page and realised that I have the same issue with these pages.  Can anyone help?
Sorry, my mistake... you could replace the if(!is_int.....) line with just:

$articleid=(int)$articleid;

as that will ensure it's an integer value.

Can you paste line 64 from editarticle.php please? And paste the edit form from individualarticle.php too (but just those bits, makes it easier to read).
Line 64 of editarticle.php:
$articleid = $_GET["articleid"];

Edit Form from individualarticle.php:
<form name="gotoeditarticle" method="get" action="editarticle.php">
  <input type="hidden" name="article" value="<? echo $articleid; ?>" />
  <input type="submit" name="submit" value="Edit article" />
</form>


ASKER CERTIFIED SOLUTION
Avatar of sjohnstone1234
sjohnstone1234
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial