I think it's a bad idea to generalize validation and filtering logic. That was the idea behind magic quotes after all, which is now universally condemned.
Besides that, validating field inputs usually involves a lot of specific junk. Generic rules turn out to be a rather small part of validation, especially as apps grow in size and complexity.
It would be a better idea to come up with a mini framework that allows you to handle both generic and specific validation in the same place. Something like this...
class BrokenRules extends Exception {
protected $errors;
function __construct($errors) {
$this->errors = $errors;
}
function getErrors() {
return $this->errors;
}
}
class Foo {
protected $db;
function __construct(PDO $db) {
$this->db = $db;
}
function loadNew() {
return array('bar' => 'new foo', 'baz' => 5);
}
function loadById($id) {
$stmt = $this->db->prepare('SELECT * FROM foo WHERE id = ?');
$stmt->bindValue(1, $id, PDO::PARAM::INT);
$stmt->execute();
return $stmt->fetch();
}
function save($data) {
return isset($data['id']) ? $this->update($data) : $this->insert($data);
}
protected function validateForInsert($data) {
if ((int)$data['baz'] <= 3) $errors['baz'][] = 'Baz must be greater than 3';
if (isset($errors)) throw new BrokenRules($errors);
}
protected function validateForUpdate($data) {
// TODO: validateForUpdate
}
protected function insert($data) {
$this->validateForInsert($data);
$stmt = $this->db->prepare('INSERT INTO foo (x, y) VALUES (?, ?)');
$stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
$stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
$stmt->execute();
return $this->db->lastInsertId();
}
protected function update($data) {
$this->validateForUpdate($data);
$stmt = $this->db->prepare('UPDATE foo SET x = ?, y = ? WHERE id = ?');
$stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
$stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
$stmt->bindValue(3, $data['id'], PDO::PARAM_INT);
$stmt->execute();
return $data['id'];
}
}
try {
$foo = new Foo($pdo);
if ($_POST) {
$id = $foo->save($_POST);
redirect("edit_foo.php?id=$id");
} else if (isset($_GET['id'])) {
$data = $foo->loadById($_GET['id']);
} else {
$data = $foo->loadNew();
}
} catch (BrokenRules $e) {
$errors = $e->getErrors();
}
include 'templates/foo.php';