Link to home
Start Free TrialLog in
Avatar of bswinnerton
bswinnertonFlag for United States of America

asked on

How to store PHP session variable as MySQL results

I'm trying to find a way using PHP to pass the contents of a MySQL query over to the next page using a session.

So here is how it's laid out. I have my main file called index.php which does a MySQL query that gets the id,title and content of a post from the database. It then shows a shortened version of the content and a link to the full version article. The problem is that I'm using clean url's so it's just the title in the link, so I need to pass the id of the post as well so that posts.php know's which post to display (but all of this has to be hidden which is why I'm using a session).

Here's my current code and I'm open to any new ideas if I'm not going about this the right way.

-----------------------------------------------------------------------------------------------------------------------------
index.php:

session_start();
$query = "SELECT id, title, content FROM blog";
$result = mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
        $id = $row['id'];
        $content = shorten($content);
        echo "<h2><a href=\"/posts/".title_to_underscore($row['title'])."\">",$row['title'],"</a></h2>\n","<p>",$content"</p><br />";
}
$_SESSION['id'] = $id;
-----------------------------------------------------------------------------------------------------------------------------
and posts.php:

$id = $_SESSION['id'];
$query = mysql_query("SELECT id, title, date, author, content, FROM blog WHERE id = '$id'");
-----------------------------------------------------------------------------------------------------------------------------

The problem with my code is that it's making $_SESSION['id'] equal to whatever the last post in the query. So how can I get around this?
Avatar of brad2575
brad2575
Flag of United States of America image

You can have the link do a javavacript onlick that populates a form variable with the ID you want to display on the next page and after you populate the form variable the javascript function  submits the form (to the URL page you want to display the full page) and then the destination page reads the form field value.



Avatar of hielo
The problem with your posted code is that the $_SESSION has only ONE id, but your WHILE is generating one link per record. You need to include the id in the link and on the other page you just query the db for that specific id.

 echo "<h2><a href=\"/posts/".title_to_underscore($row['title'])."/?id=" . $id . ">",$row['title'],"</a></h2>\n","<p>",$content"</p><br />";
Avatar of bswinnerton

ASKER

I hielo, I understand that the link could include the id. But remember, I'm trying to do all of this without passing any parameters through the URL. The only thing that I want in the url is the domain name and the title of the article. This is why I'm using a session.
OK, and how are you associating the id with the articles on the landing page? To answer your question, the id needs to be assigned within the loop as show below. On the landing page, if you do:
<?php
session_start();
print_r($_SESSION);

?>

You should see an array of ids, ONE of which is for your article
session_start();
$query = "SELECT id, title, content FROM blog";
$result = mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
        $id = $row['id'];
        $content = shorten($content);
        echo "<h2><a href=\"/posts/".title_to_underscore($row['title'])."\">",$row['title'],"</a></h2>\n","<p>",$content"</p><br />";
	   $_SESSION['id'][] = $id;
}

Open in new window

On the landing page it looks a little something like this:

$id = $_SESSION['id'];
$query =  mysql_query("SELECT id, title, date, author, content, FROM blog WHERE id  = '$id'");

However, I have multiple mysql queries on the index.php page, which all pull the id from the database based on certain criteria.

But how can I know which one in the array to use?
>>But how can I know which one in the array to use?
LOL. Exactly my point. You need to "disclose" something via the browser! That's why you usually pass an id via the url.

I see you are using:
 href=\"/posts/".title_to_underscore($row['title'])

Are all those links unique? Meaning that each link takes you to a different page? IF yes technically, you shouldn't have to save and id because your  links would be something like:
href="/posts/sports"
href="/posts/technology"

So when you land in technology, you can determine the requested/current url (on the landing page do print_r($_SERVER['REQUEST_URI']);

and you should be able to see /posts/technology)

and extract the id from the db based on what you see in $_SERVER['REQUEST_URI'].  IF you do not want to do this (meaning if you do not want to requery the db  - select id from table where title = $title), then you can just use the title as the $_SESSION key and the id as the value on the code above:
$_SESSION[ $row['title'] ] = $id;

but you will still need to determine the title (ex:technology) from the requested url as discussed above.
But
Hmm, I don't mean to be a pain in the ass.

I'm using the function title_to_underscore as so:
  function title_to_underscore($string)
  {
    $badtext = array('?', '!', '$', ',', '.', '\\', '/', '(', ')', "'");
    $badtext_removed = str_replace($badtext, '', $string);
    $underscored = str_replace(' ', '_', $badtext_removed);
    return $underscored;
  };

So I suppose that you could say they are unique, however I can't directly query the database with that because the function strips special characters that will mess up the URL, and replaces them with underscores. So for example, the title: "this is a title?" would be the same thing as "this is a title!". This is the entire reason that I wanted to pass the ID in the background using a session variable. I already have a unique value id on the database, I just don't want the user's to see it in the URL.
>>So I suppose that you could say they are unique
Well, the simple way to tell is to load the page via your browser, look at the browser's source code. You should be able to see the dynamically generated links:
<a href="/posts/XXX">...</a>
...
<a href="/posts/XXX">...</a>

Where my "XXX" are placeholders for what your code is actually generated. So, to determine if they are unique, look at ALL those "XXX" on your generated links. Is there at least one duplicate? Yes => Then they are not unique, otherwise they are! It's that simple!
I understand that hielo, however like I said in my previous post: "I can't directly query the database with that because the function  strips special characters that will mess up the URL, and replaces them  with underscores".
OK, so if your url is:
/post/alph?!?

it will get converted to
_post_alph___

so when you lick on that "clean" url, on the landing page you should be able to see/get _post_alph___ from $_SERVER['REQUEST_URI']

If read post ID:30767475 again, the other suggestion was to first use the "clean" url as a key in a session variable:
$_SESSION['_post_alph___']=$id;

so on the landing page, based on what your REQUEST_URI, you would be able to get a potential key that may exist in the $_SESSION array, and if it does, then you can get the id.
This seems really messy. If for some odd reason I do end up having two titles that end up being the same because of the clean url function, everything will be messed up. That's why I'm trying to pass only the title in the url and behind the scenes the unique id (that comes from the database) of the selected post.
What I'm thinking may be a viable solution is having some sort of javascript (I have a bare knowledge of javascript), that is something like this: onclick($_SESSION['id'] == selected $row['id']). Unless there is a way of doing this with PHP, etc.
ASKER CERTIFIED SOLUTION
Avatar of hielo
hielo
Flag of Wallis and Futuna 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
I don't want to pass the ID because I'm trying to make the URL as clean as possible without any information that the end user doesn't need.

"This is how everyone else does it. I don't understand why you oppose to  this." -- This is where I disagree with you. Wordpress for example structures it's posts as such: http://www.mysite.com/blog/2010/04/is-this-a-post/ for the title "is & thi's a post?", obviously stripping special characters. Now, I'm not sure how they do it, but they must ALSO pass some sort of unique id as well (but as you can see, not in the link).
Ah, well that clears things up? I thought you were opposed to passing the id - period. It is clear now that what you don't want is a querystring:
?a=1&c=3

etc.

That is done with mod_rewrite support on the server end. Basically when the user goes to:
 http://www.mysite.com/blog/2010/04/is-this-a-post/  

there is typically an .htaccess file that will "convert" that url (internally - meaning without the user seeing the "new" url) into some sort of tokenized string like:
 http://www.mysite.com/blog?year=2010&day=04&title=is-this-a-post

then your script is able to get each of those components to query a db. Do a search for ".htaccess" or mod_rewrite tutorials.

When I said "This is how everyone else does it." I was referring to the "unique" token per url that would allow me to query specific record(s) from my db, not necessarily an id, but using an id is also certainly doable:
 http://www.mysite.com/post/2389/ => http://www.mysite.com/post?id=2389