Database Rules (unique, exists)#
ReqShield batches expensive DB validation rules across fields for performance.
To use DB rules, provide a DatabaseProvider implementation to Validator::make($rules, $dbProvider).
Batch execution is always native-provider based: ReqShield calls
batchExistsCheck() and batchUniqueCheck() on every provider.
There is no SQL query-builder fallback path.
DatabaseProvider Implementation#
Your class must implement Infocyph\ReqShield\Contracts\DatabaseProvider.
<?php
namespace App\Validation;
use Infocyph\ReqShield\Contracts\DatabaseProvider;
use PDO;
final class PdoDatabaseProvider implements DatabaseProvider
{
public function __construct(private PDO $pdo)
{
}
public function batchExistsCheck(string $table, array $checks): array
{
return [];
}
public function batchUniqueCheck(string $table, array $checks): array
{
return [];
}
public function compositeUnique(
string $table,
array $columns,
?int $ignoreId = null,
): bool {
return true;
}
public function exists(
string $table,
string $column,
$value,
?int $ignoreId = null,
): bool {
$sql = "SELECT COUNT(*) FROM `{$table}` WHERE `{$column}` = ?";
$params = [$value];
if ($ignoreId !== null) {
$sql .= " AND `id` != ?";
$params[] = $ignoreId;
}
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return (int)$stmt->fetchColumn() > 0;
}
public function query(string $query, array $params = []): array
{
// Not used by ReqShield batch DB rules; kept for compatibility.
$stmt = $this->pdo->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
Use the Provider#
use Infocyph\ReqShield\Validator;
$validator = Validator::make([
'email' => 'required|email|unique:users,email',
'category_id' => 'required|integer|exists:categories,id',
], $dbProvider);
$result = $validator->validate($payload);
Rule Syntax#
exists:
exists:table,columnExample:
exists:users,id
unique:
unique:table,columnunique:table,column,ignoreIdunique:table,column,ignoreId,idColumn,withTrashed,softDeleteColumn
Examples:
'email' => 'unique:users,email'
'email' => 'unique:users,email,10' // ignore row id=10
'email' => 'unique:users,email,,id,false,deleted_at' // ignore soft-deleted rows
'email' => 'unique:users,email,,id,true,deleted_at' // include soft-deleted rows
Object Rule for Full Control#
Use Infocyph\ReqShield\Rules\Unique directly when you need explicit constructor parameters.
use Infocyph\ReqShield\Rules\Unique;
$validator = Validator::make([
'email' => [
'required',
new Unique(
table: 'users',
column: 'email',
ignoreId: null,
idColumn: 'id',
withTrashed: false,
softDeleteColumn: 'deleted_at',
),
],
], $dbProvider);