php用户登录验证及效验
登录界面
后台界面
代码示例
登录页面代码
<?php
// 载入配置文件
require_once '../config.php';
// // 给用户找一个箱子(如果你之前有就用之前的,没有给个新的)
session_start();
function login () {
// 1. 接收并校验
// 2. 持久化
// 3. 响应
if (empty($_POST['email'])) {
$GLOBALS['message'] = '请填写邮箱';
return;
}
if (empty($_POST['password'])) {
$GLOBALS['message'] = '请填写密码';
return;
}
$email = $_POST['email'];
$password = $_POST['password'];
// //设置密码
// if ( $email !== '[email protected]' ) {
// $GLOBALS['message'] = '不存在此用户名';
// return;
// }
// if ( $password !== 'admin') {
// $GLOBALS['message'] = '用户密码不正确';
// return;
// }
// 当客户端提交过来的完整的表单信息就应该开始对其进行数据校验
//1.建立连接
//2.
$conn = mysqli_connect(XIU_DB_HOST, XIU_DB_USER, XIU_DB_PASS,XIU_DB_NAME);
if (!$conn) {
exit('<h1>连接数据库失败</h1>');
}
$query = mysqli_query($conn, "select * from users where email = '{$email}' limit 1;");
if (!$query) {
$GLOBALS['message'] = '登录失败,请重试!';
return;
}
// 获取登录用户
$user = mysqli_fetch_assoc($query);
// 存一个登录标识,记录登录标识
// $_SESSION['is_logged_in'] = true;
//为了后续可以直接获取当前登录信息,这里直接将用户信息放到 session 中
$_SESSION['current_login_user'] = $user;
//信息同步
// $_SESSION['current_login_user_id'] = $user['id'];
if (!$user) {
// 用户名不存在
$GLOBALS['message'] = '用户名不存在';
return;
}
// 一般密码是加密存储的
if ($user['password'] !==$password) {
// 密码不正确
$GLOBALS['message'] = '密码不匹配';
return;
}
//保存SESSION
// 一切OK 可以跳转
header('Location: /admin/');
}
//判断用户请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
login();
}
?>
<!-- <!DOCTYPE html> -->
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>Sign in « Admin</title>
<link rel="stylesheet" href="/static/assets/vendors/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/static/assets/vendors/animate/animate.css">
<link rel="stylesheet" href="/static/assets/css/admin.css">
</head>
<body>
<div class="login">
<!-- 可以通过在 form 上添加 novalidate 取消浏览器自带的校验功能 -->
<!-- autocomplete="off" 关闭客户端的自动完成功能 -->
<form class="login-wrap<?php echo isset($message) ? ' shake animated' : '' ?>" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" autocomplete="off" novalidate>
<img class="avatar" src="/static/assets/img/default.png">
<!-- 作为一个优秀的页面开发人员,必须考虑一个页面的不同状态下展示的内容不一样的情况 -->
<!-- 有错误信息时展示 -->
<?php if (isset($message)): ?>
<div class="alert alert-danger">
<strong>错误!</strong> <?php echo $message; ?>
</div>
<?php endif ?>
<div class="form-group">
<label for="email" class="sr-only">邮箱</label>
<input id="email" name="email" type="email" class="form-control" placeholder="邮箱" autofocus value="<?php echo empty($_POST['email']) ? '' : $_POST['email'] ?>">
</div>
<div class="form-group">
<label for="password" class="sr-only">密码</label>
<input id="password" name="password" type="password" class="form-control" placeholder="密码" autocomplete="new-password" >
</div>
<button class="btn btn-primary btn-block">登 录</button>
</form>
</div>
<script src="/static/assets/vendors/jquery/jquery.js"></script>
<script>
$(function ($) {
//1.单独作用域
//2.确保页面加载过后执行
//目标,在用户输入邮箱之后展示这个邮箱的对应头像
//实现,
//时机,邮箱文本框失去焦点,
//添加正则验证
var emailFormat = /^[a-zA-Z-Z0-9]+@[a-zA-Z-Z0-9]+\.[a-zA-Z-Z0-9]+$/
//添加对应事件
$('#email').on('blur', function () {
// console.log($(this).val());
var value = $(this).val();
//忽略掉文本框为空或者不是一个邮箱
if (!value || !emailFormat.test(value)) return;
console.log(value);
//斜体样式用户输入一个合理的邮箱地址## 标题
////事情,获取这个文本框中填写的邮箱的对应的头像地址,展示到上面的 img 元素上
//因为客户端的JS 无法直接操作数据库 应该通过 JS 发送 AJAX 告诉服务端的某个 接口
//让这个接口帮助客户端获取头像地址
$.get('/admin/api/avatar.php', { email: value }, function (res) {
//希望 res=> 这个邮箱对应的头像地址
if (!res) return;
//展示到img 元素
// $('.avatar').fadeOut().attr('src', res).fadeIn();
//设置淡入淡出效果
$('.avatar').fadeOut(function () {
//等到淡出完成
$(this).on('load', function() {
//图片完全加载成功
$(this).fadeIn();
}).attr('src', res);
});
})
})
})
</script>
</body>
</html>
后台部分页面代码
<?php
// //效验当前用户的数据,有没有登录
// session_start();
// if (empty($_SESSION['current_login_user'])) {
// //没有当前登录用户信息,意味着没有登录
// header('Location: /admin/login.php');
// }
//判断是否存在用户
require_once '../functions.php';
//判断用户是否登陆一定是最先去做
baixiu_get_current_user();
//获取界面所需要的数据
//重复的操作一定封装起来
$posts_count = xiu_fetch('select count(1) as num from posts;');
//记录SESSION
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>Dashboard « Admin</title>
<link rel="stylesheet" href="/static/assets/vendors/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/static/assets/vendors/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="/static/assets/vendors/nprogress/nprogress.css">
<link rel="stylesheet" href="/static/assets/css/admin.css">
<script src="/static/assets/vendors/nprogress/nprogress.js"></script>
</head>
<body>
<script>NProgress.start()</script>
<div class="main">
<?php include 'inc/navbar.php'; ?>
<div class="container-fluid">
<div class="jumbotron text-center">
<h1>照亮</h1>
<p>力量, 故事 和 主意.</p>
<p><a class="btn btn-primary btn-lg" href="post-add.html" role="button">写文章</a></p>
</div>
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">站点内容统计:</h3>
</div>
<ul class="list-group">
<li class="list-group-item"><strong>10</strong>篇文章(<strong>2</strong>篇草稿)</li>
<li class="list-group-item"><strong>6</strong>个分类</li>
<li class="list-group-item"><strong>5</strong>条评论(<strong>1</strong>条待审核)</li>
</ul>
</div>
</div>
<div class="col-md-4"></div>
<div class="col-md-4"></div>
</div>
</div>
</div>
<?php $current_page = 'index'; ?>
<?php include 'inc/sidebar.php'; ?>
<script src="/static/assets/vendors/jquery/jquery.js"></script>
<script src="/static/assets/vendors/bootstrap/js/bootstrap.js"></script>
<script>NProgress.done()</script>
</body>
</html>
数据库连接插件代码
主机配置文件配件
<?php
/**
* 项目配置信息
*
*
*
* */
/** 数据库主机*/
define('XIU_DB_HOST','localhost');
/**数据库名 */
define('XIU_DB_USER','root');
/**数据库密码 */
define('XIU_DB_PASS','123456');
/**网站数据库名字 */
define('XIU_DB_NAME','baixiu-dev');
// phpinfo();
//网站根目录
// D:\www\baixiu
define('ROOT_DIR', dirname(__FILE__));
数据库功能文件
<?php
//载入配置文件
require_once 'config.php';
//封装公用的函数
session_start();
/**
* 获取当前登陆用户信息, 如果没有获取到则自动跳转到登陆页面
* 定义函数一定要注意内置函数:
* return [type] [description]
*
*/
function baixiu_get_current_user () {
if(empty($_SESSION['current_login_user'])) {
//没有当前登陆用户信息,意味着没有登陆
header('Location: /admin/login.php');
exit();//没有必要执行
}
//返回用户信息
return $_SESSION['current_login_user'];
}
/**
* 通过数据库查询获取数据
*
*
*/
function xiu_fetch ($sql) {
$conn = mysqli_connect(XIU_DB_HOST, XIU_DB_USER, XIU_DB_PASS, XIU_DB_NAME);
if(!conn) {
exit('连接失败!');
}
//查询
$query = mysqli_query($conn, $sql);
if(!$query) {
//查询失败
return false;
}
//查询成功,遍历数据
while ( $row = mysqli_fetch_assoc(($query))) {
$result[] = $row;
}
return $result;
多页面功能一样共用部分
为了使各个页面切换的时候不改变侧边栏导航栏部分。只改变内容,抽离部分。
解决方案
创建一个共用的文件夹 inc
把共用的代码剪切进去
navar.php 公共部分代码
<nav class="navbar">
<button class="btn btn-default navbar-btn fa fa-bars"></button>
<ul class="nav navbar-nav navbar-right">
<li><a href="profile.html"><i class="fa fa-user"></i>个人中心</a></li>
<li><a href="login.html"><i class="fa fa-sign-out"></i>退出</a></li>
</ul>
</nav>
sidebar.php 代码
<!-- 也可以使用 $_SERVER['PHP_SELF'] 取代 $current_page -->
<!--侧边栏-->
<?php
//因为这个 sidebar.php 是被 index。php 载入执行, 所以 这里的相对路径 是相对于 index.php
//如果希望根治这个问题,可以采用物理路径解决
// require_once '../../functions.php';
// require_once dirname(__FILE__) . '/ ../ ../functions.php';
require_once '../functions.php';
$current_page = isset($current_page) ? $current_page : '';
$current_user = baixiu_get_current_user();
// //载入数据库连接 相对路径
// require_once '../config.php';
// //获取用户登录信息
// $current_user = baixiu_get_current_user();
//读取缓存
// session_start();
// $current_user = $_SESSION['current_login_user'];
?>
<div class="aside">
<div class="profile">
<img class="avatar" src="<?php echo $current_user['avatar']; ?>">
<h3 class="name"><?php echo $current_user['nickname'];?></h3>
</div>
<ul class="nav">
<li<?php echo $current_page === 'index' ? ' class="active"' : '' ?>>
<a href="/admin/index.php"><i class="fa fa-dashboard"></i>仪表盘</a>
</li>
<?php $menu_posts = array('posts', 'post-add', 'categories'); ?>
<li<?php echo in_array($current_page, $menu_posts) ? ' class="active"' : '' ?>>
<a href="#menu-posts"<?php echo in_array($current_page, $menu_posts) ? '' : ' class="collapsed"' ?> data-toggle="collapse">
<i class="fa fa-thumb-tack"></i>文章<i class="fa fa-angle-right"></i>
</a>
<ul id="menu-posts" class="collapse<?php echo in_array($current_page, $menu_posts) ? ' in' : '' ?>">
<li<?php echo $current_page === 'posts' ? ' class="active"' : '' ?>><a href="/admin/posts.php">所有文章</a></li>
<li<?php echo $current_page === 'post-add' ? ' class="active"' : '' ?>><a href="/admin/post-add.php">写文章</a></li>
<li<?php echo $current_page === 'categories' ? ' class="active"' : '' ?>><a href="/admin/categories.php">分类目录</a></li>
</ul>
</li>
<li<?php echo $current_page === 'comments' ? ' class="active"' : '' ?>>
<a href="/admin/comments.php"><i class="fa fa-comments"></i>评论</a>
</li>
<li<?php echo $current_page === 'users' ? ' class="active"' : '' ?>>
<a href="/admin/users.php"><i class="fa fa-users"></i>用户</a>
</li>
<?php $menu_settings = array('nav-menus', 'slides', 'settings'); ?>
<li<?php echo in_array($current_page, $menu_settings) ? ' class="active"' : '' ?>>
<a href="#menu-settings"<?php echo in_array($current_page, $menu_settings) ? '' : ' class="collapsed"' ?> data-toggle="collapse">
<i class="fa fa-cogs"></i>设置<i class="fa fa-angle-right"></i>
</a>
<ul id="menu-settings" class="collapse<?php echo in_array($current_page, $menu_settings) ? ' in' : '' ?>">
<li<?php echo $current_page === 'nav-menus' ? ' class="active"' : '' ?>><a href="/admin/nav-menus.php">导航菜单</a></li>
<li<?php echo $current_page === 'slides' ? ' class="active"' : '' ?>><a href="/admin/slides.php">图片轮播</a></li>
<li<?php echo $current_page === 'settings' ? ' class="active"' : '' ?>><a href="/admin/settings.php">网站设置</a></li>
</ul>
</li>
</ul>
</div>
对于二级菜单的css处理
每个文件都要引用
<?php include '文件路径'; ?>
文件夹/文件名字
//服务器调用当前的样式,发送请求
---请求服务器相同的类样式
--注意,每一个抽离出来的页面都要声明属性值
<?php
//抽离的公共部分定义当前页面属性
$current_page = '当前部分属性';?>
<?php
//载入抽离公共部分的文件
include '文件的相对路径';
?>
抽离出来的服务器判定当前样式
<li<?php echo $current_page=== '当前页面属性' : class='active'? ''?>></li>
-----分级菜单--子菜单---采用数组的方式
//声明数组
<?php $Menu_posts =array(声明变量名1,声明变量名2,声明变量3); ?>>
举例代码
<?php $menu_posts = array('posts', 'post-add', 'categories'); ?>
//判断是否添加样式
//主菜单样式
<li <?php echo in_array(公共部分的变量名,当前值的变量名) ? 'class="active"' : '' ?>></li>
//子菜单样式 这个是bootstrap 样式 collapse in 为展开 没有 in 则为没有展开
举例代码
//展开判断
<ul id="menu-posts" class="collapse<?php echo in_array($current_page, $menu_posts) ? ' in' : ''; ?>">
//a 地址连接bootstrap 样式
//判定条件 当主菜单存在的时候去掉属性,不存在主菜单的时候加上属性
<a href="#menu=posts" <?php in_array($current_page, $menu_posts) ? '' : 'class="collapsed"'?>></a>
<li <?php echo $current_page === 声明变量名1 ? 'class="active"' : ''; ?>></li>
<li <?php echo $current_page === 声明变量名2 ? 'class="active"' : ''; ?>></li>
<li <?php echo $current_page === 声明变量名3 ? 'class="active"' : ''; ?>></li>
//补充点
获取数据库当前登录信息
$current_user = baixiu_get_current_user();
属于个人整理的一些小问题,不懂得小伙伴可以私信:
页面暂时只介绍登录页面和后台登录界面;