NOTE: Controller is not responsible for "transporting data". Controller's responsibility is altering model's (and in special cases - current view instance's) state.
There is actually third approach: have a separate isValid()
method for the domain object (you call them "entities"). The setter validation becomes messy, when you have validation rules across multiple data entries.
Example: validation of repeated password for user registration form.
Having validation in setter for this will turn out quite messy. Especially if you opt to use exceptions for each failing validation.
Also, instead of data access objects I would recommend for you to use data mappers. The code would basically look something like this:
$post = new Model\Domain\Post;
$mapper = new Model\Mappers\Post($pdo);
$post->setId(42);
$mapper->fetch($post);
$post->setTitle($title);
if ($post->isValid()) {
$mapper->store($post);
}
This approach also lets you externalize the validation by injecting some kind of Validator
instance in the Model\Domain\Post
instance through constructor, if you want to reuse some validation rules.
Though, when making a larger app, you will probably notice, that there are very few repeated checks, which go beyond existing php filters.
NOTE: please don't use static classes. This forces you to use procedural paradigm, where it's not needed.
Another thing that you have to pay attention to is: what kind of validation are you doing ?
Business rules should be validated in domain objects, but data integrity checks (like: "is this email address unique") are part of persistence logic. And persistence logic should (according to SRP be handled by a separate instance. In the given example that part was managed by data mapper.