views:

30

answers:

1

I have a web service written in PHP, that returns JSON results. It works well and has been thoroughly tested.

I needed to add logging to the service calls (who called and when). I implemented this using a SQLite database (for very small amount of data) and PDO. The one condition to the logging was that it should not harm the web service itself. The fact that I'm logging his call should not matter to the user, nor should any error in the logging process block any service call.

I implemented a Log class and an "execute" function that expects SQL strings:

    function __construct() {
        $this->dbConn = 'sqlite:' . realpath("myLog.sqlite");
        try {
            $this->db = new PDO($this->dbConn);
        }
        catch (PDOException $e) {
            //I don't care
        }
    }

    private function execute($sql) {
        try {
            $query = $this->db->prepare($sql);
            $query->execute();  
        }
        catch(Exception $e) {
            //I don't care
        }
    }

I then added at the end of every service function a call similar to this:

$sql = "INSERT INTO $table(id, Time) VALUES('$id', datetime('now','localtime'))";
$this->execute($sql);

$jsonResult = doSomething($id);
return $jsonReuslt;

The problem is: from time to time, I get a string on the client that contains a fatal error string (pointing to this line $query->execute()) saying it's not an object.

In all cases so far, I traced it to an erroneous SQL query. But what I need is a way to make sure the original JSON gets returned even if there is an error in the logging function.

How can I ensure that no matter what happens when I call $this->execute($sql) - $jsonResult will return with the actual JSON results?

TIA,
Guy

A: 

Test the result of preparing the query before executing it - if the statement cannot be successfully prepared, the server will return false (or throw an exception).

$query = $this->db->prepare($sql);
if ($query)
    $query->execute();
Chadwick
Thanks for the suggestion, but the main purpose of the question is not to fix the code, but understand how to make sure its side effects won't affect the main service call.
Traveling Tech Guy
This prevents the side effects by preventing the fatal error. Fatal errors are just that: fatal. You have to prevent them, not stop them after the fact. The fatal error occurs when you attempt to call a method on a non-object. Specifically `false` returned from some error in `prepare(...)`. Testing it before calling `execute(..)` on `false` prevents the fatal error, preventing any side effects, allowing `doSomething($id)` to be called and the `$jsonResult` to be returned.
Chadwick
I understand. But suppose another issue crops up after fixing the prepare() function - I still want to avoid adverse side effects to the main functionality. I need a sort of catch-all on the logging functionality to prevent it killing the service.
Traveling Tech Guy