Asked  7 Months ago    Answers:  5   Viewed   34 times

I'm using the following script to use a database using PHP:

try{
    $db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options);
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

Now, I want to use this database handle to do a request using this code:

try{
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

Here is the problem:

  • When the connection to the DB is OK, everything works,
  • When the connection fails but I don't use the DB, I have the $GLOBALS['errors'][] array and the script is still running afterwards,
  • When the connection to the DB has failed, I get the following fatal error:

Notice: Undefined variable: db in C:xampphtdocs[...]test.php on line 32

Fatal error: Call to a member function prepare() on a non-object in C:xampphtdocs[...]test.php on line 32

Note: Line 32 is the $query = $db->prepare(...) instruction.

That is to say, the script crashes, and the try/catch seems to be useless. Do you know why this second try/catch don't works and how to solve it?

Thanks for the help!

EDIT: There are some really good replies. I've validated one which is not exactly what I wanted to do, but which is probably the best approach.

 Answers

55

try/catch blocks only work for thrown exceptions (throw Exception or a subclass of Exception must be called). You cannot catch fatal errors using try/catch.

If your DB connection cannot be established, I would consider it fatal since you probably need your DB to do anything meaningful on the page.

PDO will throw an exception if the connection cannot be established. Your specific problem is that $db is not defined when you try to call a method with it so you get a null pointer (sort of) which is fatal. Rather than jump through if ($db == null) hoops as others are suggesting, you should just fix your code to make sure that $db is either always defined when you need it or have a less fragile way of making sure a DB connection is available in the code that uses it.

If you really want to "catch" fatal errors, use set_error_handler, but this still stops script execution on fatal errors.

Wednesday, March 31, 2021
 
RenegadeAndy
answered 7 Months ago
54

Solution #1

Use ErrorException to turn errors into exceptions to handle:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");

Solution #2

try {
    // just an example
    $time      = 'wrong datatype';
    if (false === $timestamp = date("Y-m-d H:i:s", $time)) {
        throw new Exception('date error');
    }
} catch (Exception $e) {
    return false;
}
Wednesday, March 31, 2021
 
Noob_Programmer
answered 7 Months ago
83

Fatal errors are fatal and terminate execution. There is no way around this if a fatal error occurs. However, your error:

Fatal error: Call to a member function find() on a non-object in ...

is entirely preventable. Just add a check to make sure you have an instance of the correct object, and if not, handle the error:

if ($foo instanceof SomeObject) {
    $foo->find(...);
} else {
    // something went wrong
}
Saturday, May 29, 2021
 
SheppardDigital
answered 5 Months ago
58

The real error is Out of memory on a 23818256-byte allocation. You are attempting to allocate a ~22MB block of memory, and you do not have that much free memory available, let alone a contiguous block that large.

In this case, this is coming from a drawable resource. ~22MB would be a truly massive image, more like 2400x2400 than 1200x1200.

Your process heap size is 48MB, which is substantial, but ~22MB is almost half your heap budget.

I would recommend that you find out which drawable resource this is (looks like it might be a background of a RelativeLayout), then reduce its size and the sizes of similar images. Here, by "size" I mean total pixel count, not the on-disk size, as what matters is the decompressed size in RAM, not how big the image is on disk.

Also, this might be an issue of resource directories. For example, if you put your 1200x1200 image in res/drawable/, that effectively is synonymous with res/drawable-mdpi/. If this device happens to be an -xhdpi device, then that would explain the memory usage, as Android will try to upsample this image and double each of the dimensions.

Wednesday, July 28, 2021
 
Alix
answered 3 Months ago
100

check your php5-mysql php module if it is installed correctly (maybe you forgot apache restart?)

had the same issue and after checking php-mysql module again and fixing it, this error vanished

Saturday, August 7, 2021
 
coderaider
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share