Rozbudowa walidatora o klasę match, która po raz pierwszy użyje naszej zmiennej params. Do dzieła.

Stanęliśmy na tym:

<?php 

/*
$form_rules =  [
    'email' => ['required', 'email'],
    'password' => ['required'],
    'confirmPassword' => ['required', 'match:password']
];
*/

$form_data = [ 
    'email' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];



interface RuleInterface
{
  public function validate(array $data, string $field, array $params): bool;

  public function getMessage(array $data, string $field, array $params): string;
}

class RequiredRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    return !empty($data[$field]);
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "Field {$field} is missing!";
  }
}



class EmailRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    return (bool) filter_var($data[$field], FILTER_VALIDATE_EMAIL);
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "Invalid email";
  }
}
class UrlRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    return (bool) filter_var($data[$field], FILTER_VALIDATE_URL);
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "Invalid URL";
  }
}

$field = 'email';
$rule = new UrlRule;
$is_url = $rule->validate($form_data, $field, []);
if(!$is_url){
    echo $rule->getMessage($form_data, $field, []);
}
//Invalid URL

Klasa MatchRule:

class MatchRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    $fieldOne = $data[$field];
    $fieldTwo = $data[$params[0]];

    return $fieldOne === $fieldTwo;
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "Does not match {$params[0]} field";
  }
}

Próba:

<?php 

/*
$form_rules =  [
    'email' => ['required', 'email'],
    'password' => ['required'],
    'confirmPassword' => ['required', 'match:password']
];
*/

$form_data = [ 
    'email' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];



//(...)

class MatchRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    $fieldOne = $data[$field];
    $fieldTwo = $data[$params[0]];

    return $fieldOne === $fieldTwo;
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "Does not match {$params[0]} field";
  }
}

$field = 'confirmPassword';
$rule = new MatchRule;
$params = ['password'];

$password_match = $rule->validate($form_data, $field, $params);
if(!$password_match){
    echo $rule->getMessage($form_data, $field, $params);
}

Ok, teraz sprawdźmy, czy pola confirmPassword i email się pokrywają:

<?php 

/*
$form_rules =  [
    'email' => ['required', 'email'],
    'password' => ['required'],
    'confirmPassword' => ['required', 'match:password']
];
*/

$form_data = [ 
    'email' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];

//(...)

class MatchRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    $fieldOne = $data[$field];
    $fieldTwo = $data[$params[0]];

    return $fieldOne === $fieldTwo;
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "Does not match {$params[0]} field";
  }
}

$field = 'confirmPassword';
$rule = new MatchRule;
$params = ['email'];

$password_match = $rule->validate($form_data, $field, $params);
if(!$password_match){
    echo $rule->getMessage($form_data, $field, $params);
}
//Does not match email field

Powinniśmy oswoić się z tym, jak parametry są przekazywane, bo będzie to wykorzystywana przez nas konwencja. Do następnego razu!