如何在PHP中创建自己的数据验证器
在本教程中,我将教您如何通过逐步构建我们自己的验证库在PHP中创建自定义数据验证器。对于任何需要确保用户提取的数据有效且安全的开发人员来说,数据验证器都是必不可少的工具。在本教程结束时,您将对如何在PHP中创建自定义数据验证器有深入的了解,这将使您能够更好地处理用户输入并确保应用程序的安全性。
步骤1:创建验证类
第一步是创建一个可以处理验证的类。此类应该能够存储我们要验证的每个字段的验证规则,并在调用时验证这些规则。
这是一个简单验证类的示例:
<?php
namespace DevCoder\Validator;
use DevCoder\Validator\Assert\ValidatorInterface;
use InvalidArgumentException;
use Psr\Http\Message\ServerRequestInterface;
use function array_map;
use function array_merge;
use function get_class;
use function gettype;
use function is_array;
use function is_object;
use function is_string;
use function sprintf;
use function trim;
class Validation
{
/**
* @var array<string,array>
*/
private $validators;
/**
* @var array<string,string>
*/
private $errors = [];
/**
* @var array
*/
private $data = [];
public function __construct(array $fieldValidators)
{
foreach ($fieldValidators as $field => $validators) {
if (!is_array($validators)) {
$validators = [$validators];
}
$this->addValidator($field, $validators);
}
}
public function validate(array $data): bool
{
$this->data = $data;
/**
* @var $validators array<ValidatorInterface>
*/
foreach ($this->validators as $field => $validators) {
if (!isset($this->data[$field])) {
$this->data[$field] = null;
}
foreach ($validators as $validator) {
if ($validator->validate($this->data[$field]) === false) {
$this->addError($field, (string)$validator->getError());
}
}
}
return $this->getErrors() === [];
}
/**
* @return array<string,string>
*/
public function getErrors(): array
{
return $this->errors;
}
/**
* @return array
*/
public function getData(): array
{
return $this->data;
}
private function addError(string $field, string $message): void
{
$this->errors[$field][] = $message;
}
/**
* @param string $field
* @param array<ValidatorInterface> $validators
* @return void
*/
private function addValidator(string $field, array $validators): void
{
foreach ($validators as $validator) {
if (!$validator instanceof ValidatorInterface) {
throw new InvalidArgumentException(sprintf(
$field . ' validator must be an instance of ValidatorInterface, "%s" given.',
is_object($validator) ? get_class($validator) : gettype($validator)
));
}
$this->validators[$field][] = $validator;
}
}
}
步骤2:为数据验证创建规则类
现在我们已经创建了验证器类,下一步是创建我们自己的验证规则。这些规则将用于检查提交的数据是否有效。我们将在单独的文件中创建它们,一个用于每个验证规则。每个验证规则文件应包含以IT实施规则命名的类。例如,如果我们有一个验证规则来检查值是否是整数,我们将命名类整数。
验证器面
<?php
namespace DevCoder\Validator\Assert;
interface ValidatorInterface
{
public function validate($value): bool;
public function getError(): ?string;
}
抽象效能器
<?php
namespace DevCoder\Validator\Assert;
abstract class AbstractValidator implements ValidatorInterface
{
/**
* @var string|null
*/
protected $error;
public function getError(): ?string
{
return $this->error;
}
protected function error(string $message, array $context): void
{
$replace = [];
foreach ($context as $key => $value) {
if (is_object($value)) {
$value = method_exists($value, '__toString') ? (string)$value : get_class($value);
} elseif (is_array($value)) {
$value = json_encode($value);
} else {
$value = (string)$value;
}
$replace['{{ ' . $key . ' }}'] = $value;
}
$this->error = strtr($message, $replace);
}
}
整数
<?php
declare(strict_types=1);
namespace DevCoder\Validator\Assert;
use function ctype_digit;
use function is_int;
use function strval;
class Integer extends AbstractValidator
{
/**
* @var string
*/
private $invalidMessage = 'This value should be of type {{ type }}.';
private $minMessage = '{{ value }} should be {{ limit }} or more.';
private $maxMessage = '{{ value }} should be {{ limit }} or less.';
/**
* @var int|null
*/
private $min;
/**
* @var int|null
*/
private $max;
public function validate($value): bool
{
if ($value === null) {
return true;
}
if (ctype_digit(strval($value)) === false) {
$this->error($this->invalidMessage, ['value' => $value, 'type' => 'integer']);
return false;
}
if (is_int($this->min) && $value < $this->min) {
$this->error($this->minMessage, ['value' => $value, 'limit' => $this->min]);
return false;
}
if (is_int($this->max) && $value > $this->max) {
$this->error($this->maxMessage, ['value' => $value, 'limit' => $this->max]);
return false;
}
return true;
}
public function invalidMessage(string $invalidMessage): self
{
$this->invalidMessage = $invalidMessage;
return $this;
}
public function minMessage(string $minMessage): self
{
$this->minMessage = $minMessage;
return $this;
}
public function maxMessage(string $maxMessage): self
{
$this->maxMessage = $maxMessage;
return $this;
}
public function min(int $min): self
{
$this->min = $min;
return $this;
}
public function max(int $max): self
{
$this->max = $max;
return $this;
}
}
Notnull
<?php
declare(strict_types=1);
namespace DevCoder\Validator\Assert;
class NotNull extends AbstractValidator
{
private $message = 'This value should not be null.';
public function validate($value): bool
{
if ($value === null) {
$this->error($this->message, ['value' => $value]);
return false;
}
return true;
}
public function message(string $message): self
{
$this->message = $message;
return $this;
}
}
步骤3:创建验证类的实例
此对象将一系列验证选项作为输入。数组的键是字段的名称,值是验证器的数组。
<?php
$validation = new Validator([
'age' => [(new Integer())->min(18)->max(99), new NotNull()],
'number_of_children' => [new NotNull(), new Integer()],
'salary' => [new NotNull(), new Integer()],
]);
步骤4:数据验证
创建了验证类的实例后,您可以通过调用验证类的validate()方法来验证数据。如果满足所有验证规则,则此方法将返回true。
<?php
if ($validation->validate($_POST) === true) {
$data = $validation->getData();
// save in database
// redirect in another page
}
return render('template.html.php', [
'errors' => $validation->getErrors()
]);
可以添加的其他规则的示例
$validation = new Validation([
'email' => [new NotNull(), new Email()],
'password' => new NotNull(),
'firstname' => [new NotNull(), (new StringLength())->min(3), new Alphabetic()],
'lastname' => [(new StringLength())->min(3)],
'gender' => new Choice(['Mme', 'Mr', null]),
'website' => [new NotNull(), new Url()],
'age' => [new NotNull(), (new Integer())->min(18)],
'invoice_total' => [new NotNull(), new Numeric()],
'active' => [new NotNull(), new Custom(function ($value) {
return is_bool($value);
})]
]);
要查看可以添加的其他验证规则,请在以下URL上查看我的GitHub存储库:https://github.com/devcoder-xyz/php-validator/tree/main/src/Assert
小型项目的理想选择
简单简单!
https://github.com/devcoder-xyz/php-validator