八:PHP Session 和 Cookie——记住用户状态

一、回顾与本篇目标

上一篇你学会了 PHP 表单处理——接收 GET 和 POST 数据、验证用户输入、防御 XSS 和 CSRF 攻击、处理文件上传。你的应用现在可以和用户交互了。

但有一个根本问题还没解决:HTTP 是无状态协议。这意味着服务器默认把每个请求都当作独立的——同一个用户访问首页和访问个人中心,服务器不知道这是同一个人。你登录之后刷新页面,服务器”忘记”你已经登录了。每次请求都要重新验证身份?那用户体验会非常糟糕。

解决这个问题的两种核心技术就是 CookieSession。Cookie 在浏览器端存储数据,Session 在服务器端存储数据。两者配合使用,就能让服务器”记住”用户——登录状态、购物车内容、浏览历史、语言偏好——这些都需要跨请求保持状态。

本篇的目标:

  1. 理解 Cookie 的原理和用法:创建、读取、删除
  2. 理解 Session 的原理和用法:启动、存取数据、销毁
  3. 学会用 Session 实现用户登录状态保持
  4. 理解 Cookie 的安全属性:HttpOnly、Secure、SameSite
  5. 掌握 Session 安全:固定攻击防御、过期时间配置
  6. 实现一个完整的登录/注销系统

二、为什么需要状态管理

HTTP 协议的设计哲学是每个请求都是独立的。服务器处理完一个请求就”忘记”了——不记得上一个请求是谁发的、上一个请求做了什么。这种设计让 HTTP 协议非常简单、可扩展,但也带来一个问题:怎么让服务器知道两次请求来自同一个用户?

比如一个在线购物流程:用户浏览商品 → 加入购物车 → 结算 → 付款。这涉及多次 HTTP 请求。如果不做状态管理,每次请求服务器都以为是一个新用户,购物车永远是空的。

解决方案:

  • Cookie:服务器在响应中给浏览器发一个”通行证”,浏览器把它存起来。以后每次请求同一个网站,浏览器自动把这个通行证带回去。这样服务器就能认出”哦,是你啊”。
  • Session:通行证上只写一个编号(Session ID),真正的数据(用户信息、购物车内容)存在服务器端。浏览器只负责携带编号,服务器根据编号找到对应的数据。

类比:Cookie 就像超市的会员卡——卡片本身可以存储一些信息(积分、等级)。Session 就像超市的存包柜——你手里只有一把钥匙(Session ID),你的物品(用户数据)存在超市的柜子里(服务器端)。

三、Cookie:浏览器端的存储

3.1 Cookie 是什么

Cookie 是服务器通过 HTTP 响应头发给浏览器的一小段文本数据(通常不超过 4KB)。浏览器收到后会把它存起来。之后每次向同一个域名发送请求时,浏览器会自动把对应的 Cookie 附带在请求头中发送给服务器。

Cookie 的核心机制可以概括为:

  • 服务器发送 Cookie:通过 Set-Cookie 响应头。
  • 浏览器存储 Cookie:按域名分类存储,每个域名下的 Cookie 互不干扰。
  • 浏览器回传 Cookie:每次请求自动把该域名下的所有 Cookie 通过 Cookie 请求头发送给服务器。

3.2 用 PHP 创建 Cookie

使用 setcookie() 函数。这个函数必须在任何 HTML 输出之前调用——因为它本质上是设置 HTTP 响应头,响应头必须在响应体之前发送。

<?php
// 创建一个 Cookie:名为 username,值为"张三",有效期 7 天
setcookie('username', '张三', time() + 7 * 24 * 60 * 60, '/');

echo "Cookie 已设置";
?>

setcookie() 的参数:

参数 含义 示例
name Cookie 的名称(必填) 'username'
value Cookie 的值 '张三'
expires 过期时间(Unix 时间戳) time() + 86400(24 小时后)
path Cookie 在哪个路径下生效 '/'(全站生效)
domain Cookie 在哪个域名下生效 'example.com'
secure 是否只在 HTTPS 下传输 true
httponly 是否禁止 JavaScript 访问 true

过期时间的计算:

  • time() + 3600:1 小时后过期。
  • time() + 86400:24 小时后过期(86400 = 24 × 60 × 60)。
  • time() + 7 * 86400:7 天后过期。
  • 不设置 expires:Cookie 在浏览器关闭时自动删除(会话 Cookie)。

3.3 读取 Cookie

Cookie 的值通过 $_COOKIE 超全局变量获取:

<?php
// 读取名为 username 的 Cookie
$username = $_COOKIE['username'] ?? '未设置';

echo "Cookie 中的 username:{$username}";
?>

重要:通过 setcookie() 设置的 Cookie,在当前请求中无法通过 $_COOKIE 立即获取。因为 Cookie 是服务器通过响应头发给浏览器的,浏览器收到响应后才会存储它。只有下一次请求,浏览器才会把它带回来,这时候 $_COOKIE 里才有值。

<?php
// 第一次访问:设置 Cookie
setcookie('test', 'hello', time() + 3600, '/');
echo isset($_COOKIE['test']) ? $_COOKIE['test'] : 'Cookie 还没生效,刷新页面试试';
// 输出:Cookie 还没生效,刷新页面试试

// 刷新页面后:Cookie 已经生效
echo $_COOKIE['test'] ?? '未设置';
// 输出:hello
?>

3.4 删除 Cookie

删除 Cookie 的方法是:把过期时间设置为过去的时间。浏览器发现 Cookie 已经过期,就会自动删除它。

<?php
// 把过期时间设为 1 小时前
setcookie('username', '', time() - 3600, '/');

echo "Cookie 已删除";
?>

删除时,path 参数必须和创建时一致,否则浏览器可能删不掉。

四、Session:服务器端的存储

4.1 Session 是什么

Session 是服务器端的存储机制。服务器为每个用户创建一个唯一标识(Session ID),通过 Cookie 传给浏览器。浏览器每次请求时带上这个 Session ID,服务器根据它找到对应的数据。

Session 的工作流程:

  1. 用户第一次访问网站,服务器创建一个 Session,生成一个唯一的 Session ID。
  2. 服务器把 Session ID 通过 Cookie(名为 PHPSESSID)发给浏览器。
  3. 浏览器存储这个 Cookie。
  4. 用户再次访问,浏览器自动带上 PHPSESSID Cookie。
  5. 服务器根据 Session ID 找到对应的 Session 数据。

Session 和 Cookie 的关系:Session 依赖 Cookie 来传递 Session ID。如果浏览器禁用了 Cookie,Session 就无法正常工作(可以通过 URL 参数传递 Session ID,但极不推荐)。

4.2 启动 Session

在使用 Session 之前,必须调用 session_start()。这个函数必须在任何 HTML 输出之前调用——和 setcookie() 一样,它需要设置响应头。

<?php
// 启动 Session(必须在任何输出之前)
session_start();

// 现在可以使用 $_SESSION 了
$_SESSION['user_id'] = 1;
$_SESSION['username'] = '张三';
$_SESSION['logged_in'] = true;

echo "Session 已启动,数据已存储";
?>

session_start() 做了什么:

  1. 检查请求中是否带有 PHPSESSID Cookie。
  2. 如果有,根据这个 ID 从服务器存储中加载对应的 Session 数据,填充到 $_SESSION 数组中。
  3. 如果没有,创建一个新的 Session ID,生成一个新的空 Session,并通过 Set-Cookie 响应头发给浏览器。

最佳实践:把 session_start() 放在配置文件中,确保每个需要 Session 的页面都调用它。可以使用条件判断避免重复启动:

<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}
?>

4.3 存取 Session 数据

Session 数据存储在 $_SESSION 超全局数组中。这是一个关联数组,你可以在里面存任何 PHP 数据类型(字符串、数字、数组、对象——只要对象是可序列化的)。

<?php
session_start();

// 存储数据
$_SESSION['user'] = [
    'id' => 1,
    'name' => '张三',
    'email' => 'zhangsan@example.com',
    'role' => 'admin'
];
$_SESSION['login_time'] = time();
$_SESSION['cart'] = ['item1', 'item2'];

// 读取数据
echo "欢迎,{$_SESSION['user']['name']}!<br>";
echo "登录时间:" . date('Y-m-d H:i:s', $_SESSION['login_time']) . "<br>";
echo "购物车有 " . count($_SESSION['cart']) . " 件商品<br>";

// 删除单个 Session 变量
unset($_SESSION['cart']);

// 修改 Session 变量
$_SESSION['user']['role'] = 'editor';
?>

4.4 销毁 Session

用户登出时,需要彻底清除 Session:

<?php
session_start();

// 方式一:清空所有 Session 数据(保留 Session ID)
$_SESSION = [];

// 方式二:彻底销毁 Session(推荐用于登出)
session_unset();     // 清空 $_SESSION 数组
session_destroy();   // 删除服务器端的 Session 文件

// 同时删除客户端的 Session Cookie
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}

echo "Session 已销毁,用户已登出";
?>

为什么需要同时删除 Cookie? session_destroy() 只删除服务器端的 Session 数据,浏览器端的 PHPSESSID Cookie 还在。如果不删除 Cookie,下次请求浏览器仍然会发送旧的 Session ID,服务器会创建一个新的空 Session。虽然数据没了,但 Cookie 残留是不规范的做法。

五、Session 的存储与配置

PHP 默认把 Session 数据以文件形式存储在服务器的临时目录中(通常是 /tmp)。每个 Session 对应一个文件,文件名是 sess_ + Session ID

5.1 Session 的过期时间

PHP 默认的 Session 过期机制有两个层面:

  • Session 文件本身:由 PHP 的垃圾回收机制清理。默认在 24 分钟后可能被清理(取决于 session.gc_maxlifetime 配置,通常是 1440 秒 = 24 分钟)。
  • Session Cookie 的过期:默认是浏览器关闭时删除(会话 Cookie)。如果你希望用户关闭浏览器后仍然保持登录,需要手动设置 Session Cookie 的过期时间。

要延长登录状态的有效期,在 session_start() 之前设置:

<?php
// 设置 Session 的有效期为 7 天
ini_set('session.gc_maxlifetime', 7 * 24 * 60 * 60);  // 服务器端
session_set_cookie_params(7 * 24 * 60 * 60);          // 浏览器端 Cookie

session_start();
?>

或者更简单的方式——在 php.ini 配置文件中全局设置(推荐,但不总是可操作)。

5.2 Session 存储的其他方式

文件存储在小规模应用中可以接受,但存在两个问题:

  • 性能:高并发时,大量 Session 文件的读写会成为瓶颈。
  • 分布式部署:如果有多台服务器,一台服务器上的 Session 文件另一台无法访问——用户的请求被负载均衡分配到不同服务器时,Session 就丢了。

解决方案是把 Session 存储到共享的中央存储中——通常是 Redis 或数据库。PHP 允许你自定义 Session 处理器。最常用的是 Redis:

<?php
// 使用 Redis 存储 Session(需要安装 phpredis 扩展)
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');

session_start();
?>

这样所有服务器的 Session 都存到同一个 Redis 中,实现了共享。这个暂时不需要深入,知道有这种方案就行。

六、Cookie 的安全属性

Cookie 默认通过 HTTP 明文传输(如果不用 HTTPS)。它有一些重要的安全属性,每个都应该了解:

属性 含义 建议值
HttpOnly 禁止 JavaScript 通过 document.cookie 访问此 Cookie 始终开启(特别是 Session Cookie)
Secure 只在 HTTPS 连接中传输此 Cookie 生产环境必须开启
SameSite 控制跨站请求是否携带此 Cookie 设为 Lax(默认)或 Strict
<?php
// 安全的 Cookie 设置示例
setcookie('session_token', $token, [
    'expires' => time() + 86400,    // 24 小时后过期
    'path' => '/',                   // 全站生效
    'domain' => '',                  // 当前域名
    'secure' => true,                // 仅 HTTPS
    'httponly' => true,              // 禁止 JS 访问
    'samesite' => 'Lax'              // 跨站请求控制
]);
?>

HttpOnly 为什么重要:如果 Session Cookie 没有 HttpOnly 属性,攻击者通过 XSS 漏洞注入的 JavaScript 代码可以直接读取 document.cookie,把 Session ID 发送给攻击者的服务器。攻击者拿到 Session ID 后,就可以冒充你的身份访问网站。开启 HttpOnly 之后,JavaScript 完全无法访问这个 Cookie,XSS 攻击的破坏范围被大大限制。

SameSite 的三个值:

  • Strict:完全禁止跨站携带 Cookie。用户从外部链接点击进来时,Cookie 不会被发送——用户总是未登录状态。最安全但用户体验差。
  • Lax(默认):大部分跨站请求不携带 Cookie,但导航到目标网站的 GET 请求会携带。用户在搜索引擎点链接进入你的网站时,能保持登录状态。这是平衡安全和体验的最佳选择。
  • None:所有跨站请求都携带 Cookie。必须同时设置 Secure。不推荐,除非你明确需要(比如嵌入在 iframe 中的第三方应用)。

七、Session 安全

7.1 会话固定攻击

会话固定攻击的基本思路:

  1. 攻击者访问你的网站,获得一个 Session ID(比如 abc123)。
  2. 攻击者诱导用户点击一个链接,URL 中带了这个 Session ID(比如 http://yoursite.com/?PHPSESSID=abc123)。
  3. 用户点击链接访问网站,PHP 使用了这个已知的 Session ID。
  4. 用户登录后,Session 中存储了用户的身份信息。
  5. 攻击者用同样的 Session ID 访问网站,直接获得用户的登录状态。

防御:登录后重新生成 Session ID

<?php
session_start();

// 验证用户名密码...
if ($login_successful) {
    // 登录成功后重新生成 Session ID
    session_regenerate_id(true);
    // true 参数表示删除旧的 Session 文件
    
    $_SESSION['user_id'] = $user['id'];
    $_SESSION['username'] = $user['name'];
}
?>

session_regenerate_id(true) 生成一个新的 Session ID,攻击者之前拿到的旧 ID 立即失效。用户登录后的身份信息绑定在新的、只有用户自己知道的 Session ID 上。

7.2 Session 的其他安全配置

<?php
// 在 session_start() 之前设置
ini_set('session.use_strict_mode', 1);            // 严格模式:拒绝未初始化的 Session ID
ini_set('session.cookie_httponly', 1);            // Cookie 设为 HttpOnly
ini_set('session.cookie_secure', 1);              // Cookie 仅在 HTTPS 下传输(生产环境)
ini_set('session.cookie_samesite', 'Lax');        // SameSite 属性
ini_set('session.use_only_cookies', 1);           // 仅通过 Cookie 传递 Session ID(禁止 URL 传递)

session_start();
?>

严格模式的作用:如果浏览器传来的 Session ID 在服务器端不存在(比如攻击者伪造的),PHP 会拒绝使用它,创建一个新的 Session ID。这可以防止攻击者随意指定 Session ID。

八、综合演示:完整的登录/注销系统

下面这个完整示例综合了 Cookie、Session、数据库操作、表单验证、安全防护:

<?php
// config.php —— 公共配置
session_start();

// 安全配置
ini_set('session.use_strict_mode', 1);
ini_set('session.cookie_httponly', 1);
ini_set('session.use_only_cookies', 1);

require_once 'db.php';

// 检查用户是否已登录
function isLoggedIn(): bool {
    return isset($_SESSION['user_id']);
}

// 获取当前登录用户的信息
function getCurrentUser(): ?array {
    if (!isLoggedIn()) {
        return null;
    }
    try {
        $pdo = getDBConnection();
        $stmt = $pdo->prepare("SELECT id, name, email, age, created_at FROM users WHERE id = :id");
        $stmt->execute(['id' => $_SESSION['user_id']]);
        return $stmt->fetch() ?: null;
    } catch (PDOException $e) {
        return null;
    }
}

// 获取提示消息
$message = $_SESSION['message'] ?? '';
$messageType = $_SESSION['message_type'] ?? '';
unset($_SESSION['message'], $_SESSION['message_type']);
?>

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title><?= isLoggedIn() ? '个人中心' : '登录' ?></title>
    <style>
        body { font-family: sans-serif; padding: 40px; background: #f0f4f8; display: flex; justify-content: center; }
        .container { background: white; padding: 40px; border-radius: 12px; width: 400px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h2 { margin-top: 0; color: #333; text-align: center; }
        .form-group { margin-bottom: 16px; }
        label { display: block; margin-bottom: 4px; color: #555; font-size: 14px; }
        input { width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px; box-sizing: border-box; }
        .error { color: #e74c3c; font-size: 13px; margin-top: 4px; }
        .message { padding: 12px; border-radius: 6px; margin-bottom: 20px; text-align: center; }
        .success { background: #e8f5e9; color: #2e7d32; }
        .error-msg { background: #fbe9e7; color: #c62828; }
        button { width: 100%; padding: 12px; background: #4a90d9; color: white; border: none; border-radius: 6px; font-size: 16px; cursor: pointer; }
        button:hover { background: #3a7bc8; }
        .btn-logout { background: #e74c3c; margin-top: 20px; }
        .btn-logout:hover { background: #c0392b; }
        .user-info { background: #f8f9fa; padding: 16px; border-radius: 8px; margin: 16px 0; }
        .user-info p { margin: 8px 0; }
        .links { text-align: center; margin-top: 16px; font-size: 14px; }
        .links a { color: #4a90d9; text-decoration: none; }
    </style>
</head>
<body>

<div class="container">
    <?php if ($message): ?>
        <div class="message <?= $messageType ?>"><?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8') ?></div>
    <?php endif; ?>

    <?php if (isLoggedIn()): ?>
        <!-- 已登录:显示用户信息 -->
        <?php $user = getCurrentUser(); ?>
        <h2>👤 个人中心</h2>
        
        <?php if ($user): ?>
            <div class="user-info">
                <p><strong>姓名:</strong><?= htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8') ?></p>
                <p><strong>邮箱:</strong><?= htmlspecialchars($user['email'], ENT_QUOTES, 'UTF-8') ?></p>
                <p><strong>年龄:</strong><?= $user['age'] ?> 岁</p>
                <p><strong>注册时间:</strong><?= $user['created_at'] ?></p>
            </div>
        <?php endif; ?>
        
        <form method="POST" action="logout.php">
            <button type="submit" class="btn-logout">退出登录</button>
        </form>
        
    <?php else: ?>
        <!-- 未登录:显示登录表单 -->
        <h2>🔐 用户登录</h2>
        
        <form method="POST" action="login.php">
            <div class="form-group">
                <label>邮箱</label>
                <input type="email" name="email" required>
            </div>
            
            <div class="form-group">
                <label>密码</label>
                <input type="password" name="password" required>
            </div>
            
            <div class="form-group">
                <label>
                    <input type="checkbox" name="remember"> 记住我(7 天)
                </label>
            </div>
            
            <button type="submit">登录</button>
        </form>
        
        <div class="links">
            还没有账号?<a href="register.php">立即注册</a>
        </div>
    <?php endif; ?>
</div>

</body>
</html>

login.php —— 处理登录逻辑:

<?php
session_start();
require_once 'db.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: index.php');
    exit;
}

$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
$remember = isset($_POST['remember']);

// 验证
if ($email === '' || $password === '') {
    $_SESSION['message'] = '请填写邮箱和密码';
    $_SESSION['message_type'] = 'error-msg';
    header('Location: index.php');
    exit;
}

try {
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("SELECT id, name, password FROM users WHERE email = :email");
    $stmt->execute(['email' => $email]);
    $user = $stmt->fetch();

    if (!$user || !password_verify($password, $user['password'])) {
        $_SESSION['message'] = '邮箱或密码错误';
        $_SESSION['message_type'] = 'error-msg';
        header('Location: index.php');
        exit;
    }

    // 登录成功:重新生成 Session ID
    session_regenerate_id(true);

    $_SESSION['user_id'] = $user['id'];
    $_SESSION['username'] = $user['name'];
    $_SESSION['login_time'] = time();

    // 如果勾选了"记住我",延长 Session Cookie 有效期
    if ($remember) {
        setcookie(session_name(), session_id(), time() + 7 * 24 * 60 * 60, '/');
    }

    $_SESSION['message'] = '登录成功!欢迎回来,' . $user['name'];
    $_SESSION['message_type'] = 'success';
    header('Location: index.php');
    exit;

} catch (PDOException $e) {
    $_SESSION['message'] = '系统错误,请稍后重试';
    $_SESSION['message_type'] = 'error-msg';
    header('Location: index.php');
    exit;
}
?>

logout.php —— 处理登出逻辑:

<?php
session_start();

// 清空 Session 数组
$_SESSION = [];

// 删除服务器端的 Session 文件
session_destroy();

// 删除客户端的 Session Cookie
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}

// 重定向到首页
header('Location: index.php');
exit;
?>

代码设计要点:

  • 会话固定防御:登录成功后调用 session_regenerate_id(true),防止攻击者使用预先准备的 Session ID。
  • “记住我”功能:勾选后,通过 setcookie() 延长 Session Cookie 的有效期到 7 天。不勾选时,Cookie 是会话级别的(浏览器关闭即失效)。
  • 密码验证:使用 password_verify() 验证用户输入的密码和数据库中存储的哈希值是否匹配。
  • 登出完整性:清空 $_SESSION、调用 session_destroy()、删除浏览器端的 Session Cookie——三步缺一不可。
  • 重定向后显示消息:处理完登录/登出后,把提示消息存入 Session,然后重定向到首页。首页读取并显示消息后立即清除——这是 Flash Message(一次性消息)的标准实现方式。

九、本篇动手练习

练习 1:实现用户偏好设置

新建 practice8-1.php,用 Cookie 存储用户的主题偏好(亮色/暗色)和字体大小。用户通过表单选择偏好后,页面使用相应的样式。Cookie 有效期设为 30 天。

练习 2:简单的购物车

新建 practice8-2.php,用 Session 实现一个简单的购物车。用户可以”添加商品到购物车”(商品列表可以是硬编码的数组),购物车页面显示所有已添加的商品、数量和总价。用户关闭浏览器再打开,购物车内容还在(默认 Session Cookie 在浏览器关闭时失效,可以不处理这个)。

练习 3:登录次数限制

新建 practice8-3.php,在登录功能中增加失败次数限制。同一个 IP 地址在 15 分钟内连续登录失败 5 次,锁定该 IP 15 分钟。用 Session 或数据库记录失败次数和时间。

练习 4:完整的注册登录系统

新建一个完整的项目文件夹,包含注册页面(参考第七篇的综合演示)、登录页面(参考本篇的综合演示)、个人中心页面、退出登录功能。确保:CSRF Token 防护、密码哈希存储、会话固定防御、XSS 输出转义、SQL 注入防护——安全措施全部到位。

十、本篇小结

这一篇你学会了 PHP 中状态管理的两个核心机制:

  • Cookie:浏览器端的存储。通过 setcookie() 创建,通过 $_COOKIE 读取,把过期时间设为过去来删除。有大小限制(4KB),每次请求都会自动发送给服务器。
  • Session:服务器端的存储。通过 session_start() 启动,通过 $_SESSION 存取数据。依赖 Cookie 传递 Session ID(PHPSESSID)。
  • Cookie 安全属性HttpOnly(禁止 JS 访问)、Secure(仅 HTTPS)、SameSite(控制跨站携带)。Session Cookie 必须开启 HttpOnly。
  • Session 安全:登录后重新生成 Session ID(session_regenerate_id(true))防止会话固定。严格模式拒绝未初始化的 Session ID。只通过 Cookie 传递 Session ID,禁止 URL 传递。
  • 登录系统:完整的登录/登出流程——验证身份、存储 Session、Flash Message 提示、”记住我”功能。

Session 和 Cookie 是 Web 开发中最基础的状态管理机制。掌握了它们,你就能实现登录状态保持、购物车、用户偏好、表单多步骤提交等任何需要”跨请求记住信息”的功能。下一篇,我们学习 PHP 面向对象编程——类、对象、继承、封装、命名空间。

下一篇预告

下一篇——《PHP 面向对象编程——类、对象与继承》:理解类和对象的概念、构造函数和析构函数、访问修饰符(public/private/protected)、继承和多态、静态属性和方法、命名空间的使用。面向对象是现代 PHP 框架的基础。

PHP 零基础入门,每周更新。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容