跳转至

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 下,各个镜像基本上是按官方配置,然后适当修改一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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

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

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

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

用户登录

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

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

先创建用户:

1
bin/console make:user

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

1
bin/console make:entity User

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

1
2
3
4
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

1
2
3
4
5
6
7
8
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 的支持。