PHP项目分享链接如何设置过期时间

wen PHP项目 28

本文目录导读:

PHP项目分享链接如何设置过期时间

  1. 在URL中嵌入过期时间戳
  2. 使用数据库存储和管理
  3. 使用Redis实现(高性能方案)
  4. 分享链接控制器示例
  5. 推荐方案选择
  6. 安全建议

在PHP项目中实现分享链接过期时间,常见有这几种方式:

在URL中嵌入过期时间戳

<?php
// 生成分享链接
function generateShareLink($fileId, $expireHours = 24) {
    $expireTime = time() + ($expireHours * 3600);
    $token = md5($fileId . $expireTime . 'your-secret-key');
    $link = "http://yourdomain.com/share.php?id={$fileId}&expire={$expireTime}&token={$token}";
    return $link;
}
// 验证分享链接
function validateShareLink($fileId, $expireTime, $token) {
    // 1. 检查是否过期
    if (time() > $expireTime) {
        return ['valid' => false, 'message' => '链接已过期'];
    }
    // 2. 验证token
    $expectedToken = md5($fileId . $expireTime . 'your-secret-key');
    if ($token !== $expectedToken) {
        return ['valid' => false, 'message' => '无效的链接'];
    }
    return ['valid' => true, 'message' => '链接有效'];
}
// 使用示例
$link = generateShareLink('file_123', 48); // 48小时过期
echo "分享链接:<a href='{$link}'>{$link}</a>";
?>

使用数据库存储和管理

<?php
// 数据库表结构
// CREATE TABLE share_links (
//     id INT PRIMARY KEY AUTO_INCREMENT,
//     file_id VARCHAR(100),
//     token VARCHAR(64) UNIQUE,
//     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
//     expires_at TIMESTAMP,
//     is_active BOOLEAN DEFAULT TRUE,
//     access_count INT DEFAULT 0,
//     max_access INT DEFAULT NULL
// );
// 生成分享链接
function createShareLink($fileId, $expireHours = 24, $maxAccess = null) {
    $db = new PDO('mysql:host=localhost;dbname=yourdb', 'user', 'pass');
    $token = bin2hex(random_bytes(32)); // 生成随机token
    $expiresAt = date('Y-m-d H:i:s', strtotime("+{$expireHours} hours"));
    $stmt = $db->prepare("INSERT INTO share_links (file_id, token, expires_at, max_access) VALUES (?, ?, ?, ?)");
    $stmt->execute([$fileId, $token, $expiresAt, $maxAccess]);
    return "http://yourdomain.com/share/{$token}";
}
// 验证并访问分享链接
function accessShareLink($token) {
    $db = new PDO('mysql:host=localhost;dbname=yourdb', 'user', 'pass');
    $stmt = $db->prepare("SELECT * FROM share_links WHERE token = ? AND is_active = TRUE");
    $stmt->execute([$token]);
    $link = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$link) {
        return ['valid' => false, 'message' => '链接不存在'];
    }
    // 检查过期时间
    if (strtotime($link['expires_at']) < time()) {
        // 自动标记为过期
        $db->prepare("UPDATE share_links SET is_active = FALSE WHERE id = ?")->execute([$link['id']]);
        return ['valid' => false, 'message' => '链接已过期'];
    }
    // 检查访问次数限制
    if ($link['max_access'] !== null && $link['access_count'] >= $link['max_access']) {
        return ['valid' => false, 'message' => '已达到访问次数限制'];
    }
    // 更新访问计数
    $db->prepare("UPDATE share_links SET access_count = access_count + 1 WHERE id = ?")->execute([$link['id']]);
    return [
        'valid' => true,
        'file_id' => $link['file_id'],
        'access_count' => $link['access_count'] + 1
    ];
}
?>

使用Redis实现(高性能方案)

<?php
class RedisShareLink {
    private $redis;
    private $prefix = 'share_link:';
    public function __construct() {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }
    // 生成分享链接
    public function createLink($fileId, $ttl = 86400) { // ttl: 过期时间(秒),默认24小时
        $token = bin2hex(random_bytes(16));
        $key = $this->prefix . $token;
        // 存储文件ID,设置过期时间
        $this->redis->setex($key, $ttl, $fileId);
        return "http://yourdomain.com/share/{$token}";
    }
    // 获取文件
    public function getFile($token) {
        $key = $this->prefix . $token;
        $fileId = $this->redis->get($key);
        if ($fileId === false) {
            return ['valid' => false, 'message' => '链接已过期或无效'];
        }
        // 可选:限制访问次数
        $accessKey = $key . ':access';
        $accessCount = $this->redis->incr($accessKey);
        // 如果设置最大访问次数
        if ($accessCount > 5) { // 最多访问5次
            $this->redis->del($key); // 删除链接
            return ['valid' => false, 'message' => '已达到访问次数限制'];
        }
        // 设置访问计数过期时间(与主key相同)
        $this->redis->expire($accessKey, $this->redis->ttl($key));
        return ['valid' => true, 'file_id' => $fileId];
    }
    // 手动删除链接
    public function revokeLink($token) {
        $key = $this->prefix . $token;
        return $this->redis->del($key);
    }
}
// 使用示例
$share = new RedisShareLink();
// 创建48小时过期的链接
$link = $share->createLink('file_456', 172800);
echo "分享链接:{$link}";
// 验证链接
$result = $share->getFile('token123');
if ($result['valid']) {
    echo "文件ID:" . $result['file_id'];
} else {
    echo "错误:" . $result['message'];
}
?>

分享链接控制器示例

<?php
// share_controller.php
class ShareController {
    // 生成分享链接
    public function createShareLink($request) {
        $fileId = $request['file_id'];
        $expireType = $request['expire_type'] ?? '24h'; // 7d, 30d, forever
        $expireMap = [
            '1h' => 3600,
            '24h' => 86400,
            '7d' => 604800,
            '30d' => 2592000,
            'forever' => null
        ];
        $ttl = $expireMap[$expireType] ?? 86400;
        // 生成链接
        if ($ttl === null) {
            // 永久链接,不过期
            $link = $this->generatePermanentLink($fileId);
        } else {
            $link = $this->generateExpiringLink($fileId, $ttl);
        }
        return [
            'success' => true,
            'link' => $link,
            'expires_in' => $ttl,
            'created_at' => date('Y-m-d H:i:s')
        ];
    }
    // 前端页面显示
    public function sharePage() {
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title>分享文件</title>
        </head>
        <body>
            <form method="POST" action="/api/share">
                <input type="hidden" name="file_id" value="123">
                <label>过期时间:</label>
                <select name="expire_type">
                    <option value="1h">1小时</option>
                    <option value="24h" selected>24小时</option>
                    <option value="7d">7天</option>
                    <option value="30d">30天</option>
                    <option value="forever">永久</option>
                </select>
                <button type="submit">生成分享链接</button>
            </form>
        </body>
        </html>
        <?php
    }
}
?>

推荐方案选择

  • 小型项目:使用URL嵌入时间戳方式,简单直接
  • 中型项目:使用数据库方案,管理更灵活
  • 高性能需求:使用Redis方案,速度快,支持自动过期
  • 安全性要求高:结合数据库+加密token,记录访问日志

安全建议

  1. 使用HTTPS传输
  2. token长度至少32位,使用随机生成
  3. 重要文件限制访问次数
  4. 记录访问日志便于审计
  5. 定期清理已过期的链接记录

抱歉,评论功能暂时关闭!