• Aucun résultat trouvé

Using PHP to identify the current page

Dans le document DAVID POWERS Y (Page 115-122)

I’ll have more to say about security issues surrounding include files later in the chapter.

First, let’s fix that problem with the menu style that indicates which page you’re on.

Continue working with the same files. Alternatively, use index02.php, contact.php, gallery.php, journal.php, includes/menu.inc01.php, and includes/footer.inc01.php from the download files for this chapter. If using the download files, remove the 01and 02from any filenames.

1.Open menu.inc.php. The code currently looks like this:

<ul id="nav">

<li><a href="index.php" id="here">Home</a></li>

<li><a href="journal.php">Journal</a></li>

<li><a href="gallery.php">Gallery</a></li>

<li><a href="contact.php">Contact</a></li>

</ul>

The style to indicate the current page is controlled by the id="here"highlighted in line 3. What you need is a way of getting PHP to insert id="here" into the journal.php <a>tag if the current page is journal.php, into the gallery.php <a>

tag if the page is gallery.php, and into the contact.php <a>tag if the page is contact.php.

Hopefully, you have got the hint by now—you need an ifstatement (see the sec-tion on condisec-tional statements, “Making decisions,” in Chapter 3) in each <a>tag.

Line 3 needs to look like this:

<li><a href="index.php" <?php if ($currentPage == 'index.php') { ➥ echo 'id="here"'; } ?>>Home</a></li>

The other links should be amended in a similar way. But how does $currentPage get its value? You need some way of finding out the filename of the current page.

2.Leave menu.inc.phpto one side for the moment and create a new PHP page called scriptname.php. Insert the following code between a pair of PHP tags (alterna-tively, just use scriptname1.phpin the download files for this chapter):

echo $_SERVER['SCRIPT_NAME'];

3.Save scriptname.phpand view it in a browser. On a Windows system, you should see something like the following screenshot. (The download file contains the code for this step and the next, together with text indicating which is which.)

PHP Solution 4-3: Automatically setting a style to indicate the current page

On Mac OS X, you should see something similar to this:

$_SERVER['SCRIPT_NAME'] comes from one of PHP’s built-in superglobal arrays, and it always gives you the absolute (site root–relative) pathname for the current page. As you can see from the two screenshots, it works the same regardless of the server’s operating system. What you need now is a way of extracting just the filename.

4.Amend the code in the previous step like this:

echo basename($_SERVER['SCRIPT_NAME']);

5.Save scriptname.phpand click the Reloadbutton in your browser. You should now see just the filename: scriptname.php. If you get a parse error message instead, make sure that you have included the closing parenthesis just before the final semicolon.

The built-in PHP function basename()takes the pathname of a file and extracts the filename. So, there you have it—a way of finding the filename of the current page.

6.Amend the code in menu.inc.phplike this (the changes are highlighted in bold):

<?php $currentPage = basename($_SERVER['SCRIPT_NAME']); ?>

<ul id="nav">

<li><a href="index.php" <?php if ($currentPage == ➥ 'index.php') {echo 'id="here"';} ?>>Home</a></li>

<li><a href="journal.php" <?php if ($currentPage == ➥ 'journal.php') {echo 'id="here"';} ?>>Journal</a></li>

<li><a href="gallery.php" <?php if ($currentPage == ➥ 'gallery.php') {echo 'id="here"';} ?>>Gallery</a></li>

<li><a href="contact.php" <?php if ($currentPage == ➥ 'contact.php') {echo 'id="here"';} ?>>Contact</a></li>

</ul>

7.Save menu.inc.phpand load index.phpinto a browser. The menu should look no different from before. Use the menu to navigate to other pages. This time, as shown in Figure 4-5, the border alongside the current page should be white, indi-cating your location within the site. If you inspect the page’s source view in the Make sure that you get the combination of single and double quotes correct.

The value of attributes, such as id, must be enclosed in quotes for valid XHTML.

Since I’ve used double quotes around here, I’ve wrapped the string 'id="here"' in single quotes. I could have written "id=\"here\"", but a mixture of single and double quotes is easier to read.

4

browser, you’ll see that the hereID has been automatically inserted into the cor-rect link. If you experience any problems, compare your code with menu.inc02.php in the download files.

Figure 4-5. With the help of some simple conditional code, the include file produces different output for each page.

Now that you know how to find the filename of the current page, you might also find it useful to automate the <title>tag of each page. This works only if you use filenames that tell you something about the page’s contents, but since that’s a good practice anyway, it’s not really a restriction.

Although the following steps use the Japan Journey website, you can try this out with any page.

1.The basename()function used in the previous solution takes an optional second argu-ment: a string containing the filename extension. Create a new PHP file and insert the following code between a pair of PHP tags (the code is in scriptname2.php):

echo basename($_SERVER['SCRIPT_NAME'], '.php');

2.Save the page with any name you like (as long as it has a .phpfilename extension), and load it into a browser. It should display the name of the file stripped of the .phpextension. The download file displays scriptname2.

Note that when passing more than one argument to a function, you separate the arguments with commas.

PHP Solution 4-4: Automatically generating a page’s title from its filename

You now have the basis for automatically creating the page title for every page in your site, using basename(), $_SERVER['SCRIPT_NAME'], and an include file.

3.Create a new PHP file called title.inc.phpand save it in the includesfolder.

4.Strip out any code inserted by your script editor, and type in the following code (the finished code for title.inc.phpis in the ch04/includesfolder of the down-load files):

<?php

$title = basename($_SERVER['SCRIPT_NAME'], '.php');

?>

This finds the filename of the current page, strips the .phpfilename extension, and assigns the result to a variable called $title.

5.Open a PHP page in your script editor. If you’re using the Japan Journey site, use contact.php. Include title.inc.phpby typing this above the DOCTYPEdeclaration:

<?php include('includes/title.inc.php'); ?>

6.Amend the <title>tag like this:

<title>Japan Journey<?php echo "&#8212;{$title}"; ?></title>

This uses echoto display &#8212;(the numerical entity for an em dash) followed by the value of $title. Because the string is enclosed in double quotes, PHP dis-plays the value of $title(see “All you ever wanted to know about quotes—and more” in Chapter 3 for an explanation of how PHP treats variables inside double quotes).

The variable $titlehas also been enclosed in curly braces because there is no space between the em dash and $title. Although not always necessary, it’s a good idea to enclose variables in braces when using them without any whitespace in a double-quoted string, as it makes the variable clear to you and the PHP engine.

The first few lines of your page should look like this:

The code for this include file must be enclosed in PHP tags. This is because the whole file needs to be treated as PHP. Unlike the menu, it won’t be displayed directly inside other pages.

4

7.Save both pages and load the web page into a browser. Figure 4-6 shows how the change is reflected in contact.php.

Figure 4-6. Once you extract the filename, it’s possible to create the page title dynamically.

8.Not bad, but what if you prefer an initial capital letter for the part of the title derived from the filename? Nothing could be simpler. PHP has a neat little func-tion called ucfirst(), which does exactly that (the name is easy to remember once you realize that ucstands for “uppercase”). Add another line to the code in step 4 like this:

<?php

$title = basename($_SERVER['SCRIPT_NAME'], '.php');

$title = ucfirst($title);

?>

When confronted by something like this, some people start breaking out into a sweat, convinced that programming is a black art that is the work of the devil—or at least of a warped mind. Actually, it’s quite simple: the first line of code after the PHP tag gets the filename, strips the .phpoff the end, and stores it as $title. The next line takes the value of $title, passes it to ucfirst()to capitalize the first let-ter, and stores the result back in $title. So, if the filename is contact.php, $title starts out as contact, but by the end of the following line it has become Contact.

You can shorten the code by combining both lines into one like this:

$title = ucfirst(basename($_SERVER['SCRIPT_NAME'], '.php'));

When you nest functions like this, PHP processes the innermost one first and passes the result to the outer function. It makes your code shorter, but it’s not so easy to read.

If you’ve been using CSS for a while, you’ll know that putting anything above the DOCTYPE declaration forces browsers into quirks mode. However, this doesn’t apply to PHP code, as long as it doesn’t send any output to the browser. The code in title.inc.phponly assigns a value to $title, so the DOCTYPE declara-tion remains the first thing that the browser sees, and any CSS is displayed in standards-compliant mode.

9.A drawback with this technique is that filenames consist of only one word—at least they should. If you’ve picked up bad habits from Windows and Mac OS X permit-ting spaces in filenames, get out of them immediately. Spaces are not allowed in URLs, which is why most web design software replaces spaces with %20. You can get around this problem, though, by using an underscore. Change the name of the file you’re working with so that it uses two words separated by an underscore. For example, change contact.phpto contact_us.php.

10.Change the code in title.inc.phplike this:

<?php

$title = basename($_SERVER['SCRIPT_NAME'], '.php');

$title = str_replace('_', ' ', $title);

$title = ucwords($title);

?>

The middle line uses a function called str_replace()to look for every underscore and replace it with a space. The function takes three arguments:

The character you want to replace (you can also search for multiple characters) The replacement character or characters

The string where you want the changes to be made

You can also use str_replace()to remove character(s) by using an empty string (a pair of quotes with nothing between them) as the second argument. This replaces the string in the first argument with nothing, effectively removing it.

The other change is in the final line of code. Instead of ucfirst(), it uses the related function ucwords(), which gives each word an initial cap.

11.Save title.inc.phpand load into a browser the file that you renamed in step 9.

Figure 4-7 shows the result with contact_us.php.

Figure 4-7. With the help of str_replace(), you can even create titles that contain more than one word.

12.Change back the name of the file so that it no longer has an underscore. Reload the file into a browser. You’ll see that the script in title.inc.phpstill works. There are no underscores to replace, so str_replace() leaves the value of $title untouched, and ucwords() converts the first letter to uppercase, even though there’s only one word.

4

13.What happens, though, if you have page names that don’t make good titles? The home page of the Japan Journey site is called index.php. As the following screen-shot shows, applying the current solution to this page doesn’t seem quite right.

There are two solutions: either don’t apply this technique to such pages or use a conditional statement (an ifstatement) to handle special cases. For instance, to display Homeinstead of Index, amend the code in title.inc.phplike this:

<?php

$title = basename($_SERVER['SCRIPT_NAME'], '.php');

$title = str_replace('_', ' ', $title);

if ($title == 'index') {

$title = 'home';

}

$title = ucwords($title);

?>

The first line of the conditional statement uses two equal signs to check the value of $title. The following line uses a single equal sign to assign the new value to

$title. If the page is called anything other than index.php, the line inside the curly braces is ignored, and $titlekeeps its original value.

14.Save title.inc.phpand reload index.phpinto a browser. The page title now looks more natural, as shown in the following screenshot.

PHP is case-sensitive, so this solution works only if indexis all lowercase. To do a case-insensitive comparison, change the fourth line of the preceding code like this:

if (strtolower($title) == 'index') {

The function strtolower()converts a string to lowercase—hence its name—

and is frequently used to make case-insensitive comparisons. The conversion to lowercase is not permanent, because strtolower($title)isn’t assigned to a variable; it’s only used to make the comparison. To make a change permanent, you need to assign the result back to a variable as in the final line, when ucwords($title)is assigned back to $title.

To convert a string to uppercase, use strtoupper().

15.Navigate back to contact.php, and you’ll see that the page title is still derived cor-rectly from the page name.

16.There’s one final refinement you should make. The PHP code inside the <title>

tag relies on the existence of the variable $title, which won’t be set if there’s a problem with the include file. Before attempting to display the contents of a vari-able that comes from an external source, it’s always a good idea to check that it exists, using a function called isset(). Wrap the echocommand inside a condi-tional statement, and test for the variable’s existence like this:

<title>Japan Journey<?php if (isset($title)) {echo "&#8212;{$title}";} ➥

?></title>

If $titledoesn’t exist, the echocommand will be ignored, leaving just the default site title, Japan Journey. You can check your code against an updated version of index.phpin index03.phpin the download files.

Dans le document DAVID POWERS Y (Page 115-122)