Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Model validation in PHP that requires interaction with the database

Let's say I have this model. (I made it very simple for demonstration purposes.)

class User
{
    public $id;
    public $email;
    public $password;
    public $errors = [];

    public function isValid()
    {
        if (strpos($this->email, '@') === false) {
            $this->errors['email'] = 'Please enter an email address';
        }
        // ...

        return !$this->errors;
    }
}

And let's say I have this DAO for retrieving, adding, updating, and deleting users.

class UserDAO
{
    public function getUsers() { ... }

    public function getUserById($id) { ... }

    public function addUser(User $user) { ... }

    public function updateUser(User $user) { ... }

    public function deleteUser($id) { ... }

    public function isEmailUnique($email) { ... }
}

When I process a form, I typically do something like this:

$userDAO = new UserDAO();
$user = new User();
$user->email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$user->password = filter_input(INPUT_POST, 'password');

if ($user->isValid()) {
    if ($userDAO->addUser($user)) {
        // ...
    } else {
        // ...
    }
} else {
    // do something with $user->errors
}

Now, let's say part of my user validation should be to check whether email is unique, how do I make it part of the User model? So that, when $user->isValid() is called, it also checks whether the email is unique? Or am I doing this all wrong?

From my weak understanding of DAOs, DAOs are responsible for all interactions with the database. So how do I make the model work with database from within?

like image 978
Mikey Avatar asked Feb 13 '16 23:02

Mikey


People also ask

What is validation function in PHP explain user defined function with example?

Validation means check the input submitted by the user. There are two types of validation are available in PHP. They are as follows − Client-Side Validation − Validation is performed on the client machine web browsers.

What can the model validation be used for?

The purpose of model validation is to check the accuracy and performance of the model basis on the past data for which we already have actuals.

What is data model validation?

Validating a model syntactically means checking each entity if it is correct and complies with database modeling standards. The second method is to validate the data model by manipulating real test data. This last validation method sometimes requires the use of a tool other than the one used for modeling.

What is model validation explain?

Model validation refers to the process of confirming that the model actually achieves its intended purpose. In most situations, this will involve confirmation that the model is predictive under the conditions of its intended use.


Video Answer


2 Answers

My recommendation is this: don't consider email address uniqueness when validating your User model. Uniqueness is a UserDAO problem, not a User problem.

If the User can validate itself, it should be able to do so in isolation; its validation should not be concerned with any external interactions.

The only time it matters whether or not the email address is unique is at the instant you attempt to insert it into the database. Considering the possibility of multiple concurrent users, it is theoretically possible to validate the uniqueness of the address and have it no longer be unique by the time you attempt to insert it.

I think the most straightforward and dependable way to do this is to add a unique constraint on email address in your database, then in your addUser() method, just try to add it. If your database tells you it is not unique, then you know it is not unique. You cannot really know beforehand.

like image 120
Don't Panic Avatar answered Nov 15 '22 16:11

Don't Panic


Keep the User class as it is, it is a good citizen by itself.

I would make the method isEmailUnique private (iff it is used just for that) and check by the existence of a User with that e-mail inside addUser. On the other hand, this would pull the responsibility of the logic to the DAO. (See: Responsibilities and use of Service and DAO Layers)

So if you change the behavior of isValid to check if the user is already onto the database, you would be breaking your design.

like image 27
thyago stall Avatar answered Nov 15 '22 18:11

thyago stall