Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

developerWorks Community:

  • Close [x]

Learning PHP, Part 3: Authentication, objects, exceptions, and streaming

Nicholas Chase is the founder and creator of NoTooMi. In addition to technical writing for large corporations, he has been involved in website development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. He has been a high school physics teacher, a low-level-radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, an Oracle instructor, and the chief technology officer of an interactive communications company. He is the author of several books, including XML Primer Plus (Sams 2002).

Summary:  This tutorial is Part 3 of a three-part "Learning PHP" series teaching you how to use PHP through building a simple workflow application. In this tutorial, you will learn about using HTTP authentication, streaming files, and how to create objects and exceptions.

03 Jan 2013 - Nicholas Chase updated content throughout this tutorial to reflect current PHP technology.

View more content in this series

Date:  03 Jan 2013 (Published 12 Jul 2005)
Level:  Intermediate PDF:  A4 and Letter (792 KB | 36 pages)Get Adobe® Reader®

Comments:  

Handling exceptions

An exception is what happens when something unexpected occurs in a program. When an exception occurs, a program is frequently designed to stop or display errors. Because exceptions come into play when something is not quite right with an application, they are often confused with errors. Exceptions are, however, much more flexible. In this section, you'll see how to define different types of exceptions and use them to determine what's going on with the application.

A generic exception

Let's start with a simple generic exception in the definition of the WFDocument class (see Listing 23).


Listing 23. Throwing an exception
<?php

include_once("../scripts.txt");

class WFDocument {
...
   function download() {

      $filepath = UPLOADEDFILES.$this->filename;

         try {

         if(file_exists($filepath)){
              if ($stream = fopen($filepath, "rb")){
                 $file_contents = stream_get_contents($stream);
                 header("Content-type: ".$this->filetype);
                 print($file_contents);
              }
             } else {
           throw new Exception ("File '".$filepath."' does not exist.");
         }

      } catch (Exception $e) {

         echo "<p style='color: red'>".$e->getMessage()."</p>";

      }
   }
}

?>

Exceptions don't just happen, they are thrown. If you throw something, you have to catch it, so you create a try-catch statement. In the try section, you put your code. If something untoward happens, such as, in this case, a file doesn't exist, and you throw an exception, PHP moves immediately to the catch block to catch the exception.

An exception has many properties, such as the line and file from which the exception was thrown, and a message. Typically, the application sets the message when it throws the exception, as you see here. The exception itself, $e, can then provide that text using the getMessage() method. For example, if you try to download a file that doesn't exist, you'll see the message File 'c:/sw/temp/NoTooMiLogoQWSQ.png' does not exist. (see Figure 9).


Figure 9. The basic exception
Screen capture of the basic exception message

The real power of exceptions, though, comes from creating your own.


Creating a custom exception

In the last section, you examined objects, but I left out one very important aspect of them: inheritance.

One advantage to using classes is the ability to use one class as the basis for another. For example, you can create a new exception type, NoFileExistsException, which extends the original Exception class (see Listing 24).


Listing 24. Creating a custom exception
class NoFileExistsException extends Exception {

   public function informativeMessage(){
      $message = "The file, '".$this->getMessage()."', called on line ".
           $this->getLine()." of ".$this->getFile().", does not exist.";
      return $message;
   }

}

(For simplicity's sake, I added this code to the WFDocument.php file, but you can add it wherever it's accessible when you need it.)

Here, you created a new class, NoFileExistsException, with a single method: informativeMessage(). In actuality, this class is also an Exception, so all the public methods and properties for an Exception object are also available.

For example, notice that within the informativeMessage() function, you call the getLine() and getFile() methods, even though they're not defined here. They're defined in the base class, Exception, so you can use them.

Now let's see it in action.


Catching a custom exception

The easiest way to use the new exception type is to simply throw it just as you would throw a generic Exception (see Listing 25).


Listing 25. Throwing and catching a custom exception
    function download() {

      $filepath = UPLOADEDFILES.$this->filename;

      try {

         if(file_exists($filepath)){
           if ($stream = fopen($filepath, "rb")){
              $file_contents = stream_get_contents($stream);
              header("Content-type: ".$this->filetype);
              print($file_contents);
           } 
         } else {
           throw new NoFileExistsException ($filepath);
         }

      } catch (NoFileExistsException $e) {

         echo "<p style='color: red'>".$e->informativeMessage()."</p>";

      }
   }

Notice that even though you pass only the $filepath when you create the exception, the full message is returned: The file, 'c:/sw/temp/NoTooMiLogoQWSQ.png', called on line 41 of C;\sw\xampp\htdocs\WFDocument.php, does not exist. (see Figure 10).


Figure 10. Using a custom exception
Screen capture of using a custom exception

Working with multiple exceptions

One reason to create custom exception classes is so you can use PHP's ability to distinguish between them. For example, you can create multiple catch blocks for a single try (see Listing 26).


Listing 26. Distinguishing between exceptions
...
   function download() {

      $filepath = UPLOADEDFILES.$this->filename;

      try {

         if(file_exists($filepath)){
           if ($stream = fopen($filepath, "rb")){
              $file_contents = stream_get_contents($stream);
              header("Content-type: ".$this->filetype);
              print($file_contents);
           } else {
              throw new Exception ("Cannot open file ".$filepath);
           }
         } else {
           throw new NoFileExistsException ($filepath);
         }

      } catch (NoFileExistsException $e) {

         echo "<p style='color: red'>".$e->informativeMessage()."</p>";

      } catch (Exception $e){

         echo "<p style='color: red'>".$e->getMessage()."</p>";
      }
   }
}

In this case, you attempt to catch problems before they happen by checking for the existence of the file and throwing a NoFileExistsException. If you get past that hurdle and something else keeps you from opening the file, you throw a generic exception. PHP detects which type of exception you throw and executes the appropriate catch block.

All of this might seem a little overboard for simply outputting messages, but there's nothing that says that's all you can do. You can create custom methods for your exception that, for example, send notifications for particular events. You can also create custom catch blocks that perform different actions depending on the situation.

You can also use exceptions to trap for situations that technically are errors, but shouldn't actually stop your program. For example, you might attempt to process an image, and if it's not successful, leave it as it is and move on rather than exiting.

Just because you defined all these different exceptions doesn't mean you have to catch each one individually, as you'll see next.


Propagating exceptions

Another handy feature of inheritance is the ability to treat an object as though it were a member of its base class. For example, you can throw a NoFileExistsException and catch it as a generic Exception (see Listing 27).


Listing 27. Combining exception catching
...
   function download() {

      $filepath = UPLOADEDFILES.$this->filename;

      try {

         if(file_exists($filepath)){
           if ($stream = fopen($filepath, "rb")){
              $file_contents = stream_get_contents($stream);
              header("Content-type: ".$this->filetype);
              print($file_contents);
           } else {
              throw new Exception ("Cannot open file ".$filepath);
           }
         } else {
           throw new NoFileExistsException ($filepath);
         }

      } catch (Exception $e){

         echo "<p style='color: red'>".$e->getMessage()."</p>";
      }
   }
}

In this case, when you throw the exception, PHP works its way down the list of catch blocks, looking for the first one that applies. Here you have only one, but it will catch anyException, as you can see by the File 'c:/sw/temp/NoTooMiLogoQWSQ.png' does not exist. message in Figure 11.


Figure 11. Propagating exceptions
Screen capture of propagating exceptions

6 of 11 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Linux, XML
ArticleID=133669
TutorialTitle=Learning PHP, Part 3: Authentication, objects, exceptions, and streaming
publish-date=01032013
author1-email=ibmquestions@nicholaschase.com
author1-email-cc=