PHP 短链接 API:SQLite 单文件实现创建和跳转接口 [复制链接]

一级用户组

短链接是 API 站点常见工具接口。下面代码使用 SQLite 存储,包含创建短链和访问跳转两个接口,单文件可运行。

<?php
declare(strict_types=1);

$baseUrl = 'http://127.0.0.1:8000';
$pdo = new PDO('sqlite:' . __DIR__ . '/shortlink.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec('CREATE TABLE IF NOT EXISTS links (
    code TEXT PRIMARY KEY,
    url TEXT NOT NULL,
    created_at TEXT NOT NULL,
    clicks INTEGER NOT NULL DEFAULT 0
)');

function response(int $code, string $message, $data = null, int $status = 200): void
{
    http_response_code($status);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(compact('code', 'message', 'data'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function input(): array
{
    $data = json_decode(file_get_contents('php://input') ?: '{}', true);
    return is_array($data) ? $data : [];
}

function code(int $length = 6): string
{
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $value = '';
    for ($i = 0; $i < $length; $i++) {
        $value .= $chars[random_int(0, strlen($chars) - 1)];
    }
    return $value;
}

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$path = trim(parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH), '/');

if ($method === 'POST' && $path === 'api/short-links') {
    $data = input();
    $url = trim((string)($data['url'] ?? ''));
    if (!filter_var($url, FILTER_VALIDATE_URL)) {
        response(422, 'url 格式错误', null, 422);
    }

    do {
        $shortCode = code();
        $exists = $pdo->prepare('SELECT code FROM links WHERE code = ?');
        $exists->execute([$shortCode]);
    } while ($exists->fetchColumn());

    $stmt = $pdo->prepare('INSERT INTO links(code, url, created_at) VALUES (?, ?, ?)');
    $stmt->execute([$shortCode, $url, date('Y-m-d H:i:s')]);

    response(0, '创建成功', [
        'code' => $shortCode,
        'short_url' => rtrim($baseUrl, '/') . '/' . $shortCode,
        'url' => $url,
    ], 201);
}

if ($method === 'GET' && preg_match('/^[a-zA-Z0-9]{4,20}$/', $path)) {
    $stmt = $pdo->prepare('SELECT url FROM links WHERE code = ?');
    $stmt->execute([$path]);
    $url = $stmt->fetchColumn();
    if (!$url) {
        response(404, '短链接不存在', null, 404);
    }
    $pdo->prepare('UPDATE links SET clicks = clicks + 1 WHERE code = ?')->execute([$path]);
    header('Location: ' . $url, true, 302);
    exit;
}

response(404, '接口不存在', null, 404);

本地测试:

# 启动服务
php -S 127.0.0.1:8000 shortlink-api.php

# 创建短链
curl -X POST http://127.0.0.1:8000/api/short-links   -H 'Content-Type: application/json'   -d '{"url":"https://example.com"}'

# 访问返回中的 short_url 即可跳转
最新回复

请先登录后再回复 登录

uid:4 一级用户组
关注
我与春风皆过客,你携秋水揽星河
发帖 20
评论 0
粉丝 0
关注 0
发新帖
目录
PHP 短链接 API:SQLite 单文件实现创建和跳转接口