Chapter 5

Using Functions and Session Variables

In This Chapter

arrow Creating functions to manage your code's complexity

arrow Enhancing your code by using functions

arrow Working with variable scope

arrow Getting familiar with session variables

arrow Incorporating session variables into your code

PHP programs are used to solve interesting problems, which can get quite complex. In this chapter, you explore ways to manage this complexity. You discover how to build functions to encapsulate your code. You also learn how to use session variables to make your programs keep track of their values, even when the program is called many times.

Creating Your Own Functions

It won't take long before your code starts to get complex. Functions are used to manage this complexity. As an example, take a look at Figure 5-1.

9781118289389-fg2901.tif

Figure 5-1: This program rolls five dice.

Rolling dice the old-fashioned way

Before I show you how to improve your code with functions, look at a program that doesn't use functions so you have something to compare with.

The following rollDice.php program creates five random numbers and displays a graphic for each die:

  <!DOCTYPE html>
<html lang = "en-US">
  <head>
    <meta charset = "UTF-8">
    <title>rollDice1.php</title>
  </head>
  <body>
    <h1>RollDice 1</h1>
    <h2>Uses Sequential Programming</h2>
    <div>
    <?php
$roll = rand(1,6);
$image = "dado_$roll.png";
print <<< HERE
    <img src = "$image"
         alt = "roll: $roll"
         width = "100px"
         height = "100px" />
HERE;
 
$roll = rand(1,6);
$image = "dado_$roll.png";
print <<< HERE
    <img src = "$image"
         alt = "roll: $roll"
         width = "100px"
         height = "100px" />
HERE;
 
$roll = rand(1,6);
$image = "dado_$roll.png";
print <<< HERE
    <img src = "$image"
         alt = "roll: $roll"
         width = "100px"
         height = "100px" />
HERE;
 
$roll = rand(1,6);
$image = "dado_$roll.png";
print <<< HERE
    <img src = "$image"
         alt = "roll: $roll"
         width = "100px"
         height = "100px" />
HERE;
 
$roll = rand(1,6);
$image = "dado_$roll.png";
print <<< HERE
    <img src = "$image"
         alt = "roll: $roll"
         width = "100px"
         height = "100px" />
HERE;
 
    ?>
    </div>
  </body>
</html>

Here are some interesting features of this code:

  • The built-in rand()function rolls a random number. Whenever possible, try to find functions that can help you. The rand() function produces a random integer. If you use two parameters, the resulting number will be in the given range. To roll a standard six-sided die, use rand(1,6):

      $roll = rand(1,6);

  • I created an image for each possible roll. To make this program more visually appealing, I created an image for each possible die roll. The images are called dado_1.png, dado_2.png, and so on. All these images are stored in the same directory as the PHP program.
  • Theimg tag is created based on the die roll. After I have a die roll, it's easy to create an image based on that roll:

          $image = "dado_$roll.png";
          print <<< HERE
        <img src = "$image"
             alt = "roll: $roll"
             height = "100px"
             width = "100px" />
             
    HERE;

  • The die-rolling code is repeated five times. If you can roll one die, you can easily roll five. It's as easy as copying and pasting the code. This seems pretty easy, but it leads to problems. What if I want to change the way I roll the dice? If so, I'll have to change the code five times. What if I want to roll 100 dice? The program will quickly become unwieldy. In general, if you find yourself copying and pasting code, you can improve the code by adding a function.

Improving code with functions

Functions are predefined code fragments. After you define a function, you can use it as many times as you wish. As you can see in the following code, the outward appearance of this program is identical to rollDice1.php, but the internal organization is quite different:

  <!DOCTYPE html>
<html lang = "en-US">
  <head>
    <meta charset = "UTF-8">
    <title>rollDice2.php</title>
  </head>
  <body>
    <h1>RollDice 2</h1>
    <h2>Uses Functions</h2>
    <?php
      function rollDie(){
        $roll = rand(1,6);
        $image = "dado_$roll.png";
        print <<< HERE
          <img src = "$image"
               alt = "roll: $roll"
               height = "100px"
               width = "100px" />
HERE;
      } // end rollDie
      
      for ($i = 0; $i < 5; $i++){
        rollDie();
      } // end for loop
    ?>
  </body>
</html>

Here's how things have changed in this version:

  1. Use the function keyword to define a function.

    The function keyword indicates that a function definition will follow. The code inside the definition won't be run immediately, but instead, PHP will “remember” the code inside the function definition and play it back on demand:

      function rollDie(){

  2. Give the function a name.

    The function name should indicate what the function does. I call my function rollDie() because that's what it does (rolls a die):

      function rollDie(){

  3. Specify arguments with parentheses.

    You can send arguments (special variables for your function to work with) by indicating them in the parentheses. This function doesn't need arguments, so I leave the parentheses empty:

      function rollDie(){

    tip.eps For more information on functions, arguments, and the return statement, turn to Book  IV, Chapter  4. Functions in PHP act almost exactly like their cousins in JavaScript.

  4. Begin the function definition with a left brace ({).

    The left brace is used to indicate the beginning of the function code.

  5. Indent the code that makes up your function.

    Use indentation to indicate which code is part of your function. In this case, the function generates the random number and prints an image tag based on that random number:

          function rollDie(){
            $roll = rand(1,6);
            $image = "dado_$roll.png";
            print <<< HERE
              <img src = "$image"
                   alt = "roll: $roll"
                   height = "100px"
                   width = "100px" />
    HERE;
          } // end rollDie

  6. Denote the end of the function with a right brace (}).
  7. Call the function by referring to it.

    After the function is defined, you can use it in your code as if it were built into PHP. In this example, I call the function inside a loop:

      for ($i = 0; $i < 5; $i++){
      rollDie();
    } // end for loop

Because the code is defined in a function, it's a simple matter to run it as many times as I want. Functions also make your code easier to read because the details of rolling the dice are hidden in the function.

Managing variable scope

Two kinds of scope are in PHP: global and local.

If you define a variable outside a function, it has the potential to be used inside any function. If you define a variable inside a function, you can access it only from inside the function in which it was created. See Book  IV, Chapter  4 for more on variable scope.

So, if you have a variable that you want to access and modify from within the function, you either need to pass it through the parentheses or access it with the global modifier.

The following code will print hello world! only once:

  <?php
$output = "<p>hello world!</p>";
 
function helloWorld(){
    global $output;
 
    print $output;
}
 
function helloWorld2(){
    print $output;
}
 
helloWorld();
helloWorld2();
?>

I left the global keyword off in the helloWorld2() function, so it didn't print at all because inside the function, the local variable $output is undefined. By putting the global keyword on in the helloWorld() function, I let it know I was referring to a global variable defined outside the function.

tip.eps PHP defaults to local inside functions because it doesn't want you to accidentally access or overwrite other variables throughout the program. For more information about global and local scoping, check out http://us3.php.net/manual/en/language.variables.scope.php.

Returning data from functions

At the end of the function, you can tell the function to return one (and only one) thing. The return statement should be the last statement of your function. The return statement isn't required, but it can be handy.

The getName() function in the following code example will return "World" to be used by the program. The program will print it once and store the text in a variable to be printed multiple times later, as shown in the following code and Figure 5-2:

  <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>helloFunction</title>
</head>
<body>
  <?php
    function getName(){
        return "World";
    }
 
    print "<h1>Hello, " . getName() . "!</h1>";
    $name = getName();
    print <<<HERE
    <p>$name, welcome to our site. We are so very happy to have you here.</p>
    <p>If you would like to contact us, $name, just use the form on the contact page.</p>
HERE;
  ?>
</body>
</html>

9781118289389-fg2902.tif

Figure 5-2: An example of a function with a return statement.

tip.eps The example in Figure 5-2 is admittedly contrived. This function could easily be replaced by a variable, but the program that uses the function doesn't know that the function has only one line. Later on, I could make the function much more complicated (maybe pulling the name from a database or session variable). This points out a very important feature of functions that return values: they can feel like variables when you use them.

Managing Persistence with Session Variables

Server-side programming is very handy, but it has one major flaw. Every connection to the server is an entirely different transaction. Sometimes, you'll want to reuse a variable between several calls of the program. As an example, take a look at rollDice3.php in Figure 5-3.

9781118289389-fg2903.tif

Figure 5-3: This page displays a roll, the number of rolls, and the total rolls so far.

The interesting feature of rollDice3.php happens when you reload the page. Take a look at Figure 5-4. This is still rollDice3.php, after I refreshed the browser a few times. Take a look at the total. It increases with each roll.

9781118289389-fg2904.tif

Figure 5-4: The count and total values keep on growing.

The rollDice3.php program is interesting because it defies normal server-side programming behavior. In a normal PHP program, every time you refresh the browser, the program starts over from scratch. Every variable starts out new.

Understanding session variables

The rollDice3.php program acts differently. It has a mechanism for keeping track of the total rolls and number of visits to the page.

When a visitor accesses your website, she's automatically assigned a unique session id. The session id is either stored in a cookie or in the URL. Sessions allow you to keep track of things for that specific user during her time on your site and during future visits if she's not cleared her cache or deleted her cookies.

warning.eps Any mundane hacker can sniff out your session ids if you allow them to be stored in the URL. To keep this from happening, use the session. use_only_cookies directive in your PHP configuration file. This may be inconvenient to users who don't want you to have a cookie stored on their machine, but it's necessary if you're storing anything sensitive in their session.

Sessions are great because they are like a big box that the user carries around with him that you can just throw stuff into. Even if the user comes back to the site multiple times, the variables stored in the session retain their values. If you have hundreds of users accessing your site at the same time, each one will still have access to only their own versions of the variable.

tip.eps In this example I have one program that is run several times, but you can also use sessions to pass data between programs. All programs coming from the same domain have access to the same session information for each user, so you can use sessions to manage data between programs in a larger system.

Here's the code for rollDice3.php:

  {<?php
{  session_start();
{?>
{<!DOCTYPE html>
{<html lang = "en-US">
 
{  <head>
{    <meta charset = "UTF-8">
{    <title>rollDice3.php</title>
{  </head>
{  <body>
{    <h1>RollDice 3</h1>
{    <h2>Uses a Session Variable</h2>
{    <?php
{function init(){
{  global $count;
{  global $total;
{  //increment count if it exists
{  if (isset($_SESSION["count"])){
{    $count = $_SESSION["count"];
{    $count++;
{    $_SESSION["count"] = $count;
{  } else {
{    //if count doesn't exist, this is our first pass,
{    //so initialize both session variables
{    $_SESSION["count"] = 1;
{    $_SESSION["total"] = 0;
{    $count = 1;
{  } // end if
{} // end init
{function rollDie(){
{  global $total;
{  $roll = rand(1,6);
{  $image = "dado_$roll.png";
{  print <<< HERE
{    <img src = "$image"
{         alt = "roll: $roll"
{         height = "100px"
{         width = "100px" />
{HERE;
{  $total = $_SESSION["total"];
{  $total += $roll;
{  $_SESSION["total"] = $total;
{} // end rollDie
{init();
{rollDie();
{print "    <p>Rolls: $count</p> ";
{print "    <p>Total: $total</p> ";
{    ?>
{  </body>
{</html>

This program rolls a die, but it uses session variables to keep track of the number of rolls and total value rolled. The session variable is updated every time the same user (using the same browser) visits the site.

Adding session variables to your code

Here's how to incorporate sessions into your programs:

  1. Begin your code with a call to session_start().

    If you want to use session variables, your code must begin with a session_start() call, even before the DOCTYPE definition. I put a tiny <?php ?> block at the beginning of the program to enable sessions:

      <?php
      session_start();
    ?>

    warning.eps The most common error with sessions is to not begin with session_start(). Session variables use HTTP headers as part of the communication process, and any other code (even a blank line or innocent HTML code) before the session_start will cause the header to be sent without the session information. Every program that includes session variables must begin with a session_start() call.

  2. Check for the existence of the session variables.

    Like form variables, session variables may or may not exist when the program is executed. If this is the first pass through the program, the session variables may not have been created yet. The init() function checks whether the count session variable exists. If so, it will increment the counter; if not, it will initialize the sessions. $_SESSION is a superglobal array (much like $_REQUEST).

      if (isset($_SESSION["count"])){

  3. Load session variables from the $_SESSION superglobal.

    Create a local variable and extract the current value from the $_SESSION associative array:

      $count = $_SESSION["count"];

    Note that this line may trigger an error if you haven't already initialized the variable. Some PHP configurations are set up to automatically assign 0 to a nonexistent session variable, and some trigger an error.

  4. Increment the counter.

    The $count variable is now an ordinary variable, so you can add a value to it in the ordinary way:

        $count++;

  5. Store the value back into the $_SESSION superglobal.

    You can manipulate the local variable, but if you want to use the value the next time the program runs for this user, you need to store the value back into the session after you change it.

    For example, the following code loads the variable $count from the session, adds 1 to it, and stores it back into the session:

      $count = $_SESSION["count"];
    $count++;
    $_SESSION["count"] = $count;

  6. Initialize the session variables if they do not exist.

    Sometimes you need access to a session variable, but that session doesn't already exist. Usually, this will happen on the first pass of a program meant to run multiple times. It will also happen if the user jumps straight into a program without going through the appropriate prior programs (say you have got a system with three PHP programs and the user uses a bookmark to jump straight to program 3 without going to program 1, which sets up the sessions). In these situations, you'll either want to pass an error message or quietly create new session variables. In my example, I simply create a new session if it doesn't already exist. It's an easy matter of assigning values to the $_SESSION superglobal:

          //if count doesn't exist, this is our first pass,
     
        //so initialize both session variables
     
        $_SESSION["count"] = 1;
     
        $_SESSION["total"] = 0;
     
        $count = 1;

tip.eps If you want to reset your sessions for testing purposes, you can write a quick program to set the variables to 0, or you can clear the history. On most browsers, clearing all history data will also clear cookies and session data, but you may need to check additional options to ensure sessions are cleared in your browser. Note that the session data itself isn't stored in the cookie. The cookie just contains a reference number so the server can look up the session data in a file stored on the server.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset