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!
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.
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.
Your approach is not recommended for many reasons. You should:
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.