话说

因为BearSimple主题功能太多,昨天才发现有一个幻灯片的功能没使用,但是我好像没有什么东西可以放上去,思来想去好像可以做一个友链随机跳转。
本站随机跳转链接(点击幻灯片一样的效果):https://blog.lmb.blue/other/links-go.php

实现

BearSimple有独立的友链数据库表,所以可以直接用php连接数据库获取友链链接,进行随机访问。中间过渡页面是使用开往的plain简洁版页面(作者是:Lifeni)
具体代码如下:

<?php
// 数据库配置
$config = [
    'host'     => getenv('DB_HOST') ?: '127.0.0.1',
    'user'     => getenv('DB_USER') ?: 'lmb520',
    'password' => getenv('DB_PASS') ?: 'lmb520lmb520',
    'dbname'   => getenv('DB_NAME') ?: 'lmb520'
];

// 初始化变量
$hasValidLink = false;
$randomLink = ['url' => '', 'name' => ''];
$errorMessage = '';

// 连接数据库并获取随机友链
try {
    // 创建连接(启用异常模式)
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn = new mysqli($config['host'], $config['user'], $config['password'], $config['dbname']);
    $conn->set_charset('utf8mb4');

    // 查询所有已批准的友链
    $stmt = $conn->prepare("SELECT friendurl, friendname FROM typecho_bscore_friendlinks WHERE status = 'approved'");
    $stmt->execute();
    $result = $stmt->get_result();

    $links = [];
    while ($row = $result->fetch_assoc()) {
        $url = $row['friendurl'];
        $name = $row['friendname'];

        // 严格验证URL:必须包含协议且为http/https,防止危险协议
        if (filter_var($url, FILTER_VALIDATE_URL)) {
            $scheme = parse_url($url, PHP_URL_SCHEME);
            if ($scheme === 'http' || $scheme === 'https') {
                $links[] = ['url' => $url, 'name' => $name];
            }
        }
    }

    $stmt->close();
    $conn->close();

    // 随机选取一个有效友链
    if (!empty($links)) {
        $hasValidLink = true;
        $randomLink = $links[array_rand($links)];
    } else {
        $errorMessage = '暂无可用的友情链接,请稍后再试或申请加入友链。';
    }
} catch (mysqli_sql_exception $e) {
    // 数据库错误:记录日志,但不暴露敏感信息给用户
    error_log('Database error in random link page: ' . $e->getMessage());
    $errorMessage = '系统繁忙,请稍后再试。';
} catch (Exception $e) {
    error_log('Unexpected error: ' . $e->getMessage());
    $errorMessage = '发生未知错误,请联系管理员。';
}

// 准备跳转相关数据(安全转义)
$redirectUrl = $hasValidLink ? $randomLink['url'] : '';
$redirectName = $hasValidLink ? htmlspecialchars($randomLink['name'], ENT_QUOTES, 'UTF-8') : '';
$jsonUrl = json_encode($redirectUrl, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG);
?>
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="沉墨满纸,一笑若白。——林墨白">
    <title>星际穿梭中 - 哈喽!林墨白</title>
    <link rel="shortcut icon" href="https://files.blog.lmb520.cn/assets/img/logo/pink-black.png">
    <link rel="stylesheet" href="https://files.blog.lmb520.cn/assets/css/links-go.css">
    <?php if ($hasValidLink): ?>
    <script>
        // 安全跳转:3秒后自动跳转
        setTimeout(function() {
            window.location.replace(<?php echo $jsonUrl; ?>);
        }, 3000);
    </script>
    <?php endif; ?>
</head>
<body>
<main>
    <h1>
        <span>哈喽!林墨白</span>
        <?php if ($hasValidLink): ?>
        <span>正在驶入“<?php echo $redirectName; ?>”星云</span>
        <?php else: ?>
        <span>星云导航暂时中断</span>
        <?php endif; ?>
    </h1>

    <?php if ($hasValidLink): ?>
    <!-- Material Design 风格加载动画 -->
    <svg class="spinner" width="32px" height="32px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
        <circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
    </svg>
    <?php else: ?>
    <div class="error-message" style="margin: 2rem auto; text-align: center; color: #ff6b6b;">
        <p><?php echo htmlspecialchars($errorMessage, ENT_QUOTES, 'UTF-8'); ?></p>
        <p>您可以选择返回首页或申请加入友链。</p>
    </div>
    <?php endif; ?>
</main>

<footer>
    <a href="https://blog.lmb520.cn/" target="_blank" rel="noopener noreferrer">返回首页</a>
    <a href="https://blog.lmb520.cn/links.html" target="_blank" rel="noopener noreferrer">加入友链</a>
    <a href="https://github.com/Lifeni" target="_blank" rel="noopener noreferrer">模板作者</a>
    <span></span>
    <a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener noreferrer">蜀ICP备-2023019525号-1</a>
</footer>
</body>
</html>

里面的css调用代码可以将

<link rel="stylesheet" href="https://files.blog.lmb520.cn/assets/css/links-go.css">

改为

<style>
      /* 色板:https://www.materialui.co/colors */
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }

      body {
        font-family: Inter, -apple-system, HarmonyOS Sans SC, MiSans,
          Source Han Sans SC, Noto Sans SC, system-ui, Roboto, emoji, sans-serif;
        color: black;
        background: white;
        font-weight: 400;
        font-size: 1rem;
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }

      main {
        padding: 2rem;
        flex: 1;
        display: flex;
        gap: 2rem;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }

      main h1 {
        margin-top: 4rem;
        font-size: 1.75rem;
        font-weight: 700;
        line-height: 1.75;
        text-align: center;
      }

      main h1 span {
        white-space: nowrap;
      }

      footer {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem 1.5rem;
        align-items: center;
        justify-content: center;
        padding: 1.75rem 2rem;
      }

      footer a {
        font-size: 0.875rem;
        text-decoration: none;
        color: #757575;
        transition: all 0.2s;
      }

      footer span {
        flex: 1;
      }

      footer a:hover {
        color: #3f51b5;
        text-decoration: underline;
        text-underline-offset: 0.25rem;
      }

      @media (prefers-color-scheme: dark) {
        body {
          color: #eeeeee;
          background: #212121;
        }

        footer a {
          color: #bdbdbd;
          transition: all 0.2s;
        }

        footer a:hover {
          color: #5c6bc0;
        }
      }

      @media screen and (max-width: 768px) {
        main {
          margin-top: 4.5rem;
        }

        main h1 {
          font-size: 1.5rem;
        }

        footer {
          gap: 0.5rem 1rem;
        }

        footer span {
          display: none;
        }
      }

      /* Material Design 风格的加载动画 https://codepen.io/mrrocks/pen/ExLovj  */
      .spinner {
        -webkit-animation: rotator 1.4s linear infinite;
        animation: rotator 1.4s linear infinite;
      }

      @-webkit-keyframes rotator {
        0% {
          transform: rotate(0deg);
        }
        100% {
          transform: rotate(270deg);
        }
      }

      @keyframes rotator {
        0% {
          transform: rotate(0deg);
        }
        100% {
          transform: rotate(270deg);
        }
      }

      .path {
        stroke-dasharray: 187;
        stroke-dashoffset: 0;
        transform-origin: center;
        -webkit-animation: dash 1.4s ease-in-out infinite,
          colors 5.6s ease-in-out infinite;
        animation: dash 1.4s ease-in-out infinite,
          colors 5.6s ease-in-out infinite;
      }

      @-webkit-keyframes colors {
        0% {
          stroke: #4285f4;
        }
        25% {
          stroke: #de3e35;
        }
        50% {
          stroke: #f7c223;
        }
        75% {
          stroke: #1b9a59;
        }
        100% {
          stroke: #4285f4;
        }
      }

      @keyframes colors {
        0% {
          stroke: #4285f4;
        }
        25% {
          stroke: #de3e35;
        }
        50% {
          stroke: #f7c223;
        }
        75% {
          stroke: #1b9a59;
        }
        100% {
          stroke: #4285f4;
        }
      }
      @-webkit-keyframes dash {
        0% {
          stroke-dashoffset: 187;
        }
        50% {
          stroke-dashoffset: 46.75;
          transform: rotate(135deg);
        }
        100% {
          stroke-dashoffset: 187;
          transform: rotate(450deg);
        }
      }
      @keyframes dash {
        0% {
          stroke-dashoffset: 187;
        }
        50% {
          stroke-dashoffset: 46.75;
          transform: rotate(135deg);
        }
        100% {
          stroke-dashoffset: 187;
          transform: rotate(450deg);
        }
      }
</style>

因为有可能我会移动样式文件,但是我移动后也会及时更新除非我忘了,所以建议自己放在代码里或者找个地方储存调用

注意

代码里面有很多需要自己按情况修改,比如数据库信息、网页内容、网站图标等等