登录  /  注册
博主信息
博文 22
粉丝 1
评论 0
访问量 19464
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
0214作业(2)-用户登录验证流程异常处理、composer组件安装和自动加载-php培训十期线上班
Dseven
原创
1005人浏览过

1. 作业完成思路

  • 下载安装验证码的composer组件
  • 编写自动加载文件
  • 编写自定义异常处理类
  • 编写登录页面
  • 编写数据验证页面

2. 数据验证逻辑

  • 验证页面请求来源
  • 验证数据传递方法
  • 验证请求内容是否存在
  • 验证输入验证码和系统生成的验证码是否匹配
  • 验证数据库中是否存在登录邮箱
  • 验证登录密码与数据库中的密码是否相同

3.demo

3.1 自动加载文件

  1. namespace php\demo;
  2. //空行
  3. spl_autoload_register(function ($class){
  4. // 设置项目前缀
  5. $prefix = 'php\demo\\';
  6. //空行
  7. // 设置具有项目前缀的类名所对应的类的基目录
  8. $base_dir = __DIR__ . '\src\\';
  9. //空行
  10. // 去掉项目前缀,获取真实的类名称
  11. $real_class = substr($class, strlen($prefix));
  12. // die($real_class);
  13. //空行
  14. // 将命名空间分隔符,替换成目录分隔符
  15. $path = str_replace('\\', DIRECTORY_SEPARATOR, $real_class);
  16. //空行
  17. // 加上基目录和php的后缀'.php'
  18. $file = $base_dir . $path . '.php';
  19. //空行
  20. file_exists($file) ? require $file : die('文件不存在,请重新加载');
  21. });

3.2 自定义异常处理类

  1. //在项目下设置src文件夹,将此类和数据库操作类放入,统一自动加载
  2. //定义命名空间
  3. namespace php\demo\lib;
  4. //导入系统异常处理类
  5. use Exception;
  6. //从系统异常处理类派生一个自定义的子类
  7. class MyException extends Exception{
  8. //使用魔术方法,使得该类的实例作为字符串时输出
  9. public function __toString()
  10. {
  11. //HERDOC的后面不能有空格
  12. return <<< HERDOC
  13. <table border="1" cellspacing="0" cellpadding="5">
  14. <tr bgcolor="#7fffd4">
  15. <th>错误代码</th>
  16. <th>错误内容</th>
  17. <th>错误文件名</th>
  18. <th>错误代码行</th>
  19. </tr>
  20. <tr>
  21. <td>{$this->getCode()}</td>
  22. <td>{$this->getMessage()}</td>
  23. <td>{$this->getFile()}</td>
  24. <td>{$this->getLine()}</td>
  25. </tr>
  26. </table>
  27. HERDOC;
  28. }
  29. }

3.3 登录页面

  1. //定义命名空间
  2. namespace php\demo\part2;
  3. //引入composer中的自动加载
  4. require '../../../../vendor/autoload.php';
  5. //导入验证码组件
  6. use Gregwar\Captcha\CaptchaBuilder;
  7. //实例验证码对象
  8. $builder = new CaptchaBuilder;
  9. //生成一个验证码图片
  10. $builder->build();
  11. //开启会话,使用seeson传递验证码信息
  12. session_start();
  13. $_SESSION['phrase'] = $builder->getPhrase();
  14. ?>
  15. <!DOCTYPE html>
  16. <html lang="en">
  17. <head>
  18. <meta charset="UTF-8">
  19. <title>用户登录页面</title>
  20. <style>
  21. <!-- 省略样式表 -->
  22. </style>
  23. </head>
  24. <body>
  25. <div>
  26. <h2>用户登录</h2>
  27. <form action="demo1.php" method="post">
  28. <span>
  29. <label for="email">邮箱:</label>
  30. <input type="email" name="email" id="email" placeholder="邮箱地址">
  31. </span>
  32. <span>
  33. <label for="password">密码:</label>
  34. <input type="password" name="password" id="password">
  35. </span>
  36. <span>
  37. <label for="validate">验证码:</label>
  38. <input type="text" name="validate" id="validate" class="validate">
  39. <img src="<?php echo $builder->inline(); ?>" alt="" onclick="location.reload()">
  40. </span>
  41. <button>登录</button>
  42. </form>
  43. </div>
  44. </body>
  45. </html>

3.4 数据验证页面

  1. //定义命名空间
  2. namespace php\demo\part2;
  3. //
  4. //引入自定义的自动加载文件
  5. require 'autoload.php';
  6. //
  7. //导入数据库操作和异常处理类
  8. use php\demo\iDbPaparms;
  9. use php\demo\lib\Db;
  10. use php\demo\lib\Db_PDO;
  11. use php\demo\lib\MyException;
  12. //
  13. //开启会话
  14. session_start();
  15. //判断请求来源是否合法
  16. //获取请求页面的来源,利用过滤器进行过滤,利用basename获取页面文件名
  17. $currentName = basename(filter_input(INPUT_SERVER,'HTTP_REFERER',FILTER_VALIDATE_URL));
  18. //设立一个白名单,在数组里的为合法的
  19. $allowName = ['demo2.php'];
  20. //判断请求页面是否在白名单中,如果不在抛出异常
  21. try{
  22. if(!in_array($currentName,$allowName)) throw (new MyException('请求来源非法',101));
  23. } catch (MyException $e){
  24. print $e;
  25. }
  26. //
  27. //判断数据是否是通过post方式传送的
  28. try {
  29. if ($_SERVER['REQUEST_METHOD'] !== 'POST') throw new MyException('传送方式非法',102);
  30. } catch (MyException $e) {
  31. print $e;
  32. }
  33. //
  34. //检查登录邮箱、登录密码、用户输入的验证码、系统生成的验证码是否为空
  35. try {
  36. if (empty($_POST['email'])) throw new MyException('登录邮箱为空',103);
  37. } catch (MyException $e) {
  38. print $e;
  39. }
  40. try {
  41. if (empty($_POST['password'])) throw new MyException('密码为空',104);
  42. } catch (MyException $e) {
  43. print $e;
  44. }
  45. try {
  46. if (empty($_POST['validate'])) throw new MyException('验证码为空',105);
  47. } catch (MyException $e) {
  48. print $e;
  49. }
  50. try {
  51. if (empty($_SESSION['phrase'])) throw new MyException('验证码生成错误',106);
  52. } catch (MyException $e) {
  53. print $e;
  54. }
  55. //
  56. //过滤外部数据
  57. //先将外部变量放入一个数组中,键名为变量名,值为过滤器
  58. $arr = [
  59. 'validate'=>FILTER_SANITIZE_STRING,
  60. 'email'=>FILTER_VALIDATE_EMAIL,
  61. 'password'=>FILTER_SANITIZE_STRING,
  62. ];
  63. //利用filter_input_array过滤函数过滤,该函数第一个参数为变量类型(INPUT_POST/INPUT_SERVER/INPUT_GET...),第二个参数为需要过滤的数组,返回值为过滤后的数组
  64. $arr = filter_input_array(INPUT_POST,$arr);
  65. //
  66. //验证码对比
  67. try {
  68. //将session中保存的系统生成的验证码赋给变量phrase
  69. $phrase = $_SESSION['phrase'];
  70. //将输入的验证码和生成的验证码全部转为小写
  71. $validate = strtolower($arr['validate']);
  72. $phrase = strtolower($phrase);
  73. //对比验证码,如果不对抛出异常
  74. if ($validate !== $phrase) throw new MyException('验证码不符',201);
  75. } catch (MyException $e) {
  76. print $e;
  77. }
  78. //
  79. //2.和数据库中数据进行比对
  80. //准备数据库连接参数
  81. $dsn = iDbPaparms::TYPE . ':host=' . iDbPaparms::HOST . ';dbname=' . iDbPaparms::DBNAME;
  82. //生成利用PDO操作数据库操作的一个对象(这个类是基于自定义接口实现的一个类)
  83. $links = new Db_PDO($dsn, iDbPaparms::USER_NAME, iDbPaparms::PASSWORD);
  84. //利用数据库通用操作类获取结果集(这个类是基于自定义接口实现的一个类),
  85. $result = Db::select($links, "`email`='{$arr['email']}'");
  86. //查询出所有与登录email相同的数据,理论上要么不存在,如果存在应该只有一条
  87. try {
  88. if (empty($result)) throw new MyException('用户不存在',202);
  89. } catch (MyException $e) {
  90. print $e;
  91. }
  92. //如果用户存在,对比登录密码和数据库中的密码
  93. try {
  94. if (sha1($arr['password']) !== $result['password']) throw new MyException('密码错误',203);
  95. } catch (MyException $e) {
  96. print $e;
  97. }
  98. //如果整个过程没有抛出异常,说明登录成功,输出成功信息
  99. if(empty($e)){
  100. // echo '<pre>'.print_r($result,true).'</pre>';
  101. echo $result['name'].',登录成功';
  102. }

4. 运行效果图

4.1 登录页面


4.2 登录成功页面

4.3 登录出现异常页面


5.小结

5.1 自动加载的原理

  • 按照PSR-4的规范,设定命名空间、文件名和文件存放路劲
  • 自定义一个自动加载方法,也就是将命名空间和文件存放路径之间形成一个映射关系
  • 利用spl_autoload_register()注册自定义的自动加载的方法
  • 在需要的文件中引入自动加载页面
  • 文件执行过程中遇到了没有定义的类,会触发自动加载方法
  • 自动加载方法会按照类名在之前映射的文件中查找,因为文件名和类名是一致的,所以就是查找文件名,找到之后进行引入

5.2 composer使用

  • 下载安装好composer之后,在项目中会有一个vendor的文件夹,里面存放着我们下载的composer组件
  • 在vendor文件夹中有一个autoload.php的文件,这个是用来自动加载composer组件的文件,我们需要在使用的文件中引入
  • 引入composer组件的文件之后,需要使用use将我们用到的类进行导入

5.3 异常处理的实现

  • 新建一个继承与系统异常处理类的子类
  • 在类中可以设定对异常发生时提示信息的表达方式
  • 在程序中利用try和catch的组合进行检查,try字面理解就是试试接下来的代码,如果没问题就跳过catch中的代码,如果有问题就实例一个自定义异常对象,并给其赋值
  • 在try中出现异常后,程序进入到catch里面的代码块,输出异常内容(自定义)、异常代码(自定义)、异常文件、异常处的代码行号等。
批改老师:天蓬老师天蓬老师

批改状态:合格

老师批语:写得很棒
本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
作者最新博文
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学