使用php创建一个注册表单,如何实现一个简单的注册表单

创建一个注册表单是非常容易的 - 它事实上意味着,你只需要创建一个表单,表单将更新一些User的模型对象(这个例子是一个Doctrine实体)并保存它。

受欢迎的FOSUserBundle 提供了一个注册表单,重置密码表单和其他用户管理功能。

如果你先前没有一个User实体和能工作的登录系统,你要先从怎样从数据库加载安全用户开始。

你的User实体至少应该有以下字段:

username

他是用来登录的,除非你想用email来替代你的用户(在那种情况下,这个字段就不是必要的了)。

email

这是一条不错的信息,很值得收集。您也可以允许用户通过email登录。

password

编译的密码

plainPassword

这个字段不会被持久化:(注意没有上面的@ORM\Column)。他将临时存储注册表单的明文密码。此字段可以被验证,然后被用于password字段的填充。

添加了一些验证,你的类可能看起来像这样:

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

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95// src/AppBundle/Entity/User.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use Symfony\Component\Validator\Constraints as Assert;

use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

use Symfony\Component\Security\Core\User\UserInterface;

/**

* @ORM\Entity

* @UniqueEntity(fields="email", message="Email already taken")

* @UniqueEntity(fields="username", message="Username already taken")

*/

class User implements UserInterface

{

/**

* @ORM\Id

* @ORM\Column(type="integer")

* @ORM\GeneratedValue(strategy="AUTO")

*/

private $id;

/**

* @ORM\Column(type="string", length=255, unique=true)

* @Assert\NotBlank()

* @Assert\Email()

*/

private $email;

/**

* @ORM\Column(type="string", length=255, unique=true)

* @Assert\NotBlank()

*/

private $username;

/**

* @Assert\NotBlank()

* @Assert\Length(max=4096)

*/

private $plainPassword;

/**

* The below length depends on the "algorithm" you use for encoding

* the password, but this works well with bcrypt.

*

* @ORM\Column(type="string", length=64)

*/

private $password;

// other properties and methods

public function getEmail()

{

return $this->email;

}

public function setEmail($email)

{

$this->email = $email;

}

public function getUsername()

{

return $this->username;

}

public function setUsername($username)

{

$this->username = $username;

}

public function getPlainPassword()

{

return $this->plainPassword;

}

public function setPlainPassword($password)

{

$this->plainPassword = $password;

}

public function setPassword($password)

{

$this->password = $password;

}

public function getSalt()

{

// The bcrypt algorithm doesn't require a separate salt.

// You *may* need a real salt if you choose a different encoder.

return null;

}

// other methods, including security methods like getRoles()

}

UserInterface要求要有一些其他的方法,并且你的security.yml文件需要被正确配置,来让User实体工作。更多完整的例子,参见实体提供器文章。

为什么限制4096密码 ¶

注意,plainPassword字段的最大长度是4096字符。为了安全起见(CVE-2013-5750),当编译它时,Symfony限制明文密码长度到4096字符。添加此约束来确保如果有人尝试了一个超长的密码,你的表单应该提示一个验证错误。

你需要添加这个约束到你应用程序任何需要用户提交明文密码的地方(如,修改密码表单)。唯一不需要你担心的就是你的登录表单,因为symfony安全组件会替你处理。

为实体创建一个表单 ¶

下一步,给User实体创建表单:

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// src/AppBundle/Form/UserType.php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;

use Symfony\Component\Form\FormBuilderInterface;

use Symfony\Component\OptionsResolver\OptionsResolver;

use Symfony\Component\Form\Extension\Core\Type\EmailType;

use Symfony\Component\Form\Extension\Core\Type\TextType;

use Symfony\Component\Form\Extension\Core\Type\RepeatedType;

use Symfony\Component\Form\Extension\Core\Type\PasswordType;

class UserType extends AbstractType

{

public function buildForm(FormBuilderInterface $builder, array $options)

{

$builder

->add('email', EmailType::class)

->add('username', TextType::class)

->add('plainPassword', RepeatedType::class, array(

'type' => PasswordType::class,

'first_options' => array('label' => 'Password'),

'second_options' => array('label' => 'Repeat Password'),

)

);

}

public function configureOptions(OptionsResolver $resolver)

{

$resolver->setDefaults(array(

'data_class' => 'AppBundle\Entity\User',

));

}

}

这里有两个字段:email, username 和 plainPassword(重复确认输入的密码)。

探索更多关于表单组件的事情,请阅读表单指南。

处理表单提交 ¶

下一步,你需要一个控制器去处理表单渲染和提交。如果表单被提交,控制器执行验证并保存数据到数据库:

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

41

42

43

44

45

46// src/AppBundle/Controller/RegistrationController.php

namespace AppBundle\Controller;

use AppBundle\Form\UserType;

use AppBundle\Entity\User;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Symfony\Component\HttpFoundation\Request;

class RegistrationController extends Controller

{

/**

* @Route("/register", name="user_registration")

*/

public function registerAction(Request $request)

{

// 1) build the form

$user = new User();

$form = $this->createForm(UserType::class, $user);

// 2) handle the submit (will only happen on POST)

$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {

// 3) Encode the password (you could also do this via Doctrine listener)

$password = $this->get('security.password_encoder')

->encodePassword($user, $user->getPlainPassword());

$user->setPassword($password);

// 4) save the User!

$em = $this->getDoctrine()->getManager();

$em->persist($user);

$em->flush();

// ... do any other work - like sending them an email, etc

// maybe set a "flash" success message for the user

return $this->redirectToRoute('replace_with_some_route');

}

return $this->render(

'registration/register.html.twig',

array('form' => $form->createView())

);

}

}

在安全配置中配置上面步骤3的编码器,来定义用于编译密码的算法:

1

2

3

4# app/config/security.ymlsecurity:encoders:AppBundle\Entity\User:bcrypt

1

2

3

4

5

6

7

8

9

10

11

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:srv="http://symfony.com/schema/dic/services"

xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

bcrypt

1

2

3

4

5

6// app/config/security.php

$container->loadFromExtension('security', array(

'encoders' => array(

'AppBundle\Entity\User' => 'bcrypt',

),

));

这个案例我们推荐使用bcrypt 算法。了解更多关于如何编码用户密码的细节请看安全章节。

如果您决定不使用注释方式的路由(如上),那么你需要创建一个这个控制器的路由:

1

2

3

4# app/config/routing.ymluser_registration:path: /registerdefaults:{ _controller:AppBundle:Registration:register }

1

2

3

4

5

6

7

8

9

10

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

AppBundle:Registration:register

1

2

3

4

5

6

7

8

9

10// app/config/routing.php

use Symfony\Component\Routing\RouteCollection;

use Symfony\Component\Routing\Route;

$collection = new RouteCollection();

$collection->add('user_registration', new Route('/register', array(

'_controller' => 'AppBundle:Registration:register',

)));

return $collection;

下一步,创建模板:

1

2

3

4

5

6

7

8

9

10{# app/Resources/views/registration/register.html.twig #}

{{ form_start(form) }}

{{ form_row(form.username) }}

{{ form_row(form.email) }}

{{ form_row(form.plainPassword.first) }}

{{ form_row(form.plainPassword.second) }}

Register!

{{ form_end(form) }}

1

2

3

4

5

6

7

8

9

10

11

<?php echo $view['form']->start($form) ?>

<?php echo $view['form']->row($form['username']) ?>

<?php echo $view['form']->row($form['email']) ?>

<?php echo $view['form']->row($form['plainPassword']['first']) ?>

<?php echo $view['form']->row($form['plainPassword']['second']) ?>

Register!

<?php echo $view['form']->end($form) ?>

参见如何自定义表单渲染,里面有更多细节。

更新你的数据库结构 ¶

如果你在这个教程中已经更新了User实体,你必须要使用下面的命令去更新数据库结构:

1$ php bin/console doctrine:schema:update --force

就是这样!来到/register来尝试一下吧!

注册表单只有Email(没有 Username) ¶

如果你想要你的用户通过email登录并不需要用户名,那么你可以从你的User实体中彻底移除他。相反,让getUsername()返回email属性:

1

2

3

4

5

6

7

8

9

10

11

12

13

14// src/AppBundle/Entity/User.php

// ...

class User implements UserInterface

{

// ...

public function getUsername()

{

return $this->email;

}

// ...

}

下一步,只更改你security.yml文件的providers 部分,以便Symfony知道如何去通过email属性加载你的用户来登录。参见如何自定义表单渲染。

添加一个“打上勾”的Checkbox ¶

有时,你想要一个“你接受这个条款和声明吗?”的Checkbox,出现在你的注册表单。唯一窍门,让你要去添加这个字段到你的表单中,而你永远不需要添加多余的termsAccepted属性到你的User实体。

要做到这一点,要添加一个termsAccepted字段到你的表单,但设置它的 mapped 选项为false:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20// src/AppBundle/Form/UserType.php

// ...

use Symfony\Component\Validator\Constraints\IsTrue;

use Symfony\Component\Form\Extension\Core\Type\CheckboxType;

use Symfony\Component\Form\Extension\Core\Type\EmailType;

class UserType extends AbstractType

{

public function buildForm(FormBuilderInterface $builder, array $options)

{

$builder

->add('email', EmailType::class);

// ...

->add('termsAccepted', CheckboxType::class, array(

'mapped' => false,

'constraints' => new IsTrue(),

))

);

}

}

constraints配置也被使用了,它允许我们添加验证,尽管没有User中没有termsAccepted属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 图片不让下载,php让图片可以下载的方法

php让图片可以下载的方法发布于 2014-10-04 11:16:18 | 102 次阅读 | 评论: 0 | 来源: 网友投递PHP开源脚本语言PHP(外文名: Hypertext Preprocessor&#xff0c;中文名&#xff1a;“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点&#xff0c;…

while语法php格式,PHP While 循环

循环执行代码块指定的次数&#xff0c;或者当指定的条件为真时循环执行代码块。PHP 循环在您编写代码时&#xff0c;您经常需要让相同的代码块一次又一次地重复运行。我们可以在代码中使用循环语句来完成这个任务。在 PHP 中&#xff0c;提供了下列循环语句&#xff1a;while–…

【转】一句话的设计模式

转自&#xff1a;http://www.cnblogs.com/lzhlyle/p/4696645.html 如题&#xff0c;实际上&#xff0c;我想这是很困难的。 除非——只是为了给自己做一个提醒&#xff0c;能够看一眼就快速回想起该设计模式的种种记忆。 下列是我之前在学习《大话设计模式》时做的笔记总结&…

php代码导入sql,php导入SQL文件(示例代码)

/*************PHP导入.sql文件运行版本:php5,php4作者:panxp邮件:coolpan123gmail.com*编辑整理&#xff1a;bbs.it-home.org**************/$host "localhost";$user "root";$pwd "";$file_dir dirname(__FILE__);$file_name "bar.s…

jQuery遍历Json数组

var jsonArray [{ "name": "张三", "password": "123456"},{ "name": "李四", "password": "123456"}]; $.each(obj, function (n, value) { n&#xff1a;数组中的位置&#xff1b; val…

php自动获取m3u8,PHP自动Get监控源码分享

使用方法&#xff1a;创建个PHP文件放到你的网站根目录里面&#xff0c;访问后不会出现结果&#xff0c;等待个20秒左右关闭页面&#xff0c;就会自动执行了。如果不重启php服务器 或者重启服务器&#xff0c;get监控一直会处于运行状态。测试了一下 秒赞网的监控&#xff0c;效…

Vertex and Fragment Shader

Semantics语义词&#xff1a;   定义&#xff1a;GPU工作时&#xff0c;数据通常暂存在寄存器&#xff0c;那么在Cg中&#xff0c;语义词就指定了输入/输出数据和图形硬件寄存器之间的映射关系。   原理&#xff1a;根据输入语义&#xff0c;图形处理器从某个寄存器取数据&…

linux php cgi.sock,nginx中unix:/tmp/php-cgi.sock错误解决解决

出现这种问题一般是因为/tmp/php-cgi.sock功能是负责流量最主要的特征就是unix socket比tcp快,下面来解决办法。首先建立/tmp/php-cgi.sock文件&#xff0c;然后将之改所有者改为www-data&#xff1a;#我直接改成nginx的用户&#xff0c;好像必须要属于nginx的用户组才能正常使…

erlang套接字

Erlang的套接字可以有三种打开模式&#xff1a;主动&#xff08;active&#xff09;、单次主动&#xff08;active once&#xff09;或被动&#xff08;passive&#xff09;。这是通过在gen_tcp:connect(Address, Port, Options)或gen_tcp:listen(Port, Options)的Options参数里…

php 类学习,php的类学习(一)

function __autoload($class_name){//require_once语句在脚本执行期间包含并运行指定文件。此行为和 require()语句完全相同&#xff0c;唯一区别是如果该文件中的代码已经被包含了&#xff0c;则不会再次包含require_once $class_name . .php;}$obj new testAAA();$obj2new ty…

前端学习(1575):复习todoMVC

系统再演示一下angular的实现原理流程 分装实现 两个文件 js和html

蛋疼的中文编码及其计算机编码历史

更好的博客&#xff1a;http://my.oschina.net/goldenshaw/blog?catalog536953 一&#xff1a;编码发展&#xff1a; 1 ANSI编码&#xff1a;计算机在美国出现&#xff0c;使用单字节8位编码&#xff0c;共可以表示255个状态。&#xff08;0-32&#xff08;0x00-0x20&#xff…

java异常处理机简答题,【简答题】JAVA 语言如何进行异常处理,关键字: throws,throw,try,catch,finally 分别代表什么意义?...

【简答题】JAVA 语言如何进行异常处理&#xff0c;关键字&#xff1a; throws,throw,try,catch,finally 分别代表什么意义&#xff1f;更多相关问题用蒸汽进行设备管线吹扫时,应将被吹扫的设备管线,相应部位仪表引线阀关闭,防止损坏仪表。()铝壶内装有2.5kg的水&#xff0c;其温…

阐述linux IPC(五岁以下儿童):system V共享内存

【版权声明&#xff1a;尊重原创。转载请保留源&#xff1a;blog.csdn.net/shallnet 要么 .../gentleliu&#xff0c;文章学习交流&#xff0c;不用于商业用途】system V共享内存和posix共享内存类似&#xff0c;system V共享内存是调用shmget函数和shamat函数。 shmget函数创…

php io select,Python IO多路复用之——select方案服务端和客户端代码【python源码详解】...

准备文件&#xff1a;IO.py 服务端代码tcp_c.py 客户端代码IO.py 代码&#xff1a;from select import * #引入 select 模块from socket import * #引入 socket 模块s socket() #实例化一个socket 对象s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #设置端口可重用s.bind((0.0.0…

NDK和项目依赖

NDK使用 JDK:Java Development KitSDK:Software Development KitNDK:Native Development KitJNI: Java Nattive InterfaceNDK开发流程&#xff1a; 下载NDK并配置NDK路径新建项目 修改build.gradle文件 替换classpath:com.android.tools.build:gradle-experimental:0.4.0 替换a…