Symfony框架高级功能详解:数据库、表单与安全

打印 上一主题 下一主题

主题 877|帖子 877|积分 2631

Symfony框架高级功能详解:数据库、表单与安全

在当代Web开辟中,数据库利用、表单处置处罚和安全认证是三大焦点功能。Symfony提供了强大的工具和组件来处置处罚这些需求。本指南将详细介绍Symfony的数据库利用、表单处置处罚及安全功能。
1. 数据库与Doctrine ORM

配置数据库连接

Symfony默认使用Doctrine ORM来处置处罚数据库利用。首先,我们需要配置数据库连接信息。
配置数据库连接

在项目根目次下的 .env 文件中,找到并修改以下行:
  1. # .env
  2. DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7"
复制代码
确保您更换了 db_user、db_password 和 db_name 为实际的数据库用户名、暗码和数据库名称。
使用Doctrine ORM进行数据库利用

Doctrine ORM是一个强大的对象关系映射(ORM)工具,能够将数据库表映射到PHP对象。
创建实体(Entity)

实体是与数据库表对应的PHP类。使用Symfony CLI工具生成实体:
  1. php bin/console make:entity
复制代码
按照提示输入实体名和字段信息。例如,创建一个 Product 实体:
  1. Class name of the entity to create or update (e.g. BraveBurger):
  2. > Product
  3. New property name (press <return> to stop adding fields):
  4. > name
  5. Field type (enter ? to see all types) [string]:
  6. > string
  7. Field length [255]:
  8. > 255
  9. New property name (press <return> to stop adding fields):
  10. > price
  11. Field type (enter ? to see all types) [string]:
  12. > float
复制代码
生成的实体类如下:
  1. // src/Entity/Product.php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM;
  4. /**
  5. * @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
  6. */
  7. class Product
  8. {
  9.     /**
  10.      * @ORM\Id
  11.      * @ORM\GeneratedValue
  12.      * @ORM\Column(type="integer")
  13.      */
  14.     private $id;
  15.     /**
  16.      * @ORM\Column(type="string", length=255)
  17.      */
  18.     private $name;
  19.     /**
  20.      * @ORM\Column(type="float")
  21.      */
  22.     private $price;
  23.     // Getters and setters...
  24. }
复制代码
创建数据库表

生成实体后,需要创建数据库表:
  1. php bin/console doctrine:database:create
  2. php bin/console make:migration
  3. php bin/console doctrine:migrations:migrate
复制代码
实体(Entity)与仓储(Repository)模式

仓储模式是一种计划模式,用于抽象和封装数据访问逻辑。Symfony为每个实体自动生成一个仓储类。
使用仓储类

仓储类用于与数据库交互,例如查询和保存实体。以下是一个示例控制器,展示怎样使用 ProductRepository:
  1. // src/Controller/ProductController.php
  2. namespace App\Controller;
  3. use App\Entity\Product;
  4. use App\Repository\ProductRepository;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\Routing\Annotation\Route;
  9. class ProductController extends AbstractController
  10. {
  11.     /**
  12.      * @Route("/product/create", name="product_create")
  13.      */
  14.     public function create(EntityManagerInterface $em): Response
  15.     {
  16.         $product = new Product();
  17.         $product->setName('Sample Product');
  18.         $product->setPrice(19.99);
  19.         $em->persist($product);
  20.         $em->flush();
  21.         return new Response('Product created with ID '.$product->getId());
  22.     }
  23.     /**
  24.      * @Route("/product/{id}", name="product_show")
  25.      */
  26.     public function show(ProductRepository $repository, int $id): Response
  27.     {
  28.         $product = $repository->find($id);
  29.         if (!$product) {
  30.             throw $this->createNotFoundException('Product not found');
  31.         }
  32.         return new Response('Product: '.$product->getName().' - $'.$product->getPrice());
  33.     }
  34. }
复制代码
2. 表单与验证

Symfony表单组件介绍

Symfony的表单组件提供了强大的工具来创建、处置处罚和验证表单。它能够与实体结合,实现数据的高效输入和验证。
创建与处置处罚表单

创建表单类

首先,创建一个表单类:
  1. php bin/console make:form
复制代码
按照提示输入表单类名和关联的实体。例如,创建一个 ProductType 表单类:
  1. // src/Form/ProductType.php
  2. namespace App\Form;
  3. use App\Entity\Product;
  4. use Symfony\Component\Form\AbstractType;
  5. use Symfony\Component\Form\Extension\Core\Type\MoneyType;
  6. use Symfony\Component\Form\Extension\Core\Type\TextType;
  7. use Symfony\Component\Form\FormBuilderInterface;
  8. use Symfony\Component\OptionsResolver\OptionsResolver;
  9. class ProductType extends AbstractType
  10. {
  11.     public function buildForm(FormBuilderInterface $builder, array $options)
  12.     {
  13.         $builder
  14.             ->add('name', TextType::class)
  15.             ->add('price', MoneyType::class);
  16.     }
  17.     public function configureOptions(OptionsResolver $resolver)
  18.     {
  19.         $resolver->setDefaults([
  20.             'data_class' => Product::class,
  21.         ]);
  22.     }
  23. }
复制代码
渲染表单

在控制器中处置处罚和渲染表单:
  1. // src/Controller/ProductController.php
  2. namespace App\Controller;
  3. use App\Entity\Product;
  4. use App\Form\ProductType;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  7. use Symfony\Component\HttpFoundation\Request;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\Routing\Annotation\Route;
  10. class ProductController extends AbstractController
  11. {
  12.     /**
  13.      * @Route("/product/new", name="product_new")
  14.      */
  15.     public function new(Request $request, EntityManagerInterface $em): Response
  16.     {
  17.         $product = new Product();
  18.         $form = $this->createForm(ProductType::class, $product);
  19.         $form->handleRequest($request);
  20.         if ($form->isSubmitted() && $form->isValid()) {
  21.             $em->persist($product);
  22.             $em->flush();
  23.             return $this->redirectToRoute('product_show', ['id' => $product->getId()]);
  24.         }
  25.         return $this->render('product/new.html.twig', [
  26.             'form' => $form->createView(),
  27.         ]);
  28.     }
  29. }
复制代码
创建表单模板

在 templates/product/new.html.twig 中渲染表单:
  1. {# templates/product/new.html.twig #}
  2. {% extends 'base.html.twig' %}
  3. {% block body %}
  4.     <h1>Create new Product</h1>
  5.     {{ form_start(form) }}
  6.         {{ form_widget(form) }}
  7.         <button class="btn">{{ button_label|default('Save') }}</button>
  8.     {{ form_end(form) }}
  9. {% endblock %}
复制代码
表单验证与自定义验证器

Symfony内置了多种验证器,可以在实体类中使用注解进行配置:
  1. // src/Entity/Product.php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM;
  4. use Symfony\Component\Validator\Constraints as Assert;
  5. /**
  6. * @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
  7. */
  8. class Product
  9. {
  10.     // ...
  11.     /**
  12.      * @ORM\Column(type="string", length=255)
  13.      * @Assert\NotBlank
  14.      * @Assert\Length(
  15.      *      min = 3,
  16.      *      max = 255,
  17.      *      minMessage = "The name must be at least {{ limit }} characters long",
  18.      *      maxMessage = "The name cannot be longer than {{ limit }} characters"
  19.      * )
  20.      */
  21.     private $name;
  22.     /**
  23.      * @ORM\Column(type="float")
  24.      * @Assert\NotBlank
  25.      * @Assert\Positive
  26.      */
  27.     private $price;
  28.     // ...
  29. }
复制代码
自定义验证器

您可以创建自定义验证器来实现更复杂的验证逻辑:
  1. // src/Validator/Constraints/ContainsAlphanumeric.php
  2. namespace App\Validator\Constraints;
  3. use Symfony\Component\Validator\Constraint;
  4. /**
  5. * @Annotation
  6. */
  7. class ContainsAlphanumeric extends Constraint
  8. {
  9.     public $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.';
  10. }
  11. // src/Validator/Constraints/ContainsAlphanumericValidator.php
  12. namespace App\Validator\Constraints;
  13. use Symfony\Component\Validator\Constraint;
  14. use Symfony\Component\Validator\ConstraintValidator;
  15. class ContainsAlphanumericValidator extends ConstraintValidator
  16. {
  17.     public function validate($value, Constraint $constraint)
  18.     {
  19.         if (!preg_match('/^[a-zA-Z0-9]+$/', $value, $matches)) {
  20.             $this->context->buildViolation($constraint->message)
  21.                 ->setParameter('{{ string }}', $value)
  22.                 ->addViolation();
  23.         }
  24.     }
  25. }
复制代码
在实体中使用自定义验证器:
  1. use App\Validator\Constraints as AppAssert;
  2. class Product
  3. {
  4.     // ...
  5.     /**
  6.      * @ORM\Column(type="string", length=255)
  7.      * @AppAssert\ContainsAlphanumeric
  8.      */
  9.     private $name;
  10.     // ...
  11. }
复制代码
3. 安全与用户认证

Symfony安全组件介绍

Symfony的安全组件提供了全面的用户认证和授权解决方案,支持表单登录、LDAP、OAuth等多种认证方式。
用户认证与授权

配置安全防火墙

在 config/packages/security.yaml 中配置安全防火墙:
  1. # config/packages/security.yaml
  2. security:
  3.     encoders:
  4.         App\Entity\User:
  5.             algorithm: bcrypt
  6.     providers:
  7.         app_user_provider:
  8.             entity:
  9.                 class: App\Entity\User
  10.                 property: email
  11.     firewalls:
  12.         main:
  13.             anonymous: true
  14.             form_login:
  15.                 login_path: login
  16.                 check_path: login
  17.                 default_target_path: /dashboard
  18.     access_control:
  19.         - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
  20.         - { path: ^/dashboard, roles: ROLE_USER }
复制代码
创建用户实体

用户实体需要实现 UserInterface 和 PasswordAuthenticatedUserInterface 接口:
  1. // src/Entity/User.php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM;
  4. use Symfony\Component\Security\Core\User\UserInterface;
  5. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  6. /**
  7. * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
  8. */
  9. class User implements UserInterface, PasswordAuthenticatedUserInterface
  10. {
  11.     // ...
  12.     /**
  13.      * @ORM\Column(type="string", length=180, unique=true)
  14.      */
  15.     private $email;
  16.     /**
  17.      * @ORM\Column(type="string")
  18.      */
  19.     private $password;
  20.     /**
  21.      * @ORM\Column(type="json")
  22.      */
  23.     private $roles = [];
  24.     // Getters and setters...
  25.     public function getRoles(): array
  26.     {
  27.         $roles = $this->roles;
  28.         $roles[] = 'ROLE_USER';
  29.         return array_unique($roles);
  30.     }
  31.     public function getPassword(): string
  32.     {
  33.         return $this->password;
  34.     }
  35.     public function getUsername(): string
  36.     {
  37.         return $this->email;
  38.     }
  39.     public function eraseCredentials()
  40.     {
  41.         // If you store any temporary, sensitive data on the user, clear it here
  42.     }
  43. }
复制代码
创建登录表单

创建一个登录表单类:
  1. // src/Form/LoginFormType.php
  2. namespace App\Form;
  3. use Symfony\Component\Form\AbstractType;
  4. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  5. use Symfony\Component\Form\Extension\Core\Type\PasswordType;
  6. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  7. use Symfony\Component\Form\FormBuilderInterface;
  8. use Symfony\Component\OptionsResolver\OptionsResolver;
  9. class LoginFormType extends AbstractType
  10. {
  11.     public function buildForm(FormBuilderInterface $builder, array $options)
  12.     {
  13.         $builder
  14.             ->add('email', EmailType::class)
  15.             ->add('password', PasswordType::class)
  16.             ->add('login', SubmitType::class);
  17.     }
  18.     public function configureOptions(OptionsResolver $resolver)
  19.     {
  20.         $resolver->setDefaults([
  21.             // Configure your form options here
  22.         ]);
  23.     }
  24. }
复制代码
创建一个控制器来处置处罚登录请求:
  1. // src/Controller/SecurityController.php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Response;
  6. use Symfony\Component\Routing\Annotation\Route;
  7. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  8. class SecurityController extends AbstractController
  9. {
  10.     /**
  11.      * @Route("/login", name="login")
  12.      */
  13.     public function login(AuthenticationUtils $authenticationUtils): Response
  14.     {
  15.         $error = $authenticationUtils->getLastAuthenticationError();
  16.         $lastUsername = $authenticationUtils->getLastUsername();
  17.         return $this->render('security/login.html.twig', [
  18.             'last_username' => $lastUsername,
  19.             'error' => $error,
  20.         ]);
  21.     }
  22. }
复制代码
创建登录表单模板:
  1. {# templates/security/login.html.twig #}
  2. {% extends 'base.html.twig' %}
  3. {% block body %}
  4.     <h1>Login</h1>
  5.     {% if error %}
  6.         <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
  7.     {% endif %}
  8.     <form action="{{ path('login') }}" method="post">
  9.         <label for="username">Email:</label>
  10.         <input type="text" id="username" name="_username" value="{{ last_username }}" required autofocus>
  11.         <label for="password">Password:</label>
  12.         <input type="password" id="password" name="_password" required>
  13.         <button type="submit">Login</button>
  14.     </form>
  15. {% endblock %}
复制代码
自定义用户提供者与权限管理

自定义用户提供者

用户提供者用于从数据源加载用户信息。您可以创建自定义用户提供者:
  1. // src/Security/UserProvider.php
  2. namespace App\Security;
  3. use App\Entity\User;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  6. use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
  7. use Symfony\Component\Security\Core\User\UserInterface;
  8. use Symfony\Component\Security\Core\User\UserProviderInterface;
  9. class UserProvider implements UserProviderInterface
  10. {
  11.     private $entityManager;
  12.     public function __construct(EntityManagerInterface $entityManager)
  13.     {
  14.         $this->entityManager = $entityManager;
  15.     }
  16.     public function loadUserByUsername(string $username)
  17.     {
  18.         $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $username]);
  19.         if (!$user) {
  20.             throw new UsernameNotFoundException(sprintf('User with email "%s" not found.', $username));
  21.         }
  22.         return $user;
  23.     }
  24.     public function refreshUser(UserInterface $user)
  25.     {
  26.         if (!$user instanceof User) {
  27.             throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
  28.         }
  29.         return $this->entityManager->getRepository(User::class)->find($user->getId());
  30.     }
  31.     public function supportsClass(string $class)
  32.     {
  33.         return User::class === $class;
  34.     }
  35. }
复制代码
在 security.yaml 中配置自定义用户提供者:
  1. # config/packages/security.yaml
  2. security:
  3.     providers:
  4.         app_user_provider:
  5.             id: App\Security\UserProvider
复制代码
权限管理

在Symfony中,您可以通过脚色和权限来管理用户访问控制。以下示例展示了怎样在控制器中检查用户权限:
  1. // src/Controller/AdminController.php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\HttpFoundation\Response;
  5. use Symfony\Component\Routing\Annotation\Route;
  6. class AdminController extends AbstractController
  7. {
  8.     /**
  9.      * @Route("/admin", name="admin_dashboard")
  10.      */
  11.     public function dashboard(): Response
  12.     {
  13.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  14.         return new Response('Admin dashboard');
  15.     }
  16. }
复制代码
通过这些高级功能,您可以更好地管理Symfony应用步伐的数据库利用、表单处置处罚和用户安全认证。继承深入学习和探索Symfony的其他功能,您将发现更多强大的工具和技能,帮助您构建高效、健壮的Web应用步伐。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表