PHP try catch block syntax - php

A very simple question from someone without much experience. The following try catch block has the section, "(Exception $e)" : is this like sql, where $e becomes an alias of Exception? If so, is this type of alias assignment used elsewhere in php, because I haven't come across it? I have searched for hours without being able to find an explanation on the web.
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "<br/>";
echo inverse(0) . "<br/>";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "<br/>";
}
echo 'Hello World';

What you mention is a filter construction. It resembles a declaration as known from other, declarative languages. However it has a different meaning in fact. Actually php does not have the concept of an explicit declaration (which is a shame...).
Take a look at this example:
function my_func($x) {
try {
/* do something */
if (1===$x)
throw new SpecialException('x is 1.');
else if (is_numeric($x)) }
throw new SpecialException('x is numeric.');
else return $x;
}
catch (SpecialException $e) {
echo "This is a special exception!";
/* do something with object $e of type SpecialException */
}
catch (Exception $e) {
echo "This is a normal exception!";
/* do something with object $e of type SpecialException */
}
}
Here it becomes clear what the construction is for: it filters out by type of exception. So the question which of several catch blocks is executed can be deligated to the type of exception having been thrown. This allows a very fine granulated exception handling, where required. Without such feature only one catch block would be legal and you'd have to implement conditional tests for potential exception types in each catch block. This feature makes the code much more readable, although it is some kind of break in the php syntax.
You don't have to, but you can create own exception classes with special behavior and, more important, accepting and carrying more information about what actually happened.

It's OO PHP. The $e is an instance of the exception object.
$e could easily be labelled anything else, so long as it's referred to thereon when you want to getmessages, etc.
For instance;
try {
echo inverse(5) . "<br/>";
echo inverse(0) . "<br/>";
} catch (Exception $oops) {
echo 'Caught exception: ', $oops->getMessage(), "<br/>";
}

Related

Exceptions in PHP

So i'm trying to learn about exceptions. And i've come accross something people often do , but dont really explain why they do it and how it works. Maybe this is something that speaks for itself but I still dont get it, I apologize if this question might come over as a bad question.
Basically this is the code I'm working with:
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
What is $e where is this variable defined. I have an idea.
What i'm thinking is that you're assigning the exception object to the variable $e but i'm not sure. Shouldnt it be catch (Exception = $e) ?
It works pretty much the same as function parameters:
function foo(Bar $bar) { ... }
You use a type hint Bar followed by the parameter name $bar, and that declares the variable.
In the case of try..catch, that declaration happens in catch:
catch (Exception $e) { ... }
This uses the type hint Exception, which here is used to specify which kinds of exceptions the catch is supposed to catch. You can limit the catch to specific kinds of exceptions and/or define multiple different catch blocks for different kinds of exceptions. The exception itself is then available in the variable $e. You can use any arbitrary variable name here, just as for function parameters.
Uhm, now that i think about it, i have always considered the Exception $e to be the input for the catch() call.
As far as i know, you are not defining $e, as it is already thrown, you are just passing it to the catch() block, as you would do with a function name($input){}
In this code
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
The keyword Exception is the type for the parameter $e.
In PHP Exception is the base exception class that all exceptions derive from so that catch block is a catch-all for all exceptions.
i.e. You might want multiple handlers for different exception types before the catch-all:
try {
someOperation($parameter);
} catch(DatabaseException $e) {
echo 'Database Exception: ' .$e->getMessage();
} catch(Exception $e) {
echo 'General Exception: ' .$e->getMessage();
}

Php selective exception handling

I have a problem where I want to catch all exception except descendants of my custom exception.
Maybe bad design, but here it is (Simplified and names changed, but the code is quite accurate):
function doStuff()
{
try {
// code
if (something) {
// manually throw an exception
throw StuffError("Something is bad.");
}
// a third-party code, can throw exceptions
LibraryClass::arcaneMagic();
} catch (Exception $e) {
throw new StuffError("Error occured while doing stuff: "
. $e->getMessage());
}
}
/** My custom exception */
class StuffError extends Exception
{
function __construct($msg) {
parent::__construct('StuffError: ' . $msg);
}
}
However, the issue here is that I don't want the try-catch to intercept the manually throws StuffError. Or, seamlessly rethrow it or something.
As it is now, I'd get:
StuffError: Error occured while doing stuff: StuffError: Something is bad.
I want just:
StuffError: Something is bad.
How would I do it?
You can have multiple catch clauses, and the first one that matches will be the one that runs. So you could have something like this:
try {
do_some_stuff();
}
catch (StuffError $e) {
throw $e;
}
catch (Exception $e) {
throw new StuffError(Error occurred while doing stuff: " . $e->getMessage());
}
But you might want to rethink wrapping stuff like this. It obscures the real cause of the error. For one thing, you lose the stack trace. But it also complicates error handling, since now someone can't differentiate exception types the way you're trying to do, short of trying to parse the exception message (which is rather an anti-pattern in itself).
I might be misinterpreting you, but I think this is what you're looking for:
...
} catch (Exception $e) {
if (get_class($e) == 'StuffError' || is_subclass_of($e, 'StuffError')) {
throw $e;
} else {
throw new StuffError("Error occured while doing stuff: "
. $e->getMessage());
}
}
...
Replace your catch statement with the code above. It checks to see if the exception is a StuffError or a child class of StuffError. I'm still very confused at why you would need to throw a StuffError exception after you catch, but maybe that's just some weirdness coming from translating/cleaning your code.

PHP exception catching and programming logic

I am trying to catch an error on object creation, because this object can and should sometimes throw an error.
try {
$obj = new MyObject();
} catch (Exception $e) {
echo 'Caught exception: ';
}
I want to do a lot of things with this new object, but only IF it was created without throwing an exception.
The problem is that I do not wish to do all these things inside the try catch block. How would I accomplish this?
Thanks a lot
Michael
I really can't see any reason for what you are asking, but maybe the best thing is to do all the other stuff in a function that you call from the try/catch block...
function allMyStuff($obj){
// do some stuff to $obj here
}
try {
$obj = new MyObject();
allMyStuff($obj);
} catch (Exception $e) {
echo 'Caught exception: ';
}
Otherwise, to do literally as you seem to be asking, you could set a switch before the try/catch block to on, and set it to off in the catch block. That way you can test the switch to see whether to execute all your other stuff.
$mySwitch = true;
try {
$obj = new MyObject();
} catch (Exception $e) {
echo 'Caught exception: ';
$mySwitch = false;
}
if($mySwitch){
// do some stuff here
}
There's no point in doing it outside. It also makes more sense to do all of your actions inside the try/catch block to test it for errors.
You should keep it inside the try/catch block as it is exactly what it was designed for.
Slightly odd - but you could either die or redirect...
try {
$obj = new MyObject();
} catch (Exception $e) {
die("Caught exception: {$e->getMessage()}");
}
//program continues as it hasn't "died"
or...
try {
$obj = new MyObject();
} catch (Exception $e) {
header("Location:/exceptionHandler.php?e=" . rawurlencode(serialize($e)));
die();
}
//program continues as it's not been redirected or "died"
... though as everyone else has said - it probably still makes more sense to wrap the whole kaboodle in a try ... catch block.

Simple Exception sample - PHP

I am trying to understand what the best approach would be to handle Exceptions in the following scenario:
I have a class employee:
class employee extends person {
private $salary;
private $baseSalary = 6.5;
function __construct($f, $m, $l, $a,$fsalary=0){
if(!is_numeric($fsalary)){
throw new Exception("Age supplied is not a number", 114);
}
parent::__construct($f, $m, $l, $a);
$this->salary=$fsalary;
}
function GetDetails(){
return parent::GetName().
"<br/>".
$this->salary;
}
function __toString(){
return $this->GetDetails();
}
}
And using this:
try{
if(!$f = new employee("Sarah", "Sebastian", "Pira", "abc")){
throw new Exception();
}
else {
echo $f;
}
}
catch (Exception $e){
echo "<br/>";
echo var_dump($e);
}
Now I would think it would be a good idea to throw an exception in the class and then use just one catch block in all the scripts that would be using an employee object - But this doesn't seem to work - I need to have a try catch block within the class - Is this the correct way of looking at this?
Thanks
I think what you're saying is that you want to do something like this:
try {
class Employee extends Person {
// ...blah blah...
}
}
catch(Exception $e) {
// handle exception
}
...and then be able to insantiate it in other classes, without explicitly catching any exceptions:
// try { << this would be removed
$employee = new Employee();
// }
// catch(Exception $e) {
// (a whole bunch of code to handle the exception here)
// }
You can't do that, because then the try/catch block in the class will only catch any exceptions that occur when defining the class. They won't be caught when you try to instantiate it because your new Employee line is outside the try/catch block.
So really, your problem is that you want to be able to re-use a try/catch block in multiple places without re-writing the code. In that case, your best solution is to move the contents of the catch block out to a separate function that you can call as necessary. Define the function in the Employee class file and call it like this:
try {
$employee = new Employee();
$employee->doSomeStuff();
$employee->doMoreStuffThatCouldThrowExceptions();
}
catch(Exception $e) {
handle_employee_exception($e);
}
It doesn't get rid of the try/catch block in every file, but it does mean that you don't have to duplicate the implementation of the exception-handling all the time. And don't define handle_employee_exception as an instance method of the class, do it as a separate function, otherwise it will cause a fatal error if the exception is thrown in the constructor because the variable won't exist.
You should read more about Exceptions in PHP.
You can handle exceptions within the methods of the class, sure. But you should rethink how you want to do this and... why.
Good practice is also creating own exception class, so you are able to distinguish exceptions thrown by your module / class from the exceptions thrown by something else. It looks like that (see more):
class EmployeeModule_Exception extends Exception {}
and when it comes to throwing exception:
// the second parameter below is error code
throw new EmployeeModule_Exception('some message', 123);
Catching is similar, only the below example will catch only your module's exceptions:
try {
// some code here
} catch (EmployeeModule_Exception $e) {
// display information about exception caught
echo 'Error message: ' . $e->getMessage() . '<br />';
echo 'Error code: ' . $e->getCode();
}

What is the PHP equivalent to Python's Try: ... Except:

I am a strong Python programmer, but not quite there when it comes to PHP. I need to try something, and if that doesn't work out, do something else.
This is what it would look like in Python:
try:
print "stuf"
except:
print "something else"
What would this be in PHP?
http://php.net/manual/en/language.exceptions.php
try {
print 'stuff';
} catch (Exception $e) {
var_dump($e);
}
Note: this only works for exceptions, not errors.
See http://www.php.net/manual/en/function.set-error-handler.php for that.
try {
// do stuff ...
} catch (Exception $e) {
print($e->getMessage());
}
See http://php.net/manual/en/language.exceptions.php
PHP does not natively support error catching like Python does, unless you override the default behavior and set your own error handler. PHP's try - catch was only recently added to the language in version 5, and it can only catch exceptions you explicitly throw.
So basically, PHP distinguishes between errors and exceptions. Errors haven't been modularized and made available to the user like they have been in Python. I believe that's related to the fact that PHP began as a collection of dynamic web scripts, grew and gained more features over time, and only more recently offered improved OOP support (i.e., version 5); whereas Python fundamentally supports OOP and other meta-functionality. And exception handling from the beginning.
Here's an example usage (again, a throw is necessary, or else nothing will be caught):
function oops($a)
{
if (!$a) {
throw new Exception('empty variable');
}
return "oops, $a";
}
try {
print oops($b);
} catch (Exception $e) {
print "Error occurred: " . $e->getMessage();
}
You can handle PHP errors like they were exceptions by using set_error_handler
In this error handler function you can throw various exception, according to error level for instance.
By doing this you can treat any error (including programming errors) in a common way.
PHP 5 has the exception model:
try {
print 'stuff';
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
Assuming you're trying to catch exceptions, take a look at http://php.net/manual/en/language.exceptions.php
You could try something like
try {
echo "Stuff";
} catch (Exception $e) {
echo "Something Else";
}

Categories