0

I want to log something into the database when an attack is detected. The class definition and throwing go separated, but joined them here for simplicity. I was thinking about:

<?php
class Attack extends Exception {
  public function __construct($message, $code = 0, Exception $previous = null, $DB, $IP) {
    $STH = $DB->prepare("INSERT INTO blocked (`type`, `value`) VALUES ('ip', ?)");
    $STH->execute(array($IP));
    parent::__construct($message, $code, $previous);
    }
  }

// code

if (!empty($_POST['honeypot']))
  throw new Attack($IP . " submitted a filled in honeypot", 0, null, $DB, $IP);

But I can also think about this even simpler, though more rigid, method:

<?php
class Attack extends Exception {
  public function __construct($message, PDO $DB, $IP) {
    $STH = $DB->prepare("INSERT INTO blocked (`type`, `value`) VALUES ('ip', ?)");
    $STH->execute(array($IP));
    parent::__construct($message);
    }
  }

// code

if (!empty($_POST['honeypot']))
  throw new Attack($IP . " submitted a filled in honeypot", $DB, $IP);

And I'm not even sure if this works but there's also this:

<?php
class Attack extends Exception {
  public function __construct($message, $code = 0, Exception $previous = null) {
    parent::__construct($message, $code, $previous);
    }
  public function block ($DB, $IP) {
    $STH = $DB->prepare("INSERT INTO blocked (`type`, `value`) VALUES ('ip', ?)");
    $STH->execute(array($IP));
    }
  }

// code

if (!empty($_POST['honeypot'])) {
  $e = new Attack($IP . " submitted a filled in honeypot");
  $e->block($DB, $IP);
  throw $e;
  }

I just want to save the IP (and maybe some other data) into the database when an attack is detected. What are the advantages and disadvantages of each method? Can you think of any other method?

Which method is the most commonly used when logging something into the database while throwing an exception?

Francisco Presencia
  • 8,732
  • 6
  • 46
  • 90
  • What about using [set_exception_handler](http://www.php.net/manual/en/function.set-exception-handler.php) where you call custom function. In that custom function you could call global database handler, or use custom static class to query an db. Now you do not need to extend Exception class and change whole code in project... – Tomasz Dec 26 '13 at 23:37

1 Answers1

0

You don't need an exception here.

If a user reached the destination, it is by no means an exceptional case but rather a pretty regular one. So, just process this request, like you do for any other user action, without exceptions.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • It is actually inside an `if` that checks if there's a honeypot being submitted, which is expected in normal cases to be empty. Updated the question to reflect this. With that aditional info, isn't this a good case for throwing exceptions? – Francisco Presencia Dec 27 '13 at 05:34
  • Honeypot is the same address as any other. Why do you think you have to process it any other way? Exception stands for the **exceptional**, unpredictable case. While what you want is a regular program flow. Why do you want an exception for this? this is the only place where such an issue can occur. Why don't you want to use just a condition? – Your Common Sense Dec 28 '13 at 04:15
  • I've been [reading more on Exceptions](http://stackoverflow.com/q/77127) and I see what you mean now. However [this](http://stackoverflow.com/a/77419/938236) seems also like a valid opinion. I'm trying to learn how to properly use them these days. So I'd need a conditional and then, say, add a function like `block_user($DB);`, right? Do you know of any good book/tutorial to learn *how* to use them? Since everything I find are tutorials about extending `Exception` and not when to use them. – Francisco Presencia Dec 28 '13 at 19:27
  • 1
    Nope, sorry. I know no tutorials. I am using my common sense and experience. There is at least a rule of thumb: if there is only single place where you are going to throw - most likely you don't need an exception here. – Your Common Sense Dec 29 '13 at 00:55