Jump to content
Larry Ullman's Book Forums

$_Session Question


Recommended Posts

In the book's first site, let's say you, the admin, wanted to add a page for a specific member only.  That way, it is personalized for that user, and no one else, save the admin, can see those files.  So in add_page.php, what is the correct way to go about it?  Here's what I have so far.  

<form action="add_page.php" method="post" accept-charset="utf-8">
<fieldset><legend>Fill out the form to add a page of content:</legend>
<p><label for="first_name"><strong>Title</strong></label>
<?php create_form_input('title', 'text', $add_page_errors);?></p>

<p><label for="user"><strong>User</strong></label>
<select name="user"<?php if (array_key_exists('user', $add_page_errors)) echo 'class="error"';?>>
<option>Select One</option>
<?php //retrieve all the categories and add to the pull-down menu
$q = "SELECT id, username FROM users WHERE type='member' ORDER BY username ASC";
$r = mysqli_query($dbc, $q);
while ($row = mysqli_fetch_array($r, MYSQLI_NUM)) {
	echo "<option value=\"$row[0]\"";
	//check for stickyness
	if (isset($_POST['user']) && ($_POST['user'] == $row[0]) ) echo ' selected="selected"';
	echo ">$row[1]</option>\n";
}
?>
</select><?php if (array_key_exists('user', $add_page_errors)) echo ' <span class="error">' . $add_page_errors['user'] . '</span>'; ?></p>

<p><label for="category"><strong>Category</strong></label>
<select name="category"<?php if (array_key_exists('category', $add_page_errors)) echo 'class="error"';?>>
<option>Select One</option>
<?php //retrieve all the categories and add to the pull-down menu
$q = "SELECT id, category FROM categories ORDER BY category ASC";
$r = mysqli_query($dbc, $q);
while ($row = mysqli_fetch_array($r, MYSQLI_NUM)) {
	echo "<option value=\"$row[0]\"";
	//check for stickyness
	if (isset($_POST['category']) && ($_POST['category'] == $row[0]) ) echo ' selected="selected"';
	echo ">$row[1]</option>\n";
}
?>
</select><?php if (array_key_exists('category', $add_page_errors)) echo ' <span class="error">' . $add_page_errors['category'] . '</span>'; ?></p>
<p><label for="description"><strong>Description</strong></label><?php create_form_input('description', 'textarea', $add_page_errors); ?></p>
<p><label for="content"><strong>Content</strong></label><?php create_form_input('content', 'textarea', $add_page_errors); ?></p>
<p><input type="submit" name="submit_button" value="Add This Page" id="submit_button" class="formbutton"/></p>
</fieldset>
</form>

 

Now, how can that user see his/her uploaded file after logging in?  Is there a conditional statement (with the $_SESSION variable) that needs to go on page.php?

Link to comment
Share on other sites

I'm answering this without looking at your code (sorry), so my general answer may be way off.

 

By using a URL parameter, you can isolate a page to a specific user (or set of users).

For example, your "unique" page might be the same PHP script for everyone, but depending on the value of a particular URL parameter tacked onto the end, certain content would be loaded from the DB.

Naturally, you'd want to always verify that the user ID (or permissions, etc.) actually allow for a given user to access that page.

 

Given the above, you'd probably want to add some sort of user selector to add_page.php, and then have that user's ID associated with the page you create for easy confirmation later.

Link to comment
Share on other sites

If you wanted to add the ability to restrict a page to a specific user, you actually need to start by changing the database structure. Sessions won't do anything for you because the admin can't put something into the user's sessions. 

Link to comment
Share on other sites

If I understand David John correctly, the administrator adds content to the site that only user X should be allowed to see. If the administrator stores anything in the session, that will only be useful when the administrator is logged in, it wouldn't be stored in user X's session. The only way for the administrator to create something associated within another user is through a database structure change.

 

Unless I'm reading this wrong. It's not 100% clear in the original message, but that's how I interpreted it. 

Link to comment
Share on other sites

Yes, that's why I said the following:

 

Given the above, you'd probably want to add some sort of user selector to add_page.php, and then have that user's ID associated with the page you create for easy confirmation later.

 

Anyway, I'm not trying to argue with you; I just felt like I had already more or less stated that.

Link to comment
Share on other sites

HartleySan and Larry,

 

Thanks for the replies; I apologize if I caused any confusion.  Let's say the admin logs in, wants to add a page/PDF for a particular member (we'll go with User X), selects the member in the dropdown menu, and then adds the content as desired.  When X logs in, he will find his newly added content (which only he can see).  

 

I made user_id a foreign key in the "pages" table; then, as HartleySan had mentioned, added a user selector to add_page.php.  With regard to a db structure change, is it correct to use an INNER JOIN on the "users" table (again, following the book's example)?

Link to comment
Share on other sites

The database design in the book does NOT associate user IDs with pages or uploaded files, so you would need to change the database design, right? 

 

And without changing the database design, your suggestion of storing the user's ID in the session (which the book's code already does) is completely meaningless, right? 

 

There's nothing in the current database scheme that provides for any mechanism to associate specific content with specific users. In order to associate specific content with specific users, first and foremost, the database scheme has to be altered, right?

 

So I am not saying the same thing you are, am I? And yet you are arguing with me, even though you thought I was saying "more or less" the same thing you did. 

 

Add finally, even if I were to say the exact same thing as you did, there's absolutely no need for you to make a comment about that at all.

Link to comment
Share on other sites

David John, I'm not exactly sure to what query you're referring. As you already have the user ID in the session, a simple select query from pages can retrieve all the information you need. In theory you could do a join as part of the login query, but you'd have to use a LEFT JOIN there.

Link to comment
Share on other sites

I didn't say anything about what the book does or doesn't say.

I was simply saying that the user ID is the simplest way to match up unique content with a specific user.

And to that end, I wasn't aware of the fact that the unique content is displayed for a particular user right when they log in. That being the case, you're right, Larry, in that the user ID does not need to be stored in the session.

 

However, I assumed that the unique content might not be immediately accessed after logging in, in which case, you would need to store the user ID in the session, or else when the user accesses the page with the unique content at a later time, you would have to run an additional query to match up the user to a specific user ID, which seems like a waste, which is why I recommended storing the user ID in the session right when they log in (so that the user's ID is readily available without running an additional query).

 

David John, to answer your question, yes, an inner join is the simplest solution. Here's a sample query that may or may not match up with the columns and whatnot that you're using:

 

SELECT p.unique_content FROM pages AS p, users AS u WHERE p.user_ID = u.user_id AND u.email = 'some-email' AND u.password = 'some-password-hash';
Link to comment
Share on other sites

Right, you didn't say anything about what the book does or doesn't say, you're just both disagreeing with my suggestion and simultaneously saying that I'm repeating what you said. Which is an interesting contradiction.

 

Second, you say you weren't "aware of the fact that the unique content is displayed for a particular user right when they log in". That's not the case with the book's code at all. That's what David John is trying to add. 

 

Third, I'm not right in that "in that the user ID does not need to be stored in the session" for multiple reasons. A) I'm saying the opposite. B ) The user ID does need to be in the session. C) The site code already stores the user ID in the session. So, in short, in order to add this functionality that David John wants, nothing different needs to be done with the user ID or the session at all. The user ID is pulled out during the login process and stored in the session then. No changes need to be made to that process. 

 

David John, if you want to retrieve the user-specific content when the user logs in, then HartleySan's suggestion of an inner join being the simplest solution is flat out wrong. An INNER JOIN won't work. The INNER JOIN would fail for any user that provides valid login information but does not have any unique content ready for them. That's why I said you'd need to use an OUTER JOIN (LEFT JOIN) there.

 

Or you could use two separate queries: one to login and another to pull out pages. It depends upon how and where you want to display the content, and whether there are other pages of content to be displayed, too (i.e., those for all users).

Link to comment
Share on other sites

Larry, I don't like it when we start arguing like this, as it's not productive to the discussion and I think it hurts the overall reputation of the forum.

 

With that said, I fully acknowledge that the cause of our argument this time was me not clearly stating my points, but all the same, you may want to ease up a bit in the way you say things sometimes. I've never met you in person, but just reading your posts, you can come across as rather harsh, even if you are right about something.

 

In general, I answer a lot of questions at work where I don't have access to the book or the code (our computers are monitored for downloads, so I can't download the book code). As such, I rarely reference the code in the book, and prefer to answer questions with general pointers or suggestions that will hopefully point the person in the right direction and allow them to solve the problem on their own.

As a result, I did not realize that the code already stores the user ID in a session. Sorry about that.

 

Also, as you stated, the original question was not very clear, so I answered under the assumption that there would be lots of links that lots of people could see, but only some people could access, which is why I recommended the URL parameter solution.

Thinking about it more though, I guess that implementation would be rather silly as there's no reason (well, maybe there is) to display links to a bunch of content that someone cannot access.

Anyway, I suppose that argument is a moot point, as David John has since expressed the fact that he wants to load the unique content upon the user logging in.

 

Next, you are right in that the DB needs to be altered. When I said that the DB doesn't need to change, I meant in addition to the changes I already recommended to the pages table for tracking which user certain content is for.

Naturally, I could never expect you or anyone else to be able to make that assumption. As such, while I was thinking, "No additional changes beyond what I suggested are necessary," I certainly didn't express that clearly in my posts. Sorry.

 

Also, I should apologize to both you and David John, as when I stated that an inner join would work, I was assuming that the user had already been successfully logged in, and that the inner join was purely for pulling unique content (if there is any). I didn't state any if this in my post though, so again, that's my fault for making an arbitrary assumption that no one else could understand.

I fully agree with you that a single query using an outer join is best though. I was thinking the same thing, but didn't state it (because again, I was assuming that a user had already been logged in and that that point was established).

 

Also, I wasn't "agreeing but disagreeing" with you. I said that I'm not trying to argue with you because I got the feeling that I had already stated what you stated, but either because I didn't clearly express my point (the likely problem) or because you just plain misunderstood, I was trying to confirm with you whether there was a misunderstanding or not. That's why I said what I said. I wasn't trying to say something like, "I already said that, Larry!"

 

So anyway, looking back on all the posts in this thread, I think a lot of our arguments can be chalked up to me poorly stating my point (I will be sure to more carefully state my points in the future), and both you and I misunderstanding what David John wanted in the first place, which then caused us to make difference assumptions and suggest different solutions. With that said, please ease up a bit when someone either makes an incorrect statement or doesn't express themselves clearly (and that doesn't go for just me).

 

To make this post of some use to David John, I agree with you on the resolution of adding user IDs to rows in the pages table and then using one outer join when the user logs in.

Link to comment
Share on other sites

HartleySan and Larry,

 

I think it works now!  Will test some more to confirm, but so far it is returning I wanted.  

Here's how I did it:

$q = 'SELECT * FROM pages LEFT JOIN users ON pages.user_id = users.id WHERE users.id = ' .$_SESSION['user_id']. ' AND category_id = ' .$_GET['id']. ' ORDER BY date_created DESC';

 

The second part of the SQL WHERE statement was included so that the content would be relevant to the category titles.  

 

I would like to thank you both again for your help. :)   It seems I wasn't 100% clear in my question, so sorry about that... :ph34r:

Link to comment
Share on other sites

Glad to hear it.

 

I'm guessing by your SQL statement that you're using a separate SQL statement to first log the user in, and then you're using the SQL statement you wrote above as a second SQL statement to grab the unique content for that user (assuming there is any).

That's fine, but as Larry mentioned, if you perform a left join with the users table on the left and then check the email address and password hash in the WHERE clause, you can both log in the user and get any unique content in one query.

 

And as Larry suggested, the beauty of that solution is that a user will still be successfully logged in even when they don't have any unique content in the pages table.

 

Edit: Here's a simple reference page on left joins that might prove useful:

http://www.w3schools.com/sql/sql_join_left.asp

Link to comment
Share on other sites

You should. It really does help you as a programmer. A big difference between knowing how to do something, knowing why it works, and knowing that's the way it should be done. Writing and teaching has really strengthened my abilities in this last category.

Link to comment
Share on other sites

 Share

×
×
  • Create New...