Symfony+Doctrine图书借阅功能:执行后数据库未更新求助
Symfony图书借阅功能:图书状态未更新问题排查
核心问题:逻辑判断完全颠倒
在BookController的borrow方法中,借阅条件判断逻辑完全写反:
$availabilty = $book->isBorrowed(); // if available, then the user can borrow it. if($availabilty){
isBorrowed()返回true代表图书已被借阅,但你却在该条件下执行借阅操作——这意味着只有当图书已经被借走时,才会尝试标记它为已借阅,而真正可借阅的图书(isBorrowed()返回false)反而不会进入逻辑分支。
正确的判断逻辑应为:
$availabilty = $book->isBorrowed(); // 仅当图书未被借阅时,允许执行借阅操作 if(!$availabilty){
次要优化点(避免冗余与潜在问题)
移除重复的实体查询
你的多个控制器方法(show、RenderBorrow、borrow)中,已经通过Symfony参数转换器自动注入了Book $book对象,无需再通过Repository重复查询:// 冗余代码,可直接删除 $repo = $manager->getRepository(Book::class); $book = $repo->find($id);直接使用注入的
$book即可,重复查询不仅浪费资源,还可能导致实体管理器中存在多个状态不一致的对象实例。合并EntityManager的flush操作
在borrow方法中,你调用了两次$manager->flush(),可合并为一次:$user->addBook($book); $book->setBorrowed(true); // 一次flush即可提交所有变更 $manager->flush();对于EntityManager已管理的实体(如注入的
$book、通过getUser()获取的$user),无需额外调用persist(),EntityManager会自动跟踪这些对象的变更。添加表单CSRF防护
你的借阅表单使用method="post"但未添加CSRF令牌,Symfony默认开启的CSRF防护会拦截此类请求。需在表单中添加令牌字段:{{ form_widget(form._token) }}更规范的方式是使用Symfony表单组件构建借阅表单,自动处理CSRF防护。
修复后的borrow方法示例
#[Route("/book/borrowed/{id}", name: 'book_borrowed')] public function borrow(Book $book, EntityManagerInterface $manager){ // 检查图书是否未被借阅 if(!$book->isBorrowed()){ /** @var \App\Entity\User $user */ $user = $this->getUser(); $user->addBook($book); $book->setBorrowed(true); $manager->flush(); } return $this->redirectToRoute('book_show', ['id' => $book->getId()]); }
内容的提问来源于stack exchange,提问作者user19533393
相关产品推荐
相关产品推荐

