views:

116

answers:

3

Note: I am using output buffering. It's just wrapped in the head() and foot() functions.

I create pages in my current PHP project by using the following template:

<?php
include 'bootstrap.php';
head();
?>

<!-- Page content here -->

<?php
foot();
?>

Is the following example an appropriate use of die()? Also, what sort of problems might this cause for me, if any?

<?php
include 'bootstrap.php';
head();

try
{
    //Simulate throwing an exception from some class
    throw new Exception('Something went wrong!');
}
catch(Exception $e)
{
    ?>
    <p>Please fix the following error:</p>
    <p><?php echo $e->getMessage(); ?></p>
    <?php
    foot();
    die();
}

//If no exception is thrown above, continue script
doSomething();
doSomeOtherThing();

foot();
?>

Basically, I have a script with multiple tasks on it and I am trying to set up a graceful way to notify the user of input errors while preventing the remaining portion of the script from executing.

Thanks!

+4  A: 

I'd do this:

head();
try {
    somethingPossiblyWithError();
    somethingElse();
} catch (Exception $e) {
    handleError();
}
foot();

No deaths necessary. If an error is raised in somethingPossiblyWithError, then somethingElse will get skipped. foot will get executed in both cases.

UPDATE: I upvoted Col. Shrapnel's answer, since I guess you did not think about that, and that is a valuable piece of knowledge. In PHP, you can get an equivalent functionality by output buffering, without explicitly passing values around, but it's not as pretty - however, it works if you are calling functions which will print things and not return them as values, so sometimes it's useful to know.

Amadan
@Amadan - Thanks for the example. I did not think that was possible, but it is obviously a nice way to avoid using die().
letseatfood
+3  A: 

The whole page structure is wrong.
Though it's most widespread newbie mistake.

One should never output a thing before having all data ready.
Your script may send some HTTP headers, may set up some variables for use in the header() or anything.

Therefore, template use is necessary.
You have to divide your script into 2 parts - getting data part and displaying data part.
So, you have to move header() function much lower.
And based on the Amadan's answer it could be

<?php
include 'bootstrap.php';
try {
  getData();
} catch (Exception $e) {
    handleError();
}
head();
body();
foot();
?>

handleError() function may set appropriate HTTP error code (404 or 500) and substitute body template with error message text.

Col. Shrapnel
Output bufferization is here for that. Sometimes the data you want is what your script has already tried to send. But yeah, better separate data handling from output so you don't have a mess of html (or whatever templating system you use) in the middle of php code.
Arkh
@Arkh no, output buffering won't help you to set page's title with a variable.
Col. Shrapnel
Hey @Col thanks for your response. I have to partially disagree, though. The "whole" page structure is not wrong. I get most of my data via the bootstrap.php include (at the start of the script). I begin output buffering inside of the head(), which seems to make sense to me b/c there is no chance of output prior, and it allows for variables to be passed to the head() function. Output buffering ends within the foot() function. Now, I completely agree with you about the middle portion of the script (between head() and foot()). I need to refactor to allow for data retrieval before view. Thanks!
letseatfood
Would like to know your thoughts
letseatfood
@letseatfood Most data gathering in the bootstrap is a nonsense and buffering won't let you apply a variable. just get more experience and you will see. I don't feel explain obvious things.
Col. Shrapnel
@Col - Yeah you're right about ob. I meant to say that just having the head() function allows me to pass variables to it since I can create the variables before calling the function. I use bootstrap to load variables that I use a lot. Nonsense? That could use some explanation. And thanks a lot for not following through with your explanation, which isn't obvious to me.
letseatfood
@Col Although now your example is making sense to me. I have been working on so many projects for the past month that I haven't had time to pause and look back over some things.
letseatfood
+1  A: 

Your approach is not recommended for many reasons. You should:

  • separate the presentation and the logic (take a look at MVC pattern)
  • avoid procedural code, write object oriented PHP
  • separate user and admin experience (handle errors gently)

Example, implementing above:

<? $page->debug = true; ?>
<?= $page->getHead(); ?>
<?= $page->getBody(); ?>
<?= $page->getFoot(); ?>

class page {

   public debug;

   public function getBody() {
       try {
          //
       } catch (Exception $e) {
          $this->_errorhandler('message');
       }
   }

   protected function _errorhandler($message) {
        if ($this->debug) {
              // display error message
          } else {
             // display nothing, log the error
             // or throw concrete exception
             // or redirect
          }
   }
 ...
}

This is not recommended too (there are many separate classes needed for each task), but you see the point: separating, not mixing everything.

takeshin
Do not suggest short open tags
kemp
Thanks @takeshin
letseatfood