Исключение UniqueConstraintViolationException
Исключение UniqueConstraintViolationException принадлежит пространству имён Illuminate\Database\UniqueConstraintViolationException и наследуется от QueryException. Оно возникает, когда вы пытаетесь добавить или обновить запись таким образом, что значение в колонке с уникальным индексом дублируется. Это одна из наиболее частых ошибок при работе с базой данных, особенно при регистрации пользователей или создании записей с уникальными полями, такими как email, телефон или slug.
Исключение автоматически генерируется драйвером базы данных при выполнении запроса INSERT или UPDATE. В зависимости от используемой СУБД (MySQL, PostgreSQL, SQLite) сообщение об ошибке может отличаться, но суть остаётся одинаковой - нарушение ограничения уникальности. В Laravel это исключение обёрнуто в удобный класс, который позволяет перехватывать его и обрабатывать специфическим образом.
Синтаксис
<?php
use Illuminate\Database\UniqueConstraintViolationException;
try {
// Попытка создания записи с дублирующим уникальным значением
Model::create(['unique_field' => 'duplicate_value']);
} catch (UniqueConstraintViolationException $e) {
// Обработка ошибки уникальности
}
?>
Пример
Давайте рассмотрим ситуацию, когда мы пытаемся создать пользователя с email, который уже существует в базе данных:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Database\UniqueConstraintViolationException;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request)
{
try {
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
echo "User created successfully";
} catch (UniqueConstraintViolationException $e) {
echo "Email already exists in the database";
}
}
}
?>
Результат выполнения кода при попытке создать пользователя с существующим email:
"Email already exists in the database"
Пример
Обработка исключения с получением подробной информации об ошибке для логирования:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Database\UniqueConstraintViolationException;
use Illuminate\Support\Facades\Log;
class PostController extends Controller
{
public function store()
{
try {
$post = Post::create([
'title' => 'My Unique Title',
'slug' => 'my-unique-title',
'content' => 'Some content',
]);
echo "Post created";
} catch (UniqueConstraintViolationException $e) {
Log::error('Unique constraint violation: ' . $e->getMessage());
echo "Post with this slug already exists";
}
}
}
?>
Результат выполнения кода при попытке создать пост с существующим slug:
"Post with this slug already exists"
Пример
Обработка исключения при обновлении записи с нарушением уникальности:
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Database\UniqueConstraintViolationException;
class ProductController extends Controller
{
public function update($id)
{
try {
$product = Product::findOrFail($id);
$product->sku = 'EXISTING-SKU-123';
$product->save();
echo "Product updated successfully";
} catch (UniqueConstraintViolationException $e) {
echo "SKU must be unique, this value is already taken";
}
}
}
?>
Результат выполнения кода при попытке обновить SKU на уже существующее значение:
"SKU must be unique, this value is already taken"
Смотрите также
-
исключение
QueryException,
которое является родительским для всех исключений базы данных -
исключение
ModelNotFoundException,
которое возникает при отсутствии модели в базе данных -
исключение
MultipleRecordsFoundException,
которое выбрасывается при обнаружении нескольких записей там, где ожидалась одна -
исключение
MassAssignmentException,
которое возникает при попытке массового заполнения защищённых полей