如何使用面向对象技术验证PHP中的表单字段

I have created a class 'validate' to validate two fields i.e 'firstname' and 'lastname'. It is not working fine, it is showing error when field is empty but when I submit the form with non-empty fields the error is still there. How to execute this on form submission?

 <?php

  class validation {

  public $firstName, $lastName, $errorFirstName = '', $errorLastName = '';

  function __constructor($fName, $lName){
    $this->firstName = $fName;
    $this->lastName = $lName;
  }

  function check(){

      if($_SERVER["REQUEST_METHOD"] == "POST"){
        if(empty($this->firstName)){
        $this->errorFirstName = 'First name is required';
       } else {
        $this->errorFirstName = 'Input is okay';
       }

     if(empty($this->lastName)){
         $this->errorLastName = 'Last name is required';
      }  else {
       $this->errorLastName = 'Input is okay';
      }
    }
   }
  }

 $obj = new validation($_POST['firstname'], $_POST['lastname']);
 $obj->check();
 $errorF = $obj->errorFirstName;
 $errorL = $obj->errorLastName;

 ?>

  <!DOCTYPE html>
  <html lang = "en-US" dir = "ltr">
   <head>
    <title>Home</title>
    <meta charset = "UTF-8"/>
   </head>
   <body>
   <form method = "POST" action="<?php echo $_SERVER["PHP_SELF"]?>">
    <label>First Name: </label>
    <input type = "text" name = "firstname" placeholder = "John"/>
    <p class = "error"><?php echo $errorF;?></p>
    <label>Last Name: </label>
    <input type = "text" name = "lastname" placeholder = "Doe"/>
    <p class = "error"><?php echo $errorL;?></p>
    <input type="submit">
   </form>
  </body>
 </html>

Everyone always makes "database class" and "validation class". Ehh .... whaaaaay?

Don't make a validation class. It never works. The most .. emm ... sustainable options for validating user input are:

With using entities for validation, it is quite simple. In your case you would have class Profile where you have method setFirstName(string $name). Then within this method you do the validation and on error throw a custom made exception, like InvalidFirstName .. or something like that.

Using value objects is a bit trickier, but it prevents the code duplication. For example, you need to validate email address. So, the way you would want to use it would look something like:

try {
    $profile = new Profile;
    $profile->setEmail(new EmailAddress($_POST['email']));
} catch (InvalidArgumentException $e){
    // validation failed
}

Therefore, to get this behavior, you would have the class defined kinda like this:

class EmailAddress
{
    private $email;


    public function __construct(int $emailId = null, string $email = null)
    {
        if (!$this->isValid($email)) {
            throw new InvalidArgumentException('Not valid email address');
        }
        $this->email = $email;
    }


    private function isValid($email)
    {
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }


    public function __toString()
    {
        return $this->email;
    }
}

This approach is a lot more expressive, but it tends to become a big gnarly, when interacting with persistence layer.

In practice, the best option is to use combination of these both solutions:

  • keep the validation in entities, for rules, that are unique
  • use value objects for often repeating constraints