PHP怎样获取栏目过期时间_PHP取栏目过期法【时效】

1次阅读

php通过查询数据库获取expires_at字段值,转为datetime对象后与当前时间比较判断是否过期,需注意时区一致、NULL处理及字段类型为datetime/timestamp

PHP怎样获取栏目过期时间_PHP取栏目过期法【时效】

PHP 怎么读取栏目过期时间(expires_at 字段)

栏目过期时间不是 PHP 内置概念,而是业务逻辑中常见的字段,通常存于数据库(如 mysql)的栏目表里,字段名可能是 expires_atexpire_timevalid_until。PHP 本身不“知道”栏目是否过期,得你主动查、解析、比对。

典型做法是:查出该栏目的 expires_at 值 → 转成时间戳或 DateTime 对象 → 和当前时间比较。

  • 确保字段类型是 DATETIMETIMESTAMP,避免用字符串存时间(如 "2025-03-15" 不带时分秒易出错)
  • 注意时区:PHP 默认时区(date_default_timezone_set())和数据库时区要一致,否则 now()strtotime() 结果会偏差
  • 如果字段允许为 NULL,必须先判断,否则 strtotime(null) 返回 false,后续比较可能意外通过

pdo 查询并判断栏目是否已过期

这是最常用且安全的方式,避免 SQL 注入,也方便处理 NULL 和时区。

$stmt = $pdo->prepare("SELECT id, title, expires_at FROM categories WHERE id = ?"); $stmt->execute([$catId]); $category = $stmt->fetch(PDO::FETCH_ASSOC);  if (!$category || !$category['expires_at']) {     // 栏目不存在,或未设置过期时间 → 视为永不过期     $isExpired = false; } else {     $expireTime = new DateTime($category['expires_at']);     $now = new DateTime(); // 自动使用 date_default_timezone_set() 设定的时区     $isExpired = $expireTime < $now; }

关键点:

立即学习PHP免费学习笔记(深入)”;

  • new DateTime($category['expires_at']) 能自动识别标准日期格式(如 "2025-04-10 18:30:00"),比 strtotime() 更健壮
  • 不要直接拼接 SQL,比如 "WHERE expires_at —— 这会让逻辑耦合在 SQL 层,不利于单元测试和调试
  • 如果需要批量判断多个栏目,建议一次性查出所有 expires_at,再用 PHP 循环判断,别在循环里反复查库

常见错误:把时间戳当字符串比较

有人会这样写:

$row['expires_at'] < time() // ❌ 危险!$row['expires_at'] 是字符串 "2025-04-10 12:00:00"

PHP 会把字符串转成整数(从左开始取数字),"2025-04-10..."2025,永远小于 time()(约 17亿),导致“所有栏目都显示已过期”。

正确做法只有两种:

  • DateTime 对象做比较(推荐)
  • strtotime($row['expires_at']) 转成时间戳再比(但需检查返回值是否为 false

别图省事跳过类型转换

缓存场景下怎么保证过期判断实时?

如果栏目数据被 redis 或 APCu 缓存了,而 expires_at 又是动态变化的,不能只缓存栏目基本信息,还得把过期判断逻辑移出缓存层。

  • 缓存栏目元数据(idtitleexpires_at),但每次读缓存后仍要执行时间比对
  • 不要缓存 is_expired 的布尔结果 —— 它随时间推移自动翻转,缓存失效策略很难设计
  • 如果性能敏感,可缓存“下次检查时间”,比如过期前 5 分钟再查一次 DB,但实现复杂,多数项目没必要

真正容易被忽略的是:缓存键没包含时区信息,或者本地开发环境用 Asia/Shanghai,线上用 UTC,会导致同一份缓存数据在不同环境判断结果相反。

text=ZqhQzanResources