0

Can someone please provide a way to handle the Fatal error: Call to a member function prepare() on a non-object.

Here is my Scenario:

I have a Singleton Database Class which stores my database details and creates an instance of a PDO object when requested.

I then have the following two classes:

Base class:

namespace lib\translator;
use lib\database as db;

class EntityTranslator {
    protected $dbConn;

    public function __construct() {
        try {
            $this->dbConn = db\Database::getInstance();
        }
        catch(\PDOException $e) {
            // do some error logging here
        }
    }
}

Sub class:

namespace lib\translator;
use lib\entity as entity;

class RequestTranslator extends EntityTranslator {

    public function __construct() {
        parent::__construct();
    }

    public function createRequest() {
        $request = new entity\Request();
        try {
            $stmt = $this->dbConn->prepare("CALL createRequest()");
            $stmt->execute();

            $rowCount = $stmt->rowCount();
            if ($rowCount == 1) {
                $row = $stmt->fetch(\PDO::FETCH_ASSOC);

        // do stuff with the data here
            }
            return $request;
        }
        catch (\PDOException $pdoe) {
        // do error logging here
        }
    }
}

Now, I am not wondering why the error occurs. I am trying to handle the very rare case when my database connection is not available and the PDO object instantiation (done via the call to db\Database::getInstance()) throws an exception, resulting in the variable $dbConn remaining null.

I realise, it would be possible to test $dbConn for null before using it each time. But As I stated, this should be an exceptionally rare situation and may in fact never occur, so I don't think that checking for null each time is a smart performance choice.

I would like to be able to add on another catch(\Exception $ex){} block to handle what is essentially a NullPointerException (as seen in Java) but PHP does not provide for such an exception. Rather they issue the Fatal error: Call to a member function prepare() on a non-object.

So what I am looking for, is a way to handle this error, for this situation, without checking for null each time.

Maybe I have missed the basic concept of error handling in PHP, but I have not been able to find a definitive resource on this topic.

Any suggestions?

Raidri
  • 17,258
  • 9
  • 62
  • 65
samazi
  • 1,161
  • 12
  • 24

3 Answers3

0
public function createRequest() {
        $request = new entity\Request();
        try {
            if(!is_null( $this->dbConn)){
            $stmt = $this->dbConn->prepare("CALL createRequest()");
            $stmt->execute();

            $rowCount = $stmt->rowCount();
            if ($rowCount == 1) {
                $row = $stmt->fetch(\PDO::FETCH_ASSOC);

        // do stuff with the data here
            }
            return $request;
          }
        }
        catch (\PDOException $pdoe) {
        // do error logging here
        }
    }
Arun Killu
  • 13,581
  • 5
  • 34
  • 61
  • As I stated in my question, I realise i can check for null each time, however I believe this is an unnecessary performance hit when i really never expect $dbConn to null. I am looking for an answer that does not require checking for null. – samazi Oct 20 '12 at 05:17
0

You can't catch and recover from Fatal Errors in PHP. You can register a shutdown function to report details of the last error, but nothing like a finally block in Java.

More detailed explanation here: How do I catch a PHP Fatal Error

I would recommend checking for null each time - compared to other things your code is doing, this is an inexpensive call.

Community
  • 1
  • 1
doublesharp
  • 26,888
  • 6
  • 52
  • 73
  • thanks for the reference, I have been looking through implementing something like this. I have actually already changed all my code to check for null each time, however I just wish PHP provided a better way to handle null pointer exceptions. – samazi Oct 20 '12 at 05:25
0

Why is your application allowed to call RequestTranslator::createRequest() anyway, when, at the time of instantiating RequestTranslator, you already know whether or not the database connection has instantiated properly?

Shouldn't your application logic be something like the following:

try
{
    /*
     * the following line should throw
     * SomeMeaningfulException when it 
     * is unable to connect to the database
     */
    $rt = new lib\translator\RequestTranslator();

    /*
     * this line should not be reached
     * if the above throws SomeMeaningfulException
     */
    $rt->createRequest();
}
catch( SomeMeaningfulException $e )
{
    /* $rt database connection has not instantiated properly */
}

In other words, if you ask me, the constructor of RequestTranslator should already throw SomeMeaningfulException if it is unable to instantiate the database connection when the object's methods are that dependant on functioning properly:

class EntityTranslator {
    protected $dbConn;

    public function __construct() {
        try {
            $this->dbConn = db\Database::getInstance();
        }
        catch(\PDOException $e) {
            // do some error logging here
            throw new SomeMeaningfulException( 'some meaningful message' );
        }
    }
}

If this is somehow not preferred, then I don't see why checking for null is that much of an issue. I agree with others, that the performance penalty is probably neglectable.

Decent Dabbler
  • 22,532
  • 8
  • 74
  • 106
  • thank you for your consideration of the scenario in your response. I think your solution is correct, and my application will benefit from what you suggest. It does make more sense, now, to pass the exception up the chain and handle it before allowing class methods to be called by other components. – samazi Oct 20 '12 at 08:59