I have
$test = 'SomeClass';
$ins = new $test;
I want to be able to catch the error if the name for $test doesn't exist.
I'm not sure what type of exception it threw as PHP didn't gave me anything.
Use class_exists().
Check first like this:
if(class_exists($test)){
$ins = new $test;
}else{
die("Could not load class'" . $test ."'");
}
Such a construction won't let you catch any errors unless you use some error handler. However you can check whether class exists or not using class_exists() function.
PS. You should use reflection as it is much more verbose and clear. Also it uses exceptions so you can do something like:
try {
$ref = new \ReflectionClass($className);
} catch (\LogicException $le) {
// class probably doesn't exist
}
With PHP 5.3 (or greater), you can catch exceptions thrown from __autoload
function __autoload($name) {
// if class doesn't exist:
throw new Exception("Class $name not found");
// else, load class source
}
$test = 'SomeClass';
try {
$ins = new $test;
} catch (Exception $e) {
}
first, you must test if $test class exists.
http://php.net/manual/en/function.class-exists.php
Related
I currently have the following PHP which uses a try/catch block checking for exceptions.
try {
$obj->login('User', 'Pass');
$obj->joinServer('Server');
} catch(ConnectionException $objException){
die();
}
...and this is the ConnectionException class:
class ConnectionException extends Exception {
public function __construct($strError, $intError, $mixOther = null){
$this->strError = $strError;
$this->intError = $intError;
echo $this->intError, ' - ', $this->strError, chr(10);
}
}
Now let's say if the "catch" part returns a specific error (if ConnectionException outputs a specific message), how can I "retry" the try/catch again?
I guess you can nest the try/catch, wrap it the code into a function to avoid code repetition:
function login($obj){
$obj->login('User', 'Pass');
$obj->joinServer('Server');
}
try {
login($obj);
} catch(ConnectionException $objException){
try {
login($obj);
} catch(ConnectionException $objException){
die();
}
}
If you want to do this at this level, instead of having it throw a ConnectionException every time, throw a different exception that's a subclass of ConnectionException that signifies when you would want to rerun the logic. Then, encapsulate the logic that you have within the try to a function, and call it again.
try {
doWork( $obj);
} catch( ConnectionTimeoutException $e) {
// Wait a bit, then retry
try {
sleep(10);
doWork( $obj);
} catch( ConnectionException $e) {
// Because of the subclass, this would catch both ConnectionException and ConnectionTimeoutException
die();
}
} catch( ConnectionException $e) {
die();
}
You can also change how you're calling this function, and call it twice depending on the result of ConnectionException. Although, in that manner, it may make more sense to base this decision on a return value instead of an Exception.
My suggestion would be to create a simple while loop that checks for a condition:
try_connection = true;
while(try_connection) {
try {
$obj->login('User', 'Pass');
$obj->joinServer('Server');
} catch(ConnectionException $objException){
if(!specific_message)
try_connection = false;
}
}
The following try..catch is meant to run a method if it exists and run a different method if it doesn't..
$heading = new HeadingMan();
try {
if (!is_callable($heading->{$this->breadcrumbs->getCrumb(3)}())) {
throw new Exception ('<b>Error - HeadingMan class can not handle: </b>' . $this->breadcrumbs->getCrumb(3));
}
$heading->{$this->breadcrumbs->getCrumb(3)};
}
catch (Exception $e) {
$heading->latest();
}
However, the catch statement always triggers, and throws a new exception (runs the catch portion of the statement).
How do I check a method exists in a class by using a series of function calls
$this->breadcrumbs->getCrumb(3);
to get the name of the function.?
$bool = method_exists($class,$method);
http://php.net/manual/en/function.method-exists.php
How do I know if there's an error if I did $db = new SQLite3("somedb.db"); in PHP? Right now the $db doesn't really give me any sort of error?
I can check for file existance, but I'm unsure if there could be any other errors when I open a connection.
You should enable exceptions and instantiate in a try-catch block.
It is not obvious from the documentation but if you use the constructor to open the database it will throw an exception on error.
Further if you set the flag SQLITE3_OPEN_READWRITE in the second argument then it will also throw an exception when the database does not exist (rather than creating it).
class Database extends SQLite3
{
function __construct($dbName)
{
$this->enableExceptions(true);
try
{
parent::__construct($dbName, SQLITE3_OPEN_READWRITE );
}
catch(Exception $ex) { die( $ex->getMessage() ); }
}
Try:
echo $db->lastErrorMsg();
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();
}
Everyone here should know the 'or' statemens, usually glued to an die() command:
$foo = bar() or die('Error: bar function return false.');
The most of the times we see something like:
mysql_query('SELECT ...') or die('Error in during the query');
However, i cant understand how exactly that 'or' statement works.
I would like to throw a new exception instead of die(), but:
try{
$foo = bar() or throw new Exception('We have a problem here');
Doesnt work, and neither
$foo = bar() or function(){ throw new Exception('We have a problem here'); }
The only way i found to do that is this horrible thought:
function ThrowMe($mess, $code){
throw new Exception($mess, $code);
}
try{
$foo = bar() or ThrowMe('We have a problem in here', 666);
}catch(Exception $e){
echo $e->getMessage();
}
But there is a way to throw a new exception directly after the 'or' statement?
Or this kind of structure is mandatory (i dont liek the ThrowMe function at all):
try{
$foo = bar();
if(!$foo){
throw new Exception('We have a problem in here');
}
}catch(Exception $e){
echo $e->getMessage();
}
Edit: what i want is really to avoid the use of an if() check every potential dangerous operation i do, for example:
#The echo $e->getMessage(); is just an example, in real life this have no sense!
try{
$foo = bar();
if(!$foo){
throw new Exception('Problems with bar()');
}
$aa = bb($foo);
if(!$aa){
throw new Exception('Problems with bb()');
}
//...and so on!
}catch(Exception $e){
echo $e->getMessage();
}
#But i relly prefer to use something like:
try{
$foo = bar() or throw new Exception('Problems with bar()');
$aa = bb($foo) or throw new Exception('Problems with bb()');
//...and so on!
}catch(Exception $e){
echo $e->getMessage();
}
#Actually, the only way i figured out is:
try{
$foo = bar() or throw new ThrowMe('Problems with bar()', 1);
$aa = bb($foo) or throw new ThrowMe('Problems with bb()', 2);
//...and so on!
}catch(Exception $e){
echo $e->getMessage();
}
#But i'll love to thro the exception directly instead of trick it with ThrowMe function.
or is just a logical operator, and it's analogous to ||.
The common trick of
mysql_query() or die();
could just as well be written
mysql_query() || die();
What happens here is the "logical or" operator (whichever you choose) is trying to determine if either operand evaluates to TRUE. This means the operands must be expressions that can be cast as a boolean.
So, the reason
bar() or throw new Exception();
is illegal, is because
(boolean)throw new Exception();
is also illegal. In essence, the process of throwing an exception doesn't generate a return value for the operator to check.
But calling a function does generate a return value for the operator to check (no explicit return value will result int the function returning NULL which casts as FALSE) which is why it works for you when you wrap exception throwing in a function.
I've simply defined the function toss for this.
function toss(Exception $exception): void
{
throw $exception;
}
Because the file/line/stack information is captured when the exception is constructed (new) not thrown (throw) this doesn't interfere with the call stack.
So you can just do this.
something() or toss(new Exception('something failed'));
Why don't bar() and bb() throw the exceptions? In PHP Exceptions bubble up, so there's no need to throw the exception in the function/method where you call bar()/bb(). These exceptions may be thrown by bar()/bb(). In case you want to throw another exception, you can simply do:
function foo() {
try {
$bar = bar();
} catch (BarException) {
throw new FooException;
}
}
A solution I found that can replace "or die()" everywhere is to wrap the throw with a anonymous function that gets called immediately by call_user_func:
call_user_func(function(){
throw new Exception("ERROR");
});
You can see that it works by executing this on a dummy script:
false or call_user_func(function(){throw new Exception("ERROR");});
I think you want to use something like the last structure, although there's really no point in using exceptions for that:
$foo = bar();
if(!$foo){
echo 'We have a problem in here';
}
Per comment - I don't think you can do that in a single line (i.e. without the if(!$foo) check), and I agree that the exception throwing method is pretty horrible. Personally, I prefer the explicitness of:
$foo = bar();
if(!$foo){
throw new Exception('We have a problem in here');
}
but that's a personal preference. If you want the single-line thing, I think you'll have to go with your exception-throwing function option.
I guess this limitation is probably down to PHP's dynamic-typing stuff, it can cast the results of a function call to a conditional, but not the results of a throw.
Here's a single-line solution without the extra function:
if (!($foo = bar())) throw new Exception('We have a problem here');
You can also create a custom exception class and use it's static constructor method instead of throw new Exception() construction.
Exception class:
class CustomException extends Exception {
static public function doThrow($message = "", $code = 0, Exception $previous = null) {
throw new Exception($message, $code, $previous);
}
}
Usage:
try {
$foo = bar() or CustomException::doThrow('Problems with bar()');
$aa = bb($foo) or CustomException::doThrow('Problems with bb()');
} catch(Exception $e){
echo $e->getMessage();
}
Note
If you are using PHP 7 and higher - you can rename static method doThrow() to simply throw(), since in PHP 7 and higher it's allowed to use reserved keywords as method names.