YP.Lam | Symfony 4 the new way

Symfony 4 the new way

Symfony 5 已经发布了一段时间,Symfony 4 也出了 4.4 LTS 版本,于是准备把手上一个历史遗留项目升级到 4.4,然而一动手就遇到麻烦,因为现在官方已经不推荐使用之前那种传统的大 bundle,而是倾向于更通用的组件(作为一个从 Symfony 2 过来的用户,不得不说挺支持官方的做法,因为经常会因为有 bundle 不及时更新而导致 composer 冲突)。

本文章将尝试从头开始创建一个 Symfony 4 基础应用。

搭建 Docker 开发环境

Docker 在持续集成与环境部署方面提供不少便利性,因此此项目用 Docker 作为开发环境,发布环境还是使用之前比较熟悉的 deployer。

习惯上 docker-compose.yml 放根目录,项目源码放 src 下,各个镜像基本上是按官方配置,然后适当修改一下

version: '3.7'
services:
  nginx:
    build:
      context: ./docker/nginx
    ports: ["80:80"]
    volumes:
      - ./.:/www
      - ./docker/nginx/nginx-sites.conf:/etc/nginx/conf.d/site.conf
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./data/log/nginx:/var/log/nginx
    links:
      - php73fpm
  
  php73fpm:
    build:
      context: ./docker/php73fpm
      args:
        TIMEZONE: Asia/Shanghai
    links:
      - mysql
    volumes:
      - ./.:/www
      - ./data/composer:/var/www/.composer
    entrypoint: 
      - /bin/sh
      - -c 
      - ip -4 route list match 0/0 | awk '{print $$3" host.docker.internal"}' >> /etc/hosts && php-fpm
  
  mysql:
    image: percona:5.7
    ports: ['3306:3306']
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=symfony
      - MYSQL_USER=symfony
      - MYSQL_PASSWORD=123456
    volumes:
      - ./data/mysql_data:/var/lib/mysql
      - ./docker/mysql/mysql-docker.cnf:/etc/mysql/conf.d/docker.cnf
  

创建应用

官方提供两种方式创建 Symfony 应用,个人更倾向于 composer

composer create-project symfony/website-skeleton:4.4.* .

开始之前也可以先配置一下 composer 国内镜像:

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

用户登录

以前 fosuserbundle 可以说是第一个必装的 bundle,因为太方便了,配置两下就可以具备完整的用户注册、登录、召回密码等功能,然而因为用户管理可以说是一个网站的基石功能,用上了 fosuserbundle 反而会影响到系统的灵活性,并且 fosuserbundle 为了通用与兼容性,会带来一下不太想要的复杂性。

可能官方已经注意到这个情况,所以提供了一个 maker 命令生成模板。

先创建用户:

bin/console make:user

按需求选择各选项。因为我们要兼容旧版的密码加密方式,所以需要手动加上 salt 等字段:

bin/console make:entity User

系统会自动生成User Entity并且配置使用:

created: src/Entity/User.php
created: src/Repository/UserRepository.php
updated: src/Entity/User.php
updated: config/packages/security.yaml

新版本的 Symfony 的用户密码加密方式有所改变,为了兼容旧版,并且为了后续的灵活性,这里需要创建一个 App 的 UserProvider。关于密码加密方式兼容相关的信息可以参考: https://symfony.com/doc/4.4/security/password_migration.html

use HWI\Bundle\OAuthBundle\Connect\AccountConnectorInterface;
use HWI\Bundle\OAuthBundle\Form\RegistrationFormHandlerInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class UserProvider implements UserProviderInterface, PasswordUpgraderInterface, OAuthAwareUserProviderInterface, AccountConnectorInterface, RegistrationFormHandlerInterface

这里的 UserProvider 除了实现基本功能外,还增加了对 HWIOAuthBundle 的支持。