我正在使用symfony 2.8和FOSUserBundle。我想允许管理员编辑用户'用户名和电子邮件。如果已经使用了新用户名或电子邮件,则数据库会出错
SQLSTATE [23000]:完整性约束违规:1062重复条目
哪个好,但我不知道怎么回复给那些试图改变它的管理员,告诉他们出了什么问题(应用程序的生产版本只会给出错误500)。我想要做的是显示某种类型的错误消息(最好像FOSUserBundle的形式一样)来说明用户名(或电子邮件)。
表格的相关部分在此构建:
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->findUserBy(array('id' => $id));
$form = $this->createFormBuilder()
->add('username', TextType::class, array(
'label' => 'Username',
'data' => $user->getUsername(),
))
->add('email', EmailType::class, array(
'label' => 'Email',
'data' => $user->getEmail(),
))
->getForm();
并在此处理数据库:
if ($form->isSubmitted() and $form->isValid()) {
// set new username if different
$newUsername = $form['username']->getData();
if ($user->getUsername() !== $newUsername) {
$user->setUsername($newUsername);
}
// set new email if different
$newEmail = $form['email']->getData();
if ($user->getEmail() !== $newEmail) {
$user->setEmail($newEmail);
}
$userManager->updateUser($user);
}
我尝试过很多东西,比如设置username_canonical和email_canonical,或者在我的User.php类中添加@UniqueEntity,但是他们没有帮助(这是有道理的,因为错误是正确的 - 我只是可以& #39; t将其翻译成有用的信息。)
答案 0 :(得分:0)
如果您不想再进行覆盖以进行一些验证,则需要实现一个EventListener,通过监听onKernelResponse
事件来捕获您需要的异常。
<强> DBALExceptionResponseListener.php 强>
// src/AcmeBundle/EventListner/DBALExceptionResponseListener.php
<?php
namespace AcmeBundle\EventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Doctrine\DBAL\DBALException;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Router\RouterInterface;
class DBALExceptionResponseListener
{
public function __construct(SessionInterface $session, RouterInterface $router)
{
$this->session = $session;
$this->router = $router;
}
/**
* @param GetResponseForExceptionEvent $event
*/
public function onKernelResponse(GetResponseForExceptionEvent $event)
{
$request = $event->getRequest();
$exception = $event->getException();
$message = $exception->getMessage();
// Maybe some checks on the route
if ($request->get('_route') !== 'your_route' || $request->headers->get('referer') !== 'your_referer') {
return;
}
// Listen only on the expected exception
if (!$exception instanceof DBALException) {
return;
}
// You can make some checks on the message to return a different response depending on the MySQL error given.
if (strpos($message, 'Integrity constraint violation')) {
// Add your user-friendly error message
$this->session->getFlashBag()->add('error', 'SQL Error: '.$message);
}
// Create your custom response to avoid the error page.
$response = new RedirectResponse($this->router->generate('your_route'));
// Update the Event Response with yours
$event->setResponse($response);
}
}
<强> services.yml 强>
# app/config/services.yml
services:
acme.kernel.listener.dbal_exception_response_listener:
class: AcmeBundle\EventListener\DBALExceptionResponseListener
tags:
- {name: kernel.event_listener, event: kernel.exception, method: onKernelResponse}
arguments:
session: "@session"
router: "@router"
通过查看Exception::$message
,您可以轻松找到导致问题的属性。
最常见的消息包含:
... column&#39; propertyname&#39;不能为空...