当前位置: 首页 > news >正文

Symfony学习笔记 - 利用Doctrine开发一个学生信息的增删查改

现在在学习Symfony,Doctrine作为官方重点推荐的数库库Bundle,必须要试试!

1、创建Symfony的Demo的Web应用

symfony new symfony_webapp --webapp
正确安装后,目录应该是这样的:
image
如果你的目录仅仅只有config和vendor目录,那就表明你没有安装完整。原因是symfony时,需要从https://packagist.org下载相应的包,包括Symfony新建应用的模板源码。由于 https://packagist.org限速或者封锁的原因,不能下载完整的包。这时候,你需要配置一下镜像:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
然后,再执行一遍symfony的创建新应用命令。

2、启动Symfony官方开发的Web Server,根据提示,访问新应用的页面

Web Server的启动命令:
cd symfony_webapp symfony server:start
下图红框标记部分,就是启动的URL地址:
image

3、创建Student Entity和数据表

  1. 需要在.env中配置数据库连接,我用的MariaDB:
DATABASE_URL="mysql://root:123456@127.0.0.1:3306/symfony_webapp?serverVersion=10.1.34-MariaDB&charset=utf8mb4"
  1. 在项目目录下,命令行窗口,运行命令:
php bin/console make:entity

按照提示,输入表名、字段属性(字段名、类型、长度、是否允许为null等)。完了之后,会在src\Entity\目录下,创建实体类,比如Student、Teacher等。同时,还会在src\Repository\目录下,创建实体对应的数据存取类,比如StudentRepository,该类除了构造器之外,还有两个默认被注释的方法,findByExampleFieldfindOneBySomeField

  1. 在命令行运行生成迁移文件:
php bin/console make:migration

migrations目录下,会产生创建表的类文件类,文件名是Version+时间戳,比如Version20250911130132.php。

  1. 执行​​所有未应用的迁移,实际修改数据库结构
symfony console doctrine:migrations:migrate

执行完毕后,会在数据库中创建表。

4、实现新增学员

  1. 创建Student的Controller类
    php bin/console make:controller StudentController
    执行后,会创建src\Controller\StudentController.php,或者手工创建也是可以的。

  2. 在StudentController类中,新增/student/create路由及方法

#[Route('/student/create', name: 'student_create')]
public function createStudent(EntityManagerInterface $entityManager,Request $request): Response
{$student = new Student();$form = $this->createForm(StudentType::class, $student);$form->handleRequest($request);if ($form->isSubmitted()) {if ($form->isValid()) {$entityManager->persist($student);$entityManager->flush();$this->addFlash('success', 'Student created successfully.');return $this->redirectToRoute('student_list');}}return $this->render('student/edit.html.twig', ['form' => $form,]);
}
  1. 创建StudentType,该类是一个form
class StudentType extends AbstractType
{public function buildForm(FormBuilderInterface $builder, array $options){$builder->add('first_name', TextType::class)->add('last_name', TextType::class)->add('birthdate', DateType::class)->add('description', TextareaType::class)->add('save', SubmitType::class, ['label' => 'Create']);}
}
  1. edit.html.twig的代码如下:
{% extends 'base.html.twig' %}{% block body %}{{ form_start(form) }}<div class="row"><div class="col-md-6">{{ form_row(form.firstName) }}</div><div class="col-md-6">{{ form_row(form.lastName) }}</div></div><div class="row"><div class="col-md-6">{{ form_row(form.birthdate) }}</div></div><div class="row"><div class="col-md-12">{{ form_row(form.description) }}</div></div>{{ form_end(form) }}
{% endblock %}

按照上面4步,就可以完成一个学生的新增了,具体功能包括:

  • 新增
  • 保存数据
  • 保存时,验证数据的有效性验证
    image

5、实现学员列表查询

  1. 在StudentController中,定义路由和列表查询的方法
    #[Route('/students', name: 'student_list')]public function list(Request $request, EntityManagerInterface $em): Response{$initialData = ['firstName' => $request->query->get('firstName'),'lastName'  => $request->query->get('lastName'),'birthdate' => $request->query->get('birthdate') ?\DateTime::createFromFormat('Y-m-d', $request->query->get('birthdate')) : null];// 1. 创建查询表单$form = $this->createForm(StudentSearchType::class,$initialData);$form->handleRequest($request);// 2. 初始化查询构建器$repository = $em->getRepository(Student::class);$queryBuilder = $repository->createQueryBuilder('s');$searchData = $form->isSubmitted() ? $form->getData() : $request->query->all();// 3. 处理表单提交并构建查询条件if ($form->isSubmitted() && $form->isValid()) {return $this->redirectToRoute('student_list', ['firstName' => $form->get('firstName')->getData(),'lastName' => $form->get('lastName')->getData(),'birthdate' => $form->get('birthdate')->getData()?->format('Y-m-d'),]);}if (!empty($searchData['firstName'])) {$queryBuilder->andWhere('s.firstName LIKE :firstName')->setParameter('firstName', '%' . $searchData['firstName'] . '%');}if (!empty($searchData['lastName'])) {$queryBuilder->andWhere('s.lastName LIKE :lastName')->setParameter('lastName', '%' . $searchData['lastName'] . '%');}if (!empty($searchData['birthdate'])) {$queryBuilder->andWhere('s.birthdate = :birthdate')->setParameter('birthdate', $searchData['birthdate']);}// 4. 执行查询$query = $queryBuilder->getQuery();$students = $query->getResult();// 5. 渲染模板return $this->render('student/list.html.twig', ['form' => $form->createView(),'students' => $students,]);}

2、定义StudentSearchType,这个是列表上方的查询条件

class StudentSearchType extends AbstractType
{public function buildForm(FormBuilderInterface $builder, array $options){$builder->add('firstName', TextType::class, ['label' => 'First Name','required' => false,])->add('lastName', TextType::class, ['label' => 'Last Name','required' => false,])->add('birthdate', DateType::class, ['label' => 'Birth Date','required' => false,'widget' => 'single_text',])->add('search', SubmitType::class, ['label' => 'Search','attr' => ['class' => 'btn btn-primary'],]);;}
}
  1. 实现list.html.twig,实现列表中,查询条件和数据行的展示:
{% extends 'base.html.twig' %}{% block title %}Student List{% endblock %}{% block body %}
<div class="container mt-4"><h1>Student Search</h1>{# 查询表单 #}
{#    {{ form_start(form, { attr: { 'data-turbo': 'false' } }) }}#}{{ form_start(form) }}<div class="row"><div class="col-md-3">{{ form_row(form.firstName) }}</div><div class="col-md-3">{{ form_row(form.lastName) }}</div><div class="col-md-3">{{ form_row(form.birthdate) }}</div><div class="col-md-3 align-self-end">{{ form_row(form.search) }}<a href="{{ path('student_create') }}"class="btn btn-sm btn-outline-primary"><i class="fas fa-edit"></i> create</a></div></div>{{ form_end(form) }}{# 查询结果列表 #}<table class="table table-striped mt-4"><thead><tr><th>First Name</th><th>Last Name</th><th>Birth Date</th><th>Description</th></tr></thead><tbody>{% for student in students %}<tr><td>{{ student.firstName }}</td><td>{{ student.lastName }}</td><td>{{ student.birthdate ? student.birthdate|date('Y-m-d') : '' }}</td><td>{{ student.description }}</td><td>{# 编辑按钮 - 链接到编辑路由 #}<a href="{{ path('student_edit', {id: student.id}) }}"class="btn btn-sm btn-outline-primary"><i class="fas fa-edit"></i> Edit</a>{# 删除按钮 - 使用表单提交防止CSRF #}<form method="post"action="{{ path('student_delete', {id: student.id}) }}"style="display: inline-block;"onsubmit="return confirm('Are you sure to delete this student?');"><input type="hidden" name="_method" value="DELETE"><input type="hidden" name="_token" value="{{ csrf_token('delete' ~ student.id) }}"><button type="submit" class="btn btn-sm btn-outline-danger"><i class="fas fa-trash"></i> Delete</button></form></td></tr>{% else %}<tr><td colspan="4">No records found</td></tr>{% endfor %}</tbody></table>
</div>
{% endblock %}

列表页面,实现的功能有:

  1. 按条件查询学员,并分行展示
  2. 新增学员、编辑学员、删除学员的入口
    image

6、编辑学员

在列表中,定义了编辑学员的入口,现在只需要在StudentController中,定义路由并实现编辑的方法:

    #[Route('/student/{id}', name: 'student_edit')]public function edit(EntityManagerInterface $entityManager, StudentRepository $repository,Request $request, Student $student): Response{if (!$student) {throw $this->createNotFoundException('No student found for id '.$student->getId());}$form = $this->createForm(StudentType::class, $student);$form->handleRequest($request);if ($form->isSubmitted()) {if ($form->isValid()) {$entityManager->persist($student);$entityManager->flush();$this->addFlash('success', 'Student created successfully.');return $this->redirectToRoute('student_list');}}return $this->render('student/edit.html.twig', ['form' => $form,]);}

由于编辑页面与新增页面一样,因此,继续复用edit.html.twig
image

7. 删除学员

在列表中,定义了编辑学员的入口,现在只需要在StudentController中,定义路由并实现删除的方法:

    #[Route('/students/{id}', name: 'student_delete',methods: ['DELETE'])]public function delete(EntityManagerInterface $entityManager, StudentRepository $repository, Student $student): Response{if (!$student) {throw $this->createNotFoundException('No student found for id '.$student->getId());}$entityManager->remove($student);$entityManager->flush();return $this->redirectToRoute('student_list');}

这样,一个简单的学员管理的增、删、查、改就完成了。

http://www.wxhsa.cn/company.asp?id=5599

相关文章:

  • 函数计算进化之路:AI Sandbox 新基座
  • linux通过smb共享文件夹,windows进行连接
  • 强制Apache Web服务器始终使用https
  • 初始vue3
  • 如何在Nginx服务器配置https以及强制跳转https
  • centos7中安装protobuf-c
  • 赞助NYU-Poly女性网络安全研讨会:推动行业多元发展
  • MyEMS:开源能源管理的探索与实践
  • 实时内核中的调度程序节流
  • 配置Burp Suite与Proxifier抓取微信小程序流量
  • 我的ai 相关工具站
  • C#第十一章 023 024
  • MyEMS:赋能每一个组织,成为自己的能源管理专家
  • Vue开发微信公众号上传图片
  • centos7中scrapy运行环境配置
  • flutter配置国内镜像
  • 微信小程序 live-player 无声音
  • 栈的妙用:如何优雅地处理括号匹配难题 (C语言版)
  • 食品包装 AI 视觉检测技术:原理、优势与数据应用解析
  • 电流探头的常见应用场景
  • WebRTC编码过载检测与帧率适应机制分析报告
  • PC桌面应用开发选择
  • 陈燕的项目启动笔记
  • C++面试宝典八股文之什么是封装、继承、多态(附面试宝典八股文PDF)
  • 无需复杂正则:SLS 新脱敏函数让隐私保护更简单高效
  • PLC结构化文本设计模式——适配器模式(Adapter Pattern)
  • DRAM、SRAM、NAND Flash、NOR Flash、EEPROM、MRAM存储器你分得清吗?
  • 【初赛】最短路 次短路 k短路 - Slayer
  • hyperv 安装 ubuntu 压缩磁盘
  • 【实战记录】使用 wp-cli 恢复/修改 WordPress 密码