Adding Context-Specific Menus PHP Help

Menus and navigation deserve a lot more than a brief mention in a chapter. There’s a ton of user interface design and usability to discuss; there are the considerations regarding; and there’s the ever-raging argument over horizontal versus vertical menus. Still, these are all non-PHP issues. For you, PHP programmer extraordinaire, the concern is building out links and options that change based upon whether a user is logged in.

You already have a sense of this. You can just check the “user_ijd” cookie:

if (isset($_COOKIE[‘user_id’]» {
// show options for logged in users.
} else {
// show options for non-logged in users
That’s all there is to it.

Putting a Menu into Place

Go back to view.php which is where all the code that controls the header of your page resides. Having some of your core view code tucked away in scripts that the rest of your pages can reference makes a huge difference. The display_title function handles the first bits of a displayable page right now.

Find that function, and you can add a simple if: if the “user_id” cookie exists, show a profile link to show_user.php and a signout.php link (more on that in a bit). If he’s not signed in, show him a Sign In link. Of course, you can add a Home link that appears regardless:

function display_title($title, $success_message = NULL, $error_message = NULL)
echo «<EOO
<div id=”header”><hl>PHP & MySOL: The Missing Manual</hl></div>
<div id=”example”>$title</div>
<div id=”menu”>
<li><a href=”index.html”>Home</a></li>
if (isset($_COOKIE[‘user_id’]» {
echo “<li><a href=’show_user.php’>My Profile</a>”;
echo “<li><a href=’signout.php’>Sign Out</a></li>”;
} else {
echo “<li><a href=’signin.php’>Sign In</a></li>”j
echo <<<EOO
display_messages($success_message, $error_message);

There’s a twofold beauty to this. First. this menu is now available to all scripts via few on». This means that you don’t need to go rooting through all your files and insert new HTML and if statements to get a site-wide menu. Second, because you dropped this code into dispIay _title, any of your scripts that already call display _title automatically get the menu code. Nothing to change in those at all.

Also, once again, the fact that $_REQUESTwill return anything in $_COOKIEmakes this script simple:

if (isset($_COOKIE[‘user_id’]))
echo “<li><a href=’show_user.php’>My Profile</a>nj
echo “<li><a href=’signout.php’>Sign Outc/a>c/li>”;
} else {
echo “cli>ca href=’signin.php’>Sign Inc/a>c/li>”;

You’re not worried about passing a user’s ID into show_user.php  because there’s a cookie set. and you’ve already seen that show_user.php is happy to grab that value through $_ REQUEST'[user _id’ ]. just as though you’d explicitly passed in a user ID through a request parameter.

Signing Out

It’s true: unless people are on a financial site-their bank or perhaps a stock trading Site-logging and signing out is
largely never touched. Most Internet users are not very security conscious, and there’s also an expectation that a website will simply remember them when they return later. Signing out would prevent that, so why do it?

There are good reasons to add Sign-out capabilities to any app. First, if users are accessing your app on a public computer or shared laptop, you want to ensure that they can protect their credentials by signing out Defy letting anyone else use the computer. Second, just because most users aren’t security conscious doesn’t mean that none are. Give someone the option to sign out. and if he doesn’t avail himself of it. no big deal. If he does, he’ll be glad your app gives him that control. And last but not least, you know how to create cookies. It would be a good thing to know how to delete them, as well. Thus, adding a sign-out link forces you to get a handle on that. too.

To test this out, open your various scripts that display HTML:show_user.php, show_user.php Each should call page_start rather than display HTML explicitly. Otherwise, you’ll lose the menu code that you just added to page_start in view.php Here, for example, is what show_user.php should look like:

Adding Context-Specific Menus

Now; sign in. You should automatically land on show_user.php and see something like Figure 13-10. There’s a nice. simple menu on the right that appears, thanks to start _page. display, title view.php and the cookies you set in signin.php.

FIGURE 13-10

FIGURE 13-10

From HTML to Scripts

You might have noticed that even once you’ve fixed up show_user.php, show_users.php and signin.php there are still HTML web pages left in your application. There’s index.html the initial page, as well as create_user.html. But, these pages don’t get the benefit of start_page and view.php, because they’re HTML, not PHP. For index.html that probably makes sense. The only two places you want users to go is the sign-in page or the sign-up page; both are clearly accessible through those big green buttons.

However, that’s not the case with Create_user.html Suppose that someone clicks through to that form and then wants to return to the main page. Or, more likely, she might want to sign in rather than sign up. This becomes even more the case as you add other options to the menu, such as an About page. Clearly, create_user.html needs that menu.


In essence, all you have to do is convert Create_user.html to PHP. You could call it create_user.php apart from the fact that create_user.html already exists. So, as a starting point. rename create_user.html After all, it’s a form for signing up users, and the name doesn’t clash with any other file names.

[-/www/phpMM/ch13]# cp create_user.html create_user.html.orig
[-/www/phpMM/ch13]# mv create_user.html signup.php

Then, you can simply cut out the opening HTML and replace it with a PHP-driven call to page_start. You’ll have to pass through all that inline validation JavaScript, but that’s easy now; you can just use heredoc.

From HTML to Scripts

This is also a good time to update View.php to include the jQuery, validation scripts, and CSS that sigin.php needs. There’s no reason to not make those available to all your site’s pages:

From HTML to Scripts

Update your links in .naex.ntm. to reference signup Php rather than create_user.html:

From HTML to Scripts

FIGURE 13-11

FIGURE 13-11


By now, you realize that you don’t need two scripts to handle user creation. You could create a single script that submits to itself. That lets you not only do the client-side validation already in place with jQuery and JavaScript, but also check user names and emails against the database and return errors if there are duplicates. At this stage, though, you don’t need to see another painfully long code listing. You have all you need to do it yourself. Set this book down and start combining Si’J’m ot.o and create_,iser.pnp. As always, there’s swag to be had by tweeting your solution to @missingmanuals or hopping on Facebook at

Logging Users Out
Yourloqin now works, but don’t forget to add logging out. Whether you set your cookie’s expiration value to a short few minutes or a long one, always let users control their own authentication. They should be able to log in and log out when they want.

Logging in involves setting a cookie name, value, and optionally, a time for expiration:

setcookie(‘user_id’, $user_id); // Default expiration:
setcookie(‘username’, $result[‘username’]); // Log out on browser close

FIGURE 13-12

FIGURE 13-12

Requiring the Cookie to Be Set

Fortunately, the issue of error pages showing up at the wrong time isn’t hard to fix. Earlier, show_user.php and other restricted scripts required authorize.php (page 396), which did all sorts of database work to determine whether a user could log in, all using basic  HTTP authentication. As a result, you got a nice wall around your scripts.

By removing authorize.php it became possible to have signin.php handle logins. In the process, though, you knocked down that wall around your other scripts. You need the wall, but you still need to let signin.php handle authentication. That’s not hard.

First, you can drastically simplify authorize.php it down to do little more than check for a valid cookie:

if ((!isset($_COOKIE[‘user_id’)) I I
(!strlen($_COOKIE[‘user_id’) > 0» {

If there’s no cookie, or if the cookie has an empty value, just redirect the user to the sign-in page’ with a message that explains what’s going on:

if ((!isset($_COOKIE[‘user_id’]» I I
(!strlen($_COOKIE[‘user_id’]) > 0» {
header(‘Location: signin.php?’
‘error_message=You must login to see this page.’);

Next, you. can add the require_once back in to show_user.php, show_users.oilp, and delete_. user.php.

Test it. Make sure that you’re signed out (signout.php) via the menu link makes that a breeze now). Then, try to access show_user.php: You see signs of progress, although things aren’t perfect yet. Figure 13-13is a good start, though.

FIGURE 13-13

FIGURE 13-13

The missing message in Figure 13-13 is due to the fact that there’s nothing in sign.php that deals with a potential message on the request URL. Happily, you actually have the mechanics for this in place. Open Signin.php and check out the opening section:

require_once’ ../scripts/view.php’;
$error_message = “”;
// If the user is logged in, the user_id cookie will be set
if (!isset($_COOKIE[‘user_id’])) {

This is great! You have a variable to hold the error message in place. And, you already have code to display $error _message as an error:

// Still in the “not signed in” part of the if
// Start the page, and pass along any error message set earlier
page_start(“Sign In”, NULL, NULL, $error_message);

Now, you just need to see whether there’s a request parameter back up at the top rather than autoroatically assigning $error _message an empty string:
require_once’ ../scripts/database_connection.php’;
require_once’ ../scripts/view.php’;
$error_message = $_REOUEST[‘error_message’];
// If the user is logged in, the user_id cookie will be set
if (!isset($_COOKIE[‘user_id’])) {

Go ahead and try things one more time. Go to snc» ..user ptv: without having a cookie, and you should see something like Figure 13-14.

FIGURE 13-14

FIGURE 13-14

So, what’s left? Take a look back at your original list:

• A better login screen. Folks don’t like a bland, gray pop-up dialog box; they want a branded, styled login form. (Done!)

• Better messaging to indicate whether a user is logged in. (Done!)

• A way to log out. (Done!)

• Two levels of authentication: one to get to the main application, and then admin-level authentication to get to a page like SHOW_USER.PHP and Deleteuser.php (Hmmm, nothing here yet at all.)

• Some basic navigation. That navigation should change based on a user’s login and the groups to which the user belongs. (Sort of done … )

Take a quick breath and get ready for the home stretch: group-based authentication and the reason that cookies are cool, but maybe not your final authentication destination.

Posted on January 14, 2016 in Cookies, Sign- Ins, and Ditching Crummy Pop-Ups

Share the Story

Back to Top