I have require statements for my header and footer:
<?php
require "assets/php/header.php";
// Script goes here.
require "assets/php/footer.php";
?>
If I have a script in between the two statements, how can I have a die() statement in the script to end the current script, but still show the footer? If there is no way of doing this, is there any alternatives? I personally think that the require statements are obsolete, and I would love to know of some alternatives, or just a better way of setting it up. Thanks in advance.
You should use exception.
Try something like this :
<?php
try {
require "assets/php/header.php";
// Script goes here.
// replace "die();" with :
throw new Exception("I want to die");
// folowing code executed if no exception is thrown
require "assets/php/footer.php";
// end of "normal" case
} catch (Exception $e) {
// an exception makes footer and then dies
require "assets/php/footer.php";
die();
}
?>
you can also use this catch if you use Exception that mustn't trigger footer :
} catch (Exception $e) {
if($e->getMessage() == "I want to die") {
// an exception asks to make footer and then dies
require "assets/php/footer.php";
die();
} else {
throw $e;
}
}
Or if you want to make it clean, make a new exception class (for instance DieWithFooterException) and use it like this :
<?php
try {
require "assets/php/header.php";
// Script goes here.
// replace "die();" with :
throw new DieWithFooterException();
// folowing code executed if no exception is thrown
require "assets/php/footer.php";
// end of "normal" case
} catch (DieWithFooterException $dwfe) {
// an exception asks to make footer and then dies
require "assets/php/footer.php";
die();
} catch (Exception $e) {
// stuff to do with other excpetions
}
?>
This said, the last solution is the nicer way to do it :)
Related
I have a number of files that are included (with "include_once") in my code and I want to control exceptions at the top level of my "index" file.
But, try/catch statements do not capture exceptions generated in an included file. For instance, an exception in my children files will be unhandled.
Can anyone please point me in the right direction?
index.php:
try
{
include_once( "child.php" );
}
catch(Exception $e)
{
// do something....
}
child.php
throw new Exception ("error!");
Try this :
index.php
<?php
try
{
include_once( "child.php" );
} catch(Exception $e) {
echo $e->getMessage();
}
child.php
<?php
throw new Exception ("error!");
I perfectly understand the nuances of the (try/throw/catch) block.
What I don't understand is:
If we gonna use an IF (or any control structure) inside our try block anyway in order to test if a condition is met, only then, 'throw' an exception if the results of that test is false, then... in my opinion: throw/generate an exception is useles; because if a condition is not met, we can simply print an error message, call a function, instantiate a class, redirect to another location, etc.
Another story would be, if for instance, a variable was not initialized, we enclose that variable inside a try{} block, echo the variable, and from that point onward, everything will be handle by the catch() block because the try block raises an error; and since the try/catch blocks talk each other, the catch block will catch every error that was originated from his corresponding try block. However, you can set a custom error message inside yout try block (optional).
What I've read so far:
every results from searching: if vs. try
I do see the difference.
But I can not understand why some people choose try/throw/catch over if...else...switch...while... etc.
As far I can see, try/throw/catch can be used for debugging, though.
One benefit of exceptions over if/then is that you can wrap try/catch around a large block of code. It will be triggered if an error happens anywhere in the block.
try {
$db = db_open();
$statement = $db->prepare($sql);
$result = $statement->execute($params);
} catch (Exception $e) {
die($e->getMessage());
}
With if/then, you would have to perform a test at each step.
$db = db_open();
if (!$db) {
die(db_connect_error());
}
$statement = $db->prepare($sql);
if (!$statement) {
die(db_error($db));
}
$result = $statement->execute($params);
if (!$result) {
die(db_error($db));
}
As you said, it's a lot of overhead to throw an exception inside a try/catch block and catch it immediately.
try {
if (...) {
// good, do no throw
} else {
throw new Exception();
}
} catch ($e) {
// handle exception
}
This should be replaced by:
if (...) {
// good
} else {
// handle error, no exception
}
Exceptions are useful because they bubble up. So imagine if you have this code instead:
function bla() {
try {
tryToDoSomething();
} catch ($e) {
// handle error
}
}
function tryToDoSomething() {
if ($somethingNotAvailable) {
throw new Exception();
}
doSomething();
}
In this case, the function that defines the try/catch is NOT the one throwing the exception. tryToDoSomething() does not know how to handle the errors so it will let parent methods to take care of it. The exception can bubble up the call stack until someone catches it and handles the error. That's how exceptions can actually be useful :)
I am trying to catch an error with php when I connect to DB
I have something like
try{
//connect to DB
}catch(exception $e){
echo $e
}
//other php codes...
//My html elements...
<div>....
My problem is that I want to skip //other phpo codes if we have error connecting to DB and straight to show my html elements. Is that possible to do it? Thanks a lot.
Just out that code in your try/catch. Once the exception is thrown execution is handed off to the catch portion of the control structure and that portion of code is never reached:
try{
//connect to DB
// If an exception is throw above we never get here
//other php codes...
}catch(exception $e){
echo $e
}
//My html elements...
<div>....
If you don't want to move the // other php code
And you don't want/can't edit the try/catch block, surely the try/catch returns some variable you can test, even if only that $e.
try {
// something like $connected_db should be available
}
catch (exception $e)
{
}
if (!empty($connected_db) AND empty($e)) // one or the other depending on the code above
{
// other php code
}
// my html elements
Consider these two examples
<?php
function throw_exception() {
// Arbitrary code here
throw new Exception('Hello, Joe!');
}
function some_code() {
// Arbitrary code here
}
try {
throw_exception();
} catch (Exception $e) {
echo $e->getMessage();
}
some_code();
// More arbitrary code
?>
and
<?php
function throw_exception() {
// Arbitrary code here
throw new Exception('Hello, Joe!');
}
function some_code() {
// Arbitrary code here
}
try {
throw_exception();
} catch (Exception $e) {
echo $e->getMessage();
} finally {
some_code();
}
// More arbitrary code
?>
What's the difference? Is there a situation where the first example wouldn't execute some_code(), but the second would? Am I missing the point entirely?
If you catch Exception (any exception) the two code samples are equivalent. But if you only handle some specific exception type in your class block and another kind of exception occurs, then some_code(); will only be executed if you have a finally block.
try {
throw_exception();
} catch (ExceptionTypeA $e) {
echo $e->getMessage();
}
some_code(); // Will not execute if throw_exception throws an ExceptionTypeB
but:
try {
throw_exception();
} catch (ExceptionTypeA $e) {
echo $e->getMessage();
} finally {
some_code(); // Will be execute even if throw_exception throws an ExceptionTypeB
}
fianlly block is used when you want a piece of code to execute regardless of whether an exception occurred or not...
Check out Example 2 on this page :
PHP manual
Finally will trigger even if no exception were caught.
Try this code to see why:
<?php
class Exep1 extends Exception {}
class Exep2 extends Exception {}
try {
echo 'try ';
throw new Exep1();
} catch ( Exep2 $e)
{
echo ' catch ';
} finally {
echo ' finally ';
}
echo 'aftermath';
?>
the output will be
try finally
Fatal error: Uncaught exception 'Exep1' in /tmp/execpad-70360fffa35e/source-70360fffa35e:7
Stack trace:
#0 {main}
thrown in /tmp/execpad-70360fffa35e/source-70360fffa35e on line 7
here is fiddle for you. https://eval.in/933947
From the PHP manual:
In PHP 5.5 and later, a finally block may also be specified after or instead of catch blocks. Code within the finally block will always be executed after the try and catch blocks, regardless of whether an exception has been thrown, and before normal execution resumes.
See this example in the manual, to see how it works.
http://www.youtube.com/watch?v=EWj60p8esD0
Watch from: 12:30 onwards
Watch this video.
The language is JAVA though.
But i think it illustrates Exceptions and the use of finally keyword very well.
This question is about the best way to execute code outside of try block only if no exception is thrown.
try {
//experiment
//can't put code after experiment because I don't want a possible exception from this code to be caught by the following catch. It needs to bubble.
} catch(Exception $explosion) {
//contain the blast
} finally {
//cleanup
//this is not the answer since it executes even if an exception occured
//finally will be available in php 5.5
} else {
//code to be executed only if no exception was thrown
//but no try ... else block exists in php
}
This is method suggested by #webbiedave in response to the question php try .. else. I find it unsatisfactory because of the use of the extra $caught variable.
$caught = false;
try {
// something
} catch (Exception $e) {
$caught = true;
}
if (!$caught) {
}
So what is a better (or the best) way to accomplish this without the need for an extra variable?
One possibility is to put the try block in a method, and return false if an exception is cought.
function myFunction() {
try {
// Code that throws an exception
} catch(Exception $e) {
return false;
}
return true;
}
Have your catch block exit the function or (re)throw/throw an exception. You can filter your exceptions as well. So if your other code also throws an exception you can catch that and (re)throw it. Remember that:
Execution continues if no exception is caught.
If an exception happens and is caught and not (re)throw or a new one throw.
You don't exit your function from the catch block.
It's always a good idea to (re)throw any exception that you don't handle.
We should always be explicit in our exception handling. Meaning if you catch exceptions check the error that we can handle anything else should be (re)throw(n)
The way I would handle your situation would be to (re)throw the exception from the second statement.
try {
$this->throwExceptionA();
$this->throwExceptionB();
} catch (Exception $e) {
if($e->getMessage() == "ExceptionA Message") {
//Do handle code
} elseif($e->getMessage() == "ExceptionB Message") {
//Do other clean-up
throw $e;
} else {
//We should always do this or we will create bugs that elude us because
//we are catching exception that we are not handling
throw $e;
}
}