$_COOKIE: 超全局变量数组setcookie(): 设置客户端cookieCOOKIE# 1、设置 setcookie('id',1); // 可设置过期时间,默认关闭页面自动消除 // 设置user_id变量,在浏览器中一分钟后失效 setcookie('name', '欧阳克', time() + 60); # 2、读取 // 需要刷新二次,才可以获取到cookie,原因是 // 第一次刷新,是将cookie写入到客户端, 即写操作 // 第二次刷新,是将写入到客户端的cookie数据读出来,即读操作 echo 'id = '. $_COOKIE['id']. '<br>'; echo 'name = '. $_COOKIE['name']. '<br>'; // 如果想在一个cookie变量可存储多个值,可以使用数组语法 // 60*60表示1小时, 60*60*24表示1天 setcookie('user[id]', '2', time() + 60 * 60 * 24); setcookie('user[name]', '欧阳克', time() + 60 * 60 * 24); setcookie('user[email]', 'a@oyk.cn', time() + 60 * 60 * 24); if (isset($_COOKIE['user'])) { foreach ($_COOKIE['user'] as $key => $value) { echo "{$key} => {$value} <br>"; } } # 3、更新 if ($_COOKIE['id']) { $_COOKIE['id'] = 800; } echo 'id = '. $_COOKIE['id']; # 4、删除 unset($_COOKIE['username']); // 函数删除 setcookie('username', '', time() - 3600); // 设置一个已经过期的持续时间
session_start(): 启动新会话或者重用现有会话session_id(): 获取/设置当前会话 IDsession_save_path(): 读取/设置当前会话的保存路径session_encode(): 将当前会话数据编码为一个字符串session_decode: 解码会话数据session_destroy(): 销毁一个会话中的全部数据,仅清空而已session_unset(): 释放所有的会话变量session_reset(): 回滚到上一次的会话注意: 必须先执行session_start()开启会话才生效,且之前不能有输出
// 开启一个会话(之前不能有输出) // session_start()自动设置客户端的session_id,或重启启用一个已存在的会话 session_start(); // 刷新页面, 打开application可以查看到COOKIE里有PHPSESSID,适用于根路径 // 查看服务器上的sesscion会话存储的路径位置 // 到该路径下可看到一个sess_为前缀,后跟session_id的文件名 echo session_save_path(); echo '<hr>'; // 1、设置 $_SESSION['id'] = 3; $_SESSION['name'] = '欧阳克'; // 2、读取 echo 'id = '. $_SESSION['id']. '<br>'; echo 'name = '. $_SESSION['name']. '<br>'; // 3、清除 session_unset(); // 会话内容清空,但会话文件'sess_******'仍在 session_destroy(); // 会话内容清空,会话文件删除,但客户端的cookie仍在,即会话仍在,还能重启 // 可以session_destroy()后, 再调用setcookie()清除掉客户端的session_id,就完全清除了会话 setcookie('PHPSESSID','',time()-3600,'/');
创建数据库表
CREATE TABLE `user` ( `uid` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `phone` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号', `name` varchar(50) NOT NULL DEFAULT '' COMMENT '姓名', `pwd` varchar(32) NOT NULL DEFAULT '' COMMENT '密码', `age` int(3) unsigned NOT NULL DEFAULT '18' COMMENT '年龄', `sex` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '性别,值为1时是男性,值为2时是女性,值为0时是未知', `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '1为正常,0为禁止', `last_time` int(11) unsigned DEFAULT '0' COMMENT '最后登录时间', PRIMARY KEY (`uid`) USING BTREE ) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COMMENT='用户--用户信息表'; INSERT INTO `user` VALUES (1, '18011112222', '欧阳克', 'e10adc3949ba59abbe56e057f20f883e', 18, 1, 1, 1561125595);
创建数据库连接文件:connect.php
<?php $db = [ 'type' => 'mysql', 'host' => 'localhost', 'dbname' => 'php', 'username' => 'root', 'password' => 'root' ]; $dsn = "{$db['type']}:host={$db['host']};dbname={$db['dbname']}"; $username = $db['username']; $password = $db['password']; try { $pdo = new PDO($dsn, $username, $password); } catch (PDOException $e) { die('连接失败' . $e->getMessage()); }
首页文件:index.php
先展示未登陆功能
<?php // 为简化程序, 使用了一个中间层(dispatch.php): 请求派发器,类似于框架的控制器, 对用户的请求进行集中处理 // 1: 已登录: 显示出用户的登录信息, 显示退出按钮 if (isset($_COOKIE['name']) { echo '用户: ' . $_COOKIE['name'] . '已登录<br>'; echo '<a href="dispatch.php?action=logout">退出</a>'; } else { // 2. 未登录,就跳转到登录页面 echo '<a href="dispatch.php?action=login">请登录</a>'; }
派发器:dispatch.php
<?php // 请求派发器: 前端控制器 // 功能就是获取到用户的请求, 并调用不同的脚本进行处理和响应 // 连接数据库 require __DIR__ . '/connect.php'; // 获取请求参数 $action = isset($_GET['action']) ? $_GET['action'] : 'login'; $action = htmlentities(strtolower(trim($action))); // 请求分发 switch ($action) { // 1. 登录页面 case 'login': // 加载登录表单 include __DIR__ . '/login.php'; break; // 2. 验证登录 case 'check': include __DIR__ . '/check.php'; break; // 3. 退出登录 case 'logout': include __DIR__ . '/logout.php'; break; // 默认操作 default: header('Location: index.php'); echo '<script>location.assign("index.php");</script>'; }
登陆页面:login.php
<?php // 防止用户重复登录 if (isset($_COOKIE['name'])) { echo '<script>alert("不要重复登录");location.assign("index.php");</script>'; } ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title> </head> <body> <h3>用户登录</h3> <form action="dispatch.php?action=check" method="post" onsubmit="return isEmpty();"> <p> <label for="phone">手机号:</label> <input type="phone" name="phone" id="phone"> </p> <p> <label for="password">密码:</label> <input type="password" name="password" id="password"> </p> <p> <button>提交</button> </p> </form> <script> function isEmpty() { var phone = document.getElementById('phone').value; var password = document.getElementById('password').value; if (phone.length=== 0 || password.length===0) { alert('手机和密码不能为空'); return false; } } </script> </body> </html>
验证登陆:check.php
<?php // 1.判断用户的请求类型是否正确? if ($_SERVER['REQUEST_METHOD'] === 'POST') { // 2.获取表单数据 $phone = $_POST['phone']; $password = sha1($_POST['password']); // 3. 用用户表user.dbf进行验证 $sql = 'SELECT * FROM `user` WHERE `phone` = :phone AND `password` = :password LIMIT 1'; $stmt = $pdo->prepare($sql); $stmt->execute(['phone'=>$phone, 'password'=>$password]); $user = $stmt->fetch(PDO::FETCH_ASSOC); // 4. 判断验证的结果 if (false === $user) { // 验证失败,返回上一下页面 echo '<script>alert("验证失败");history.back();</script>'; die; } // 验证成功,将用户的信息写到cookie setcookie('name', $user['name']); echo '<script>alert("登录成功");location.assign("index.php");</script>'; exit; } else { die('请求类型错误'); }
退出登陆:logout.php
<?php // 必须在用户已经登录的情况下再退出 if (isset($_COOKIE['name'])) { setcookie('name', null, time()-3600); echo '<script>alert("退出成功");location.assign("index.php");</script>'; } else { // 要求用户先登录 echo '<script>alert("请先登录");location.assign("login.php");</script>'; }
首页文件:index.php
<?php //开启会话 session_start(); // 为简化程序, 使用了一个中间层: 请求派发器,类似于框架的控制器, 对用户的请求进行集中处理 // 1: 已登录: 显示出用户的登录信息, 显示退出按钮 if (isset($_SESSION['name']) && $_SESSION['name'] === 'admin') { echo '用户: ' . $_SESSION['name'] . '已登录<br>'; echo '<a href="dispatch.php?action=logout">退出</a>'; } else { // 2. 未登录,就跳转到登录页面 echo '<a href="dispatch.php?action=login">请登录</a>'; }
派发器:dispatch.php
<?php // 只需要在该脚本中打开会话即可, check.php/logout.php/login.php都是由它调用的, 不必重复开启 session_start(); // 连接数据库 require __DIR__ . '/connect.php'; // 获取请求参数 $action = isset($_GET['action']) ? $_GET['action'] : 'login'; $action = htmlentities(strtolower(trim($action))); // 请求分发 switch ($action) { // 1. 登录页面 case 'login': // 加载登录表单 include __DIR__ . '/login.php'; break; // 2. 验证登录 case 'check': include __DIR__ . '/check.php'; break; // 3. 退出登录 case 'logout': include __DIR__ . '/logout.php'; break; // 默认操作 default: header('Location: index.php'); echo '<script>location.assign("index.php");</script>'; }
登陆页面:login.php
<?php // 防止用户重复登录 if (isset($_SESSION['name'])) { echo '<script>alert("不要重复登录");location.assign("index.php");</script>'; } ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title> </head> <body> <h3>用户登录</h3> <form action="dispatch.php?action=check" method="post" onsubmit="return isEmpty();"> <p> <label for="phone">手机:</label> <input type="phone" name="phone" id="phone"> </p> <p> <label for="password">密码:</label> <input type="password" name="password" id="password"> </p> <p> <button>提交</button> </p> </form> <script> function isEmpty() { var phone = document.getElementById('phone').value; var password = document.getElementById('password').value; if (phone.length=== 0 || password.length===0) { alert('手机和密码不能为空'); return false; } } </script> </body> </html>
验证登陆:check.php
<?php // 1.判断用户的请求类型是否正确? if ($_SERVER['REQUEST_METHOD'] === 'POST') { // 2.获取表单数据 $phone = $_POST['phone']; $password = sha1($_POST['password']); // 3. 用用户表user.dbf进行验证 $sql = 'SELECT * FROM `user` WHERE `phone` = :phone AND `password` = :password LIMIT 1'; $stmt = $pdo->prepare($sql); $stmt->execute(['phone'=>$phone, 'password'=>$password]); $user = $stmt->fetch(PDO::FETCH_ASSOC); // 4. 判断验证的结果 if (false === $user) { // 验证失败,返回上一下页面 echo '<script>alert("验证失败");history.back();</script>'; die; } // 验证成功,将用户的信息写到session $_SESSION['name'] = $user['name']; echo '<script>alert("登录成功");location.assign("index.php");</script>'; exit; } else { die('请求类型错误'); }
退出登陆:logout.php
<?php // 必须在用户已经登录的情况下再退出 if (isset($_SESSION['name'])) { session_destroy(); echo '<script>alert("退出成功");location.assign("index.php");</script>'; } else { // 要求用户先登录 echo '<script>alert("请先登录");location.assign("login.php");</script>'; }