结合登录页-PHP基础知识点解析

文章目录


前言


结合常见的登录页,来入门PHP,掌握基础知识

📚 PHP 基础知识点解析

第1行:<?php

php 复制代码
<?php

知识点:PHP开始标签

  • <?php 是 PHP 代码的开始标记
  • 告诉服务器"从这里开始是 PHP 代码"
  • PHP 代码必须写在 <?php?> 之间
  • 文件最后一行可以省略 ?>(推荐做法)

第2行:命名空间

php 复制代码
namespace app\admin\controller;

知识点:什么是命名空间?

想象一个图书馆:

  • 有很多书架(命名空间)
  • 每个书架上有很多书(类)
  • 为了找到特定的书,你需要知道它在哪个书架

app\admin\controller 就是这个类所在的"书架位置"

复制代码
app\           → 应用目录
  admin\       → admin模块
    controller\ → 控制器目录

为什么需要? 防止不同地方有同名的类冲突。


第3-8行:引入类文件

php 复制代码
use think\Controller;
use think\Db;
use think\facade\Request;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Config;

知识点:use 关键字(导入类)

use 就像"借书":

  • use think\Controller = "我要借用 ThinkPHP 框架里的 Controller 类"
  • 之后在代码里就可以直接写 Controller,不用写完整路径

类比理解:

php 复制代码
use think\Controller;
相当于:
require "框架路径/Controller.php";

6个引入的类:

作用 类比
think\Controller 控制器基类 模板框架
think\Db 数据库操作类 数据库工具箱
think\facade\Request 请求处理 收件员(接收请求)
think\facade\Cache 缓存管理 记事本(临时存储)
think\facade\Cookie Cookie管理 贴纸(浏览器存储)
think\facade\Config 配置管理 设置文件

第10行:定义类

php 复制代码
class Login extends Controller

知识点:类和方法

php 复制代码
class 类名
├── extends 继承(基于某个类创建)
└── { 代码 }
  • class Login = 定义一个叫 Login 的类
  • extends Controller = 继承 ThinkPHP 的 Controller 基类
  • 就像"继承家业",子类可以使用父类的所有功能

类比理解:

php 复制代码
class Login extends Controller
     ↓              ↓
    儿子           父亲
儿子继承了父亲的功能,同时还自己的方法

第12行:定义属性

php 复制代码
private $db;

知识点:变量(属性)和作用域

php 复制代码
private $db;
     ↓     ↓
 私有   变量名
 类型
关键字 含义 谁能访问
private 私有 只有这个类内部能访问
public 公共 任何地方都能访问
protected 保护 只有自己和子类能访问

$db 这个变量用来存储数据库连接对象。


第13-21行:构造函数

php 复制代码
public function __construct(){
    parent::__construct();
    
    $db_host = Config::get('database.hostname');
    $db_user = Config::get('database.username');
    $db_pwd = Config::get('database.password');
    $db_port = Config::get('database.hostport');
    
    $this->db = Db::connect('mysql://'.$db_user.':'.$db_pwd.'@'.$db_host.':'.$db_port.'/ym_manage#utf8');
}

知识点:构造函数 __construct()

  • 什么是构造函数? 对象被创建时自动运行的函数

  • 什么时候运行? new Login() 时自动执行

    new Login() → 自动调用 __construct()

逐行解析:

php 复制代码
public function __construct(){
              ↓
           构造函数(创建对象时自动调用)
php 复制代码
parent::__construct();
     ↓      ↓
  父类   调用父类的方法
  • parent::__construct() = 调用父类的构造函数
  • ThinkPHP 要求:子类构造函数必须调用父类构造函数
php 复制代码
$db_host = Config::get('database.hostname');
  • 从配置文件中读取数据库地址
  • $db_host 存储"主机地址"(如 127.0.0.1)
php 复制代码
$this->db = Db::connect('mysql://...');
  • Db::connect() = 建立数据库连接
  • $this->db = 把连接对象存到当前实例的 $db 属性
  • mysql://用户名:密码@地址:端口/数据库名#编码

第23-29行:显示登录页面

php 复制代码
public function login()
{
    $ht_name = Config::get('app.HT_NAME');
    $this->assign('ht_name',$ht_name);
    
    return $this->fetch();
}

知识点:方法(函数)

php 复制代码
public function 方法名()
         ↓
      公开方法

逐行解析:

php 复制代码
public function login()
  • 定义一个公开方法叫 login()
  • 用户访问 /admin/login/login 时触发
php 复制代码
$ht_name = Config::get('app.HT_NAME');
  • 读取应用配置中的站点名称
  • 之前我们看到 HT_NAME = "Dreamcasino"
php 复制代码
$this->assign('ht_name',$ht_name);
  • 把变量传递给视图模板
  • 语法:$this->assign('模板变量名', PHP变量)
php 复制代码
return $this->fetch();
  • fetch() = 渲染视图模板
  • return = 返回渲染后的 HTML 内容

执行流程:

复制代码
用户访问 /admin/login/login
    ↓
执行 login() 方法
    ↓
读取配置、分配变量
    ↓
渲染视图文件 → 返回 HTML
    ↓
浏览器显示登录页面

第31-54行:处理登录请求

php 复制代码
public function doLogin()
{
    // 第1步:获取表单数据
    $data = Request::post();
    
    // 第2步:验证数据
    if(empty($data)){ die('参数有误'); }
    if(isset($data['username']) && empty($data['username'])){ die('参数有误'); }
    if(isset($data['password']) && empty($data['password'])){ die('参数有误'); }
    
    // 第3步:获取用户名密码
    $username = $data['username'];
    $password = $data['password'];
    
    // 第4步:查询数据库验证用户
    $res = $this->db->table('admin')
                     ->where('username',$username)
                     ->where('isagent','0')
                     ->find();
    if(empty($res)){ die('登录失败'); }
    
    // 第5步:验证密码
    $passwd = md5($password.$res['salt']);
    if($passwd == $res['password']){
        
        // 登录成功:写Cookie和Redis
        Cookie::set('admin_user_id',$res['id'],3600*2);    // 浏览器Cookie
        Cache::store('redis')->set('admin_user_'.$res['id'],'login',3600*2);  // Redis缓存
        
        die('success');
    }
    
    // 第6步:登录失败
    die('登录失败');
}

知识点详解:

1. Request::post() - 获取POST数据
php 复制代码
$data = Request::post();
  • Request = 请求类(收件员)
  • ::post() = 静态方法(不用创建对象直接调用)
  • 作用:获取表单POST提交的数据

类比:

复制代码
POST数据就像邮寄的包裹
Request.post() = 打开包裹,取出里面的东西
2. empty()isset() - 判断变量
php 复制代码
empty($data)                    // 判断$data是否为空
isset($data['username'])        // 判断$data['username']是否存在
empty($data['username'])        // 判断是否为空字符串
函数 作用
isset() 判断变量是否存在
empty() 判断是否为空(包括0、""、null、false)
3. die() - 终止脚本
php 复制代码
die('参数有误');
  • die() = 输出内容并终止脚本
  • 类似 exit()
4. 数据库链式查询
php 复制代码
$res = $this->db->table('admin')
                ->where('username', $username)
                ->where('isagent', '0')
                ->find();

ThinkPHP 的链式查询(像搭积木):

php 复制代码
$this->db->table('admin')     第1步:指定表名
    ↓
->where('username', $username) 第2步:添加条件1
    ↓
->where('isagent', '0')       第3步:添加条件2
    ↓
->find()                      第4步:获取一条数据

生成的 SQL:

sql 复制代码
SELECT * FROM admin WHERE username='xxx' AND isagent='0' LIMIT 1
5. md5() - 密码加密
php 复制代码
$passwd = md5($password.$res['salt']);
  • md5() = 不可逆的加密函数
  • $res['salt'] = 数据库里存的随机盐值
  • 密码 = md5(用户输入的密码 + 盐)

为什么加盐?

php 复制代码
没加盐:md5('123456') = 固定结果,容易被彩虹表破解

加盐后:md5('123456' + '随机盐') = 不固定,无法破解
6. Cookie::set() - 写入Cookie
php 复制代码
Cookie::set('admin_user_id', $res['id'], 3600*2);
参数 含义
第1个 Cookie名称
第2个 Cookie值
第3个 有效期(秒),3600=1小时,3600*2=2小时
7. Cache::store('redis') - Redis缓存
php 复制代码
Cache::store('redis')->set('admin_user_'.$res['id'], 'login', 3600*2);
部分 含义
Cache::store('redis') 使用Redis驱动
->set(...) 写入缓存
'admin_user_'.$res['id'] 缓存键名(拼接用户ID)

🎯 完整登录流程总结

php 复制代码
┌─────────────────────────────────────────────────────────┐
│  1. 用户访问 /admin/login/login                         │
│     → 显示登录页面(login方法)                          │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  2. 用户填写表单,点击登录                               │
│     → POST提交到 /admin/login/doLogin                   │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  3. doLogin方法执行:                                   │
│     ├─ 接收POST数据                                     │
│     ├─ 验证数据不为空                                   │
│     ├─ 查询数据库验证用户名                              │
│     ├─ 验证密码(md5+盐加密对比)                       │
│     ├─ 登录成功:写Cookie + Redis + 返回"success"       │
│     └─ 登录失败:返回"登录失败"                         │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  4. 前端收到"success"                                   │
│     → 跳转到后台首页                                     │
└─────────────────────────────────────────────────────────┘

相关推荐
无巧不成书02181 小时前
Java包(package)全解:从定义、使用到避坑,新手零基础入门到实战
java·开发语言·package·java包
alexhilton2 小时前
Jetpack Compose元球边缘效果
android·kotlin·android jetpack
WangJunXiang62 小时前
Python网络编程
开发语言·网络·python
guhy fighting2 小时前
new Map,Array.from,Object.entries的作用以及使用方法
开发语言·前端·javascript
lsx2024062 小时前
操作系统统计
开发语言
_下雨天.2 小时前
Python 网络编程
开发语言·网络·python
小樱花的樱花2 小时前
打造高效记事本:UI设计到功能实现
开发语言·c++·qt·ui
橘子编程2 小时前
MindOS:你的AI第二大脑知识库
java·开发语言·人工智能·计算机网络·ai
aini_lovee2 小时前
C# 快速搜索磁盘文件解决方案
开发语言·c#