PHP常用函数方法常识五

  1. 人性化时间
    function relativeTime($timestamp) {
    // 将时间戳转换为DateTime对象
    $givenTime = new DateTime($timestamp);
    $currentTime = new DateTime();
    
    // 计算时间差
    $interval = $currentTime->diff($givenTime);
    
    // 获取时间差的天数、小时和分钟
    $days = $interval->days;
    $hours = $interval->h;
    $minutes = $interval->i;
    
    // 根据时间差返回相应的描述
    if ($days >= 7) {
        // 一周或更长时间前
        $weeks = floor($days / 7);
        return "{$weeks}周前";
    } elseif ($days > 0) {
        // 多天前
        return "{$days}天前";
    } elseif ($hours > 0) {
        // 多小时前
        return "{$hours}小时前";
    } elseif ($minutes > 0) {
        // 多分钟前
        return "{$minutes}分钟前";
    } else {
        // 1分钟内
        return "刚刚";
    }
    }
    
  2. 根据身份证获取年龄
    /**
     * 根据身份证号码计算年龄(兼容15/18位,含合法性校验)
     * @param string $idCard 身份证号码
     * @return int|false 成功返回年龄,失败返回false
     */
    function getAgeFromIdCard(string $idCard)
    {
        // 第一步:校验身份证格式(基础正则)
        $idCard = trim($idCard);
        $pattern18 = '/^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))\d{3}[\dXx]$/';
        $pattern15 = '/^[1-9]\d{5}\d{2}((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))\d{3}$/';
    
        if (!preg_match($pattern18, $idCard) && !preg_match($pattern15, $idCard)) {
            return false; // 身份证格式非法
        }
    
        // 第二步:解析出生日期
        $birthDate = '';
        if (strlen($idCard) === 18) {
            // 18位:截取7-14位(YYYYMMDD)
            $birthDate = substr($idCard, 6, 8);
        } elseif (strlen($idCard) === 15) {
            // 15位:截取7-12位(YYMMDD),补全为19YYMMDD(15位身份证均为19xx年出生)
            $birthDate = '19' . substr($idCard, 6, 6);
        }
    
        // 第三步:格式化出生日期为 DateTime 对象(严格格式校验 Ymd)
        try {
            $birth = DateTime::createFromFormat('Ymd', $birthDate);
            if (!$birth) {
                return false; // 出生日期不合法(如19990230、19941301)
            }
    
            // 可选:固定基准时间(用于测试,如2026-01-17),生产环境可注释,使用服务器当前时间
            $now = DateTime::createFromFormat('Y-m-d H:i:s', '2026-01-17 10:11:30');
            // 生产环境:使用服务器当前时间
            // $now = new DateTime();
    
            // 第四步:计算年龄(核心修正:直接使用 diff()->y,无需重复减1)
            $age = $now->diff($birth)->y;
    
            // 优化:仅处理边界场景(避免负数年龄,如未来出生日期)
            $finalAge = $age < 0 ? 0 : $age;
    
            // 第五步:完善日志,便于排查
            // think\facade\Log::warning('根据身份证号码计算年龄成功:身份证=' . $idCard . ',出生日期=' . $birth->format('Y-m-d') . ',
            // 当前时间=' . $now->format('Y-m-d H:i:s') . ',最终年龄=' . $finalAge);
            return $finalAge;
        } catch (Exception $e) {
            think\facade\Log::error('身份证年龄计算异常:' . $idCard . ',异常信息:' . $e->getMessage());
            return false;
        }
    }