阅读视图

发现新文章,点击刷新页面。

子比主题文章归档页面美化版

前言

因为自己喜欢倒腾,所以从Corenext换成了子比,但不代表Corenext不好,Corenext主题绝对是做博客的首选。

我换成子比是为了倒腾一些小玩意,今天就给大家带来自己弄的一个美化版的文章归档页面

展示

图片[1]-新锐博客
图片[2]-新锐博客

教程

在子比主题的pages目录下创建一个新的php,名字随便命名,然后将如下代码放入进去

<?php
/**
 * Template name: 新锐-文章归档
 * Description: 文章归档页面,包含统计数据和文章列表
 */

// 获取分类统计信息并缓存
function get_category_statistics() {
    return get_cached_data('category_stats', function() {
        $categories = get_categories(['hide_empty' => false]);
        $data = [];
        foreach ($categories as $category) {
            $data[] = ['value' => $category->count, 'name' => $category->name];
        }
        return json_encode($data);
    });
}

// 获取最近一年每月的文章数量并缓存
function get_monthly_post_data() {
    return get_cached_data('monthly_post_data', function() {
        global $wpdb;
        $query = "
            SELECT DATE_FORMAT(post_date, '%Y-%m') AS month, COUNT(*) AS count
            FROM {$wpdb->posts}
            WHERE post_type = 'post' AND post_status = 'publish'
              AND post_date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
            GROUP BY month
            ORDER BY month ASC
        ";
        $results = $wpdb->get_results($query, ARRAY_A);

        $monthly_data = [];
        foreach ($results as $result) {
            $monthly_data[] = [
                'month' => $result['month'],
                'count' => $result['count']
            ];
        }
        return json_encode($monthly_data);
    });
}

// 缓存处理函数
function get_cached_data($transient_key, $callback) {
    if (false === ($data = get_transient($transient_key))) {
        $data = call_user_func($callback);
        set_transient($transient_key, $data, 12 * HOUR_IN_SECONDS);
    }
    return $data;
}

// 统计小工具
function render_archives_widgets($type = 'day') {
    $icons = [
        'day' => ['icon' => 'fa fa-calendar', 'color' => 'c-blue', 'title' => '运营时间'],
        'post' => ['icon' => 'fa fa-file-text', 'color' => 'c-green', 'title' => '文章总数'],
        'comment' => ['icon' => 'fa fa-comments', 'color' => 'c-purple', 'title' => '评论总数'],
        'user' => ['icon' => 'fa fa-users', 'color' => 'c-orange', 'title' => '注册用户']
    ];

    switch ($type) {
        case 'day':
            $first_post = get_posts(['numberposts' => 1, 'order' => 'ASC']);
            $start_time = !empty($first_post) ? strtotime($first_post[0]->post_date) : time();
            $statistic = round((time() - $start_time) / DAY_IN_SECONDS) . ' 天';
            break;
        case 'post':
            $statistic = wp_count_posts()->publish;
            break;
        case 'comment':
            $statistic = get_comment_count()['total_comments'];
            break;
        case 'user':
            $statistic = count_users()['total_users'];
            break;
        default: return;
    }

    echo '<div class="stats-widget">';
    echo '<div class="stats-header">'.$icons[$type]['title'].'</div>';
    echo '<div class="stats-content">';
    echo '<div class="stats-icon"><i class="'.$icons[$type]['icon'].' '.$icons[$type]['color'].'"></i></div>';
    echo '<div class="stats-value">'.$statistic.'</div>';
    echo '</div></div>';
}

// 注册脚本
function grace_archives_scripts() {
  
    wp_enqueue_script('echarts', 'https://cdn.jsdmirror.com/npm/echarts@5.4.0/dist/echarts.min.js', [], null, true);
     wp_enqueue_script('archives-script', get_template_directory_uri().'/js/archives.js', ['echarts', 'jquery'], null, true);
    
    // 将数据传递给 JavaScript
    wp_localize_script('archives-script', 'graceData', [
        'postData' => json_decode(get_category_statistics()),
        'monthlyPostData' => json_decode(get_monthly_post_data()),
        'ajaxUrl' => admin_url('admin-ajax.php')
    ]);
}
add_action('wp_enqueue_scripts', 'grace_archives_scripts');

// AJAX 处理翻页请求
function load_more_posts() {
    $paged = isset($_POST['page']) ? intval($_POST['page']) : 1;
    $posts_per_page = 20;

    $query = new WP_Query([
        'posts_per_page' => $posts_per_page,
        'paged' => $paged,
        'orderby' => 'post_date',
        'order' => 'DESC',
        'post_status' => 'publish'
    ]);

    if ($query->have_posts()) :
        $organized = [];
        while ($query->have_posts()) : $query->the_post();
            $year = get_the_time('Y');
            $month = get_the_time('m');
            $organized[$year][$month][] = $post;
        endwhile;

        ob_start();
        foreach ($organized as $year => $months) : ?>
            <div class="archive-year">
                <h2 class="year-title"><?php echo $year; ?></h2>
                <?php foreach ($months as $month => $posts) : ?>
                    <div class="archive-month">
                        <h3 class="month-title"><?php echo date('n月', mktime(0, 0, 0, $month, 1)); ?></h3>
                        <ul class="post-list">
                            <?php foreach ($posts as $post) : setup_postdata($post); ?>
                                <li>
                                    <time><?php the_time('m-d'); ?></time>
                                    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
                                        <?php the_title(); ?>
                                        <?php if (get_comments_number()) : ?>
                                            <span class="comment-count">(<?php echo get_comments_number(); ?>)</span>
                                        <?php endif; ?>
                                    </a>
                                </li>
                            <?php endforeach; ?>
                        </ul>
                    </div>
                <?php endforeach; ?>
            </div>
        <?php endforeach;

        // 生成新的分页链接
        $pagination = paginate_links([
            'total' => $query->max_num_pages,
            'current' => $paged,
            'prev_next' => true,
            'prev_text' => __('« 上一页'),
            'next_text' => __('下一页 »'),
            'echo' => false
        ]);

        $output = ob_get_clean();
        wp_send_json_success([
            'data' => $output,
            'pagination' => $pagination
        ]);
    else :
        wp_send_json_error('No more posts');
    endif;
    wp_reset_postdata();
    wp_die();
}
add_action('wp_ajax_load_more_posts', 'load_more_posts');
add_action('wp_ajax_nopriv_load_more_posts', 'load_more_posts');

get_header();
?>

<main class="grace-archives">
    <div class="archive-container">
        <div class="archive-main">
            <article class="archive-article">
                <header class="archive-header">
                    <h1><?php the_title(); ?></h1>
                    <!-- 统计小工具 -->
                    <div class="stats-grid">
                        <?php 
                        render_archives_widgets('day');
                        render_archives_widgets('post');
                        render_archives_widgets('comment');
                        render_archives_widgets('user');
                        ?>
                    </div>
                </header>
                
                <!-- 图表区域 -->
                <div class="charts-container">
                    <div class="chart-box" id="postChart"></div>
                    <div class="chart-box" id="monthlyPostChart"></div>
                </div>

                <!-- 文章列表 -->
                <div class="archives-list">
                    <?php
                    // 获取当前页码
                    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
                    $posts_per_page = 20;
                    
                    $query = new WP_Query([
                        'posts_per_page' => $posts_per_page,
                        'paged' => $paged,
                        'orderby' => 'post_date',
                        'order' => 'DESC',
                        'post_status' => 'publish'
                    ]);

                    if ($query->have_posts()) :
                        $organized = [];
                        while ($query->have_posts()) : $query->the_post();
                            $year = get_the_time('Y');
                            $month = get_the_time('m');
                            $organized[$year][$month][] = $post;
                        endwhile;

                        foreach ($organized as $year => $months) : ?>
                            <div class="archive-year">
                                <h2 class="year-title"><?php echo $year; ?></h2>
                                <?php foreach ($months as $month => $posts) : ?>
                                    <div class="archive-month">
                                        <h3 class="month-title"><?php echo date('n月', mktime(0, 0, 0, $month, 1)); ?></h3>
                                        <ul class="post-list">
                                            <?php foreach ($posts as $post) : setup_postdata($post); ?>
                                                <li>
                                                    <time><?php the_time('m-d'); ?></time>
                                                    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
                                                        <?php the_title(); ?>
                                                        <?php if (get_comments_number()) : ?>
                                                            <span class="comment-count">(<?php echo get_comments_number(); ?>)</span>
                                                        <?php endif; ?>
                                                    </a>
                                                </li>
                                            <?php endforeach; ?>
                                        </ul>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        <?php endforeach; 
                    else :
                        echo '<p>暂无文章</p>';
                    endif;
                    wp_reset_postdata();
                    ?>
                </div>

                <!-- 传统分页 -->
<div class="archive-pagination">
    <?php
    echo paginate_links([
        'total'     => $query->max_num_pages,
        'current'   => $paged,
        'prev_next' => true,
        'prev_text' => __('« 上一页'),
        'next_text' => __('下一页 »'),
        'type'      => 'plain', // 修改这里
        'mid_size'  => 2 // 控制显示页码数量
    ]);
    ?>
</div>
            </article>
        </div>
    </div>
</main>


<script>
// 仅保留图表初始化代码
jQuery(document).ready(function($) {
    // 初始化 ECharts 图表
    const postChart = echarts.init(document.getElementById('postChart'));
    const monthlyPostChart = echarts.init(document.getElementById('monthlyPostChart'));

    postChart.setOption({
        title: { text: '文章分类分布' },
        tooltip: { trigger: 'item' },
        series: [{
            type: 'pie',
            data: graceData.postData
        }]
    });

    monthlyPostChart.setOption({
        title: { text: '每月发文数量' },
        tooltip: { trigger: 'axis' },
        xAxis: {
            type: 'category',
            data: graceData.monthlyPostData.map(item => item.month)
        },
        yAxis: { type: 'value' },
        series: [{
            type: 'line',
            data: graceData.monthlyPostData.map(item => item.count)
        }]
    });
});
</script>

<style>
.grace-archives {
    padding: 2rem 20px;
    background: #f8f9fa;
    min-height: 100vh;
}
/* 分页容器 */
.archive-pagination {
    margin-top: 3rem;
    text-align: center;
}

/* 分页链接基础样式 */
.archive-pagination a, 
.archive-pagination span {
    display: inline-block;
    padding: 8px 16px;
    margin: 0 4px;
    border: 1px solid #e0e0e0;
    border-radius: 4px;
    color: #3498db;
    text-decoration: none;
    transition: all 0.3s;
}

/* 当前页样式 */
.archive-pagination span.current {
    background: #3498db;
    color: white;
    border-color: #3498db;
}

/* 悬停效果 */
.archive-pagination a:hover {
    background: #f8f9fa;
    border-color: #3498db;
}

/* 移动端适配 */
@media (max-width: 480px) {
    .archive-pagination a, 
    .archive-pagination span {
        padding: 6px 12px;
        margin: 2px;
        font-size: 14px;
    }
}
.archive-container {
    max-width: 1400px;
    margin: 0 auto;
}

.archive-main {
    background: #fff;
    border-radius: 12px;
    padding: 2rem;
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}

.archive-header {
    margin-bottom: 2rem;
    border-bottom: 2px solid #f0f0f0;
    padding-bottom: 1.5rem;
}

.archive-header h1 {
    font-size: 2.2rem;
    color: #2c3e50;
    margin: 0 0 1.5rem;
}

/* 统计小工具 */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.5rem;
    margin: 2rem 0;
}

.stats-widget {
    background: #ffffff;
    border: 1px solid #eaeaea;
    padding: 1.5rem;
    border-radius: 10px;
    transition: transform 0.3s ease;
}

.stats-widget:hover {
    transform: translateY(-3px);
    box-shadow: 0 6px 16px rgba(0,0,0,0.1);
}

.stats-header {
    color: #7f8c8d;
    font-size: 0.95rem;
    margin-bottom: 0.8rem;
    font-weight: 500;
}

.stats-content {
    display: flex;
    align-items: center;
    gap: 1.2rem;
}

.stats-icon i {
    font-size: 2rem;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
}

.stats-value {
    font-size: 1.8rem;
    font-weight: 600;
    color: #2c3e50;
}

/* 颜色定义 */
.c-blue { background: #e3f2fd; color: #2196f3; }
.c-green { background: #e8f5e9; color: #4caf50; }
.c-purple { background: #f3e5f5; color: #9c27b0; }
.c-orange { background: #fff3e0; color: #ff9800; }

/* 图表容器 */
.charts-container {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
    margin: 3rem 0;
}

.chart-box {
    height: 400px;
    background: #fff;
    border: 1px solid #eee;
    border-radius: 10px;
    padding: 1rem;
}

/* 文章列表 */
.archives-list {
    margin-top: 2rem;
}

.archive-year {
    margin-bottom: 3rem;
    background: #fafafa;
    border-radius: 8px;
    padding: 1.5rem;
}

.year-title {
    font-size: 1.8rem;
    color: #2c3e50;
    margin: 0 0 1.5rem;
    padding-bottom: 0.8rem;
    border-bottom: 2px solid #eee;
}

.archive-month {
    margin-bottom: 2rem;
    background: #fff;
    border-radius: 6px;
    padding: 1rem;
    box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}

.month-title {
    font-size: 1.4rem;
    color: #34495e;
    margin: 0 0 1rem;
    padding-left: 0.5rem;
}

.post-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.post-list li {
    padding: 1rem 1.2rem;
    border-bottom: 1px solid #f5f5f5;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    transition: background 0.3s;
}

.post-list li:hover {
    background: #f8f9fa;
}

.post-list time {
    color: #7f8c8d;
    min-width: 70px;
    font-family: monospace;
    font-size: 0.95rem;
}

.post-list a {
    color: #2c3e50;
    transition: color 0.3s;
    flex-grow: 1;
    text-decoration: none;
    font-weight: 500;
}

.post-list a:hover {
    color: #3498db;
}

.comment-count {
    color: #95a5a6;
    font-size: 0.85em;
    margin-left: 0.8rem;
    font-weight: normal;
}

/* 分页样式 */
.archive-pagination {
    margin-top: 3rem;
    text-align: center;
    padding: 1.5rem 0;
}

.archive-pagination .page-numbers {
    display: inline-block;
    padding: 8px 16px;
    margin: 0 5px;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    color: #3498db;
    text-decoration: none;
    transition: all 0.3s;
}

.archive-pagination .page-numbers.current {
    background: #3498db;
    color: #fff;
    border-color: #3498db;
}

.archive-pagination .page-numbers:hover:not(.current) {
    background: #f8f9fa;
    border-color: #3498db;
}

/* 加载提示 */
.loading {
    text-align: center;
    padding: 1.5rem;
    color: #7f8c8d;
    font-size: 0.95rem;
}

/* 响应式设计 */
@media (max-width: 1200px) {
    .charts-container {
        grid-template-columns: 1fr;
    }
    .chart-box {
        height: 350px;
    }
}

@media (max-width: 768px) {
    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 1rem;
    }
    
    .stats-value {
        font-size: 1.6rem;
    }
    
    .archive-main {
        padding: 1.5rem;
    }
    
    .year-title {
        font-size: 1.6rem;
    }
}

@media (max-width: 480px) {
    .stats-grid {
        grid-template-columns: 1fr;
    }
    
    .stats-content {
        gap: 1rem;
    }
    
    .archive-pagination .page-numbers {
        padding: 6px 12px;
        margin: 3px;
    }
    
    .post-list li {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
        padding: 1rem;
    }
    
}
</style>
<?php get_footer(); ?>

再到子比主题根目录里的JS文件夹里创建一个archives.js的文件,然后将如下代码放进去

// archives.js 完整代码

document.addEventListener('DOMContentLoaded', function() {
    
     const chartContainers = [
        'postChart', 
        'monthlyPostChart'
    ];

    chartContainers.forEach(id => {
        const el = document.getElementById(id);
        if (!el) {
            console.warn(`图表容器 #${id} 未找到`);
            return;
        }
        
        try {
            // 初始化图表代码...
        } catch (error) {
            console.error(`初始化图表 ${id} 失败:`, error);
        }
    });
    // 获取图表容器
    const postChartEl = document.getElementById('postChart');
    const monthlyChartEl = document.getElementById('monthlyPostChart');
    
    // 检查元素是否存在
    if (!postChartEl || !monthlyChartEl) {
        console.warn('图表容器未找到,请检查元素ID是否正确');
        return;
    }

    // 初始化图表实例
    const postChart = echarts.init(postChartEl);
    const monthlyPostChart = echarts.init(monthlyChartEl);

    // 配置分类分布饼图
    postChart.setOption({
        title: { text: '文章分类分布', left: 'center' },
        tooltip: { trigger: 'item' },
        series: [{
            type: 'pie',
            radius: '55%',
            data: graceData.postData,
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }]
    });

    // 配置月度趋势折线图
    monthlyPostChart.setOption({
        title: { text: '月度发文趋势', left: 'center' },
        tooltip: { trigger: 'axis' },
        xAxis: {
            type: 'category',
            data: graceData.monthlyPostData.map(item => item.month),
            axisLabel: { rotate: 45 }
        },
        yAxis: { type: 'value' },
        series: [{
            type: 'line',
            smooth: true,
            data: graceData.monthlyPostData.map(item => item.count),
            areaStyle: { color: 'rgba(52, 152, 219, 0.2)' }
        }],
        grid: { containLabel: true }
    });

    // 窗口大小变化时自适应
    window.addEventListener('resize', function() {
        postChart.resize();
        monthlyPostChart.resize();
    });
});

最后再到页面中选择新锐-文章归档模版即可

记一次function代码无法生效的情况

前言

本人喜欢瞎搞,所以子主题的function.php文件中弄了不少东西,然后也就没太在意某些代码

记录

今天有人在前一篇文章进行了留言,然后我就想要回复他,突然想到之前在function中部署了关于WordPress回复他人邮件通知的功能。

但是一直没有试验有没有部署成功,因为同款主题的其他站长确定部署成功了,我就心血来潮的想要去测试一番。

于是我就在留言板回复了自己的留言,但是一直没有收到邮件,我就知道我没有部署成功。

接着,我就找到了同款主题的其他站长询问,因为安装了wpopt插件,而插件有评论站长收到邮件通知的功能。

所以自然而然就觉得是wpopt的问题了,便有了如下对话。

图片[1]-新锐博客

但是其他人都可以,为啥就我不行呢?有没有办法解决呢?

幸好现在有强大的AI,于是我就去deepseek官网,将之前的回复他人评论邮件通知的代码发给AI,并且提问为何不生效。

AI回复我可能是因为由于其他插件的缘故,导致回复他人邮件通知的功能被屏蔽掉了。于是我就想到了提高此功能的优先级。

我便让AI帮我把功能的优先级提高了。

最终有了新的代码,当然我也让AI美化了一下界面。

传送门

WordPress解决feed文件首行换行

前言

访问各个大佬博客的时候,有个类似开往的项目,名为blogsclub,站点地址:https://www.blogsclub.org/

过程

闲来无事就加入了其中,它有个功能是通过WordPress的feed抓取文章,但是我设置了feed却提示没有抓取成功
随后就收到了他们官方发出的邮件,提示feed文件首行出现了换行,众所周知,feed是由WordPress自行生成的,不像sitemap可以通过插件来生成
所以遇到此类麻烦就很难受,于是只能由最新大热的deepseek来解决,AI告诉我,需要检查各种php文件来确保之前并没有出现换行或空格
但是那样就很麻烦,所以我就让deepseek帮我把feed顶部的空格直接删掉就行了。
于是就有了以下教程

教程

将如下代码放到主题的function.php文件中

function remove_xml_declaration_whitespace() {
    // 检查当前页面是否是 feed 页面
    if (is_feed()) {
        // 清空所有现有的输出缓冲区
        while (ob_get_level() > 0) {
            ob_end_clean();
        }

        // 启动一个新的输出缓冲区,并指定回调函数
        ob_start(function($buffer) {
            // 使用正则表达式删除 XML 声明前的所有空格和换行符
            return preg_replace('/^s*(<?xml)/', '$1', $buffer);
        });
    }
}

// 将函数挂载到 WordPress 的 'wp' 动作上,优先级为 1
add_action('wp', 'remove_xml_declaration_whitespace', 1);

WordPress解决用户名枚举漏洞禁用REST API

前言

今天群里有人说会通过某个地址泄露用户名导致有被爆破的风险,并且给出了解决方案

教程

首先检查一下自己的网站有没有这个漏洞,访问如下网站即可

https://博客域名.com/wp-json/wp/v2/users/

如果有就到主题的function.php文件中添加如下代码

add_filter('rest_authentication_errors', function ($access) { return new wp_error('rest_cannot_access', 'REST API不再提供访问', ['status' => 403]); });

此代码禁用了REST API

Mini Cover - 简易的封面设计

前言

访问本站的各位应该都看到了文章的缩略图,而这种缩略图该怎么制作呢

开源地址

Github:https://github.com/JLinMr/Mini-Cover

截图

图片[1]-新锐博客

教程

1.将项目文件下载到安装了nodejs环境的服务器或电脑中

2.修改.env和src/config.js两个文件里的内容

3.运行如下命令

npm install

4.打包程序

npm run build

5.将dist文件夹下的程序主体上传到网站根目录下即可

WordPress添加回复评论邮件通知

前言

之前就想要弄这个功能了,但是主题不支持,今天果核更新了主题终于支持了

教程

将如下代码放到子主题的function.php 中即可

/**
 * 新评论回复邮件通知函数(带按钮,美化界面)
 */
function comment_mail_notify($comment_id) {
    // 获取评论对象
    $comment = get_comment($comment_id);
    if (!$comment || $comment->comment_approved === 'spam') {
        return; // 如果评论不存在或标记为垃圾评论,直接返回
    }

    // 获取父评论 ID
    $parent_id = $comment->comment_parent ? $comment->comment_parent : '';
    if (empty($parent_id)) {
        return; // 如果没有父评论,直接返回
    }

    // 获取父评论对象
    $parent_comment = get_comment($parent_id);
    if (!$parent_comment || empty($parent_comment->comment_author_email)) {
        return; // 如果父评论不存在或邮箱为空,直接返回
    }

    // 获取收件人邮箱
    $to = trim($parent_comment->comment_author_email);

    // 构造邮件内容
    $wp_email = 'no-reply@' . preg_replace('#^www.#', '', strtolower($_SERVER['SERVER_NAME']));
    $subject  = '您在 [' . get_option("blogname") . '] 的留言有了回复';
    $comment_link = get_comment_link($comment_id);
    $message  = '
    <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px; background-color: #f9f9f9;">
        <h2 style="color: #333; font-size: 24px; margin-bottom: 20px;">' . trim($parent_comment->comment_author) . ', 您好!</h2>
        <p style="color: #555; font-size: 16px; line-height: 1.6;">
            您曾在文章《' . get_the_title($comment->comment_post_ID) . '》中留言:
        </p>
        <blockquote style="margin: 20px 0; padding: 10px 20px; background-color: #fff; border-left: 4px solid #0073aa; color: #666; font-style: italic;">
            ' . trim($parent_comment->comment_content) . '
        </blockquote>
        <p style="color: #555; font-size: 16px; line-height: 1.6;">
            ' . trim($comment->comment_author) . ' 给您的回复:
        </p>
        <blockquote style="margin: 20px 0; padding: 10px 20px; background-color: #fff; border-left: 4px solid #0073aa; color: #666; font-style: italic;">
            ' . trim($comment->comment_content) . '
        </blockquote>
        <p style="color: #555; font-size: 16px; line-height: 1.6; text-align: center;">
            点击下方按钮查看完整回复内容:
        </p>
        <div style="text-align: center; margin: 20px 0;">
            <a href="' . $comment_link . '" style="display: inline-block; padding: 12px 24px; font-size: 16px; color: #fff; background-color: #0073aa; border-radius: 4px; text-decoration: none;">
                查看回复
            </a>
        </div>
        <p style="color: #555; font-size: 16px; line-height: 1.6;">
            感谢您对 ' . get_option('blogname') . ' 的支持!
        </p>
        <p style="color: #999; font-size: 14px; margin-top: 20px; text-align: center;">
            此邮件由系统自动发送,请勿直接回复。
        </p>
    </div>';

    // 设置邮件头
    $headers = [
        'From: "' . get_option('blogname') . '" <' . $wp_email . '>',
        'Content-Type: text/html; charset=' . get_option('blog_charset'),
    ];

    // 发送邮件
    wp_mail($to, $subject, $message, $headers);
}

// 挂载钩子
add_action('comment_post', 'comment_mail_notify', 5, 1);
add_action('wp_insert_comment', 'comment_mail_notify', 5, 1);

接口授权IP授权-支持采集接口授权+解析授权+在线任意授权-IP授权高性能高效果 PHP源码

一个授权IP 功能,类型 API 接口以及任意接口授权的代码,让你实现接口安全调用,不被白嫖!

PS:最近写了几个接口,因为是自用得,一天被盗刷好几万次,emmm,所以就搞了这个功能,非常强大!收10元辛苦费,IP授权功能点十分完善了,适合单接口授权类验证,带ip记录,日志记录!默认注释掉的,需要取消注释即可!不懂得可问

51f7bc30342a0b21336be5066b556ec7

JSON解析接口套娃 轮询批量解析

如果有个JSON接口需授权IP或域名使用,那就给它套个娃,然后就可随意调用,也可以自定义返回自己想要的内容,废话不多说,代码如下:

单解析

<?php

header("content-type:application/json;charset=utf8");

$url = $_GET['url'];
if($_GET['url']==''){
    $arr = [
        'code' => 404,
        'msg' => '缺少URL',
        'from' => $_SERVER['HTTP_HOST']
        ];
    die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}

$Api='我是接口放你自己得'; //JSON接口
$jiexi = $Api.$url;
$html = httpget($jiexi);
$json = json_decode($html, true);
$vurl=$json['url'];
if($vurl ==''||$vurl ==null){
    $arr = [
        'code' => 100,
        'msg' => '解析失败',
        'link' => $url,
        'from' => $_SERVER['HTTP_HOST']
        ];
    die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}
$arr = [
    'code' => 200,
    'msg' => '解析成功',
    'url' => $vurl,
    'link' => $url,
    'from' => $_SERVER['HTTP_HOST']
    ];
die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));

function httpget($url, $timeout = 10)
{
    $ch = curl_init();                                                      //初始化 curl
    curl_setopt($ch, CURLOPT_URL, $url);                                    //要访问网页 URL 地址
    curl_setopt($ch, CURLOPT_NOBODY, false);                                //设定是否输出页面内容
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                         //返回字符串,而非直接输出到屏幕上
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, false);                        //连接超时时间,设置为 0,则无限等待
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);                            //数据传输的最大允许时间超时,设为一小时
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);                       //HTTP验证方法
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);                        //不检查 SSL 证书来源
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);                        //不检查 证书中 SSL 加密算法是否存在
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);                         //跟踪爬取重定向页面
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);                            //当Location:重定向时,自动设置header中的Referer:信息
    curl_setopt($ch, CURLOPT_ENCODING, '');                                 //解决网页乱码问题
    curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    
    $httpheaders = array();
    $httpheaders[] = "CLIENT-IP: {$_SERVER['HTTP_CLIENT_IP']}";
    $httpheaders[] = "X-FORWARDED-FOR: {$_SERVER['HTTP_X_FORWARDED_FOR']}";
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheaders);
    
    $data = curl_exec($ch);                                                 //运行 curl,请求网页并返回结果
    curl_close($ch);                                                        //关闭 curl
    return $data;
}

?>

多接口

<?php

//JSON格式化
header("content-type:application/json;charset=utf8");

//当URL为空时返回内容
$url = $_GET['url'];
if($_GET['url'] == '') {
    $arr = [
        'code' => 404,
        'msg' => '缺少URL!',
        'from' => $_SERVER['HTTP_HOST']
        ];
    die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}

$json1 = ''; //接口1

$json2 = ''; //接口2

$json3 = ''; //接口3

$json4 = ''; //接口4

$json5 = ''; //接口5

//接口轮询
$jiexi = $json1.$url;
$html = httpget($jiexi);
$data = json_decode($html, true);
if ($data['url'] == '' || $data['url'] == null) {
    $jiexi = $json2.$url;
    $html = httpget($jiexi);
    $data = json_decode($html, true);
}
if ($data['url'] == '' || $data['url'] == null) {
    $jiexi = $json3.$url;
    $html = httpget($jiexi);
    $data = json_decode($html, true);
}
if ($data['url'] == '' || $data['url'] == null) {
    $jiexi = $json4.$url;
    $html = httpget($jiexi);
    $data = json_decode($html, true);
}
if ($data['url'] == '' || $data['url'] == null) {
    $jiexi = $json5.$url;
    $html = httpget($jiexi);
    $data = json_decode($html, true);
}
if ($data['url'] == '' || $data['url'] == null) {
    $arr = [
        'code' => 100,
        'msg' => '解析失败',
        'link' => $url,
        'from' => $_SERVER['HTTP_HOST']
        ];
    die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}

$arr = [
    'code' => 200,
    'msg' => '解析成功',
    'url' => $data['url'],
    'link' => $url,
    'from' => $_SERVER['HTTP_HOST']
    ];
die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));

function httpget($url, $timeout = 5)
{
    $ch = curl_init();                                                      //初始化 curl
    curl_setopt($ch, CURLOPT_URL, $url);                                    //要访问网页 URL 地址
    curl_setopt($ch, CURLOPT_NOBODY, false);                                //设定是否输出页面内容
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                         //返回字符串,而非直接输出到屏幕上
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, false);                        //连接超时时间,设置为 0,则无限等待
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);                            //数据传输的最大允许时间超时,设为一小时
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);                       //HTTP验证方法
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);                        //不检查 SSL 证书来源
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);                        //不检查 证书中 SSL 加密算法是否存在
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);                         //跟踪爬取重定向页面
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);                            //当Location:重定向时,自动设置header中的Referer:信息
    curl_setopt($ch, CURLOPT_ENCODING, '');                                 //解决网页乱码问题
    curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    
    $httpheaders = array();
    $httpheaders[] = "CLIENT-IP: {$_SERVER['HTTP_CLIENT_IP']}";
    $httpheaders[] = "X-FORWARDED-FOR: {$_SERVER['HTTP_X_FORWARDED_FOR']}";
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheaders);
    
    $data = curl_exec($ch);                                                 //运行 curl,请求网页并返回结果
    curl_close($ch);                                                        //关闭 curl
    return $data;
}

?>

while循环:

<?php

//JSON格式化
header("content-type:application/json;charset=utf8");

//当URL为空时返回内容
$url = $_GET['url'];
if($_GET['url'] == '') {
    $arr = [
        'code' => 404,
        'msg' => '缺少URL!',
        'from' => $_SERVER['HTTP_HOST']
        ];
    die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}

$json = array(
    '',
    '',
    '',
    '',
    '',
    ); //接口

//接口轮询
$num = 0;
$jiexi = $json[$num].$url;
$html = httpget($jiexi);
$data = json_decode($html, true);

while ($data['url'] == '' || $data['url'] == null) {
    $jiexi = $json[$num+1].$url;
    $html = httpget($jiexi);
    $data = json_decode($html, true);
    $num = $num + 1;
    if ($num >= count($json)) {
        break;
    }
}

if ($data['url'] == '' || $data['url'] == null) {
    $arr = [
        'code' => 100,
        'msg' => '解析失败',
        'link' => $url,
        'from' => $_SERVER['HTTP_HOST']
        ];
    die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}
else {
    $arr = [
        'code' => 200,
        'msg' => '解析成功',
        'url' => $data['url'],
        'link' => $url,
        'from' => $_SERVER['HTTP_HOST']
        ];
    die(json_encode($arr, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}

function httpget($url, $timeout = 3)
{
    $ch = curl_init();                                                      //初始化 curl
    curl_setopt($ch, CURLOPT_URL, $url);                                    //要访问网页 URL 地址
    curl_setopt($ch, CURLOPT_NOBODY, false);                                //设定是否输出页面内容
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                         //返回字符串,而非直接输出到屏幕上
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, false);                        //连接超时时间,设置为 0,则无限等待
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);                            //数据传输的最大允许时间超时,设为一小时
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);                       //HTTP验证方法
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);                        //不检查 SSL 证书来源
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);                        //不检查 证书中 SSL 加密算法是否存在
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);                         //跟踪爬取重定向页面
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);                            //当Location:重定向时,自动设置header中的Referer:信息
    curl_setopt($ch, CURLOPT_ENCODING, '');                                 //解决网页乱码问题
    curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    
    $httpheaders = array();
    $httpheaders[] = "CLIENT-IP: {$_SERVER['HTTP_CLIENT_IP']}";
    $httpheaders[] = "X-FORWARDED-FOR: {$_SERVER['HTTP_X_FORWARDED_FOR']}";
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheaders);
    
    $data = curl_exec($ch);                                                 //运行 curl,请求网页并返回结果
    curl_close($ch);                                                        //关闭 curl
    return $data;
}

?>

 

苹果CMS 解决萌芽采集插件提示“发现冲突文件”

前言

重复安装启用插件,或萌芽更新失败的时,开关插件会提示“发现冲突文件”导致无法正常开关和卸载插件这时即便删除解压后的文件重新安装插件依然无法解决,想要完全解决这种情况需要手动删除萌芽生成的php文件,教程如下。、

4133c4ea718bef61f3a2cd84c9107169

解决方法

打开你苹果CMS目录后删除一下目录

/addons/mycj/
/static/mycj/
/application/admin/view/mycj/

以及萌芽生成的以下文件

/application/extra/cjuser.php
/application/extra/cjfaves.php 
/application/extra/cjversion.php
/application/admin/controller/Mycj.php

这时重新解压安装插件启用即可。

PixPro-支持三种存储的图床程序

前言

今天给大家带来一个小巧简洁的图床程序

开源地址

github:https://github.com/JLinMr/PixPro/

简介

一款专为个人需求设计的高效图床解决方案,集成了强大的图片压缩功能与优雅的前台后台管理界面。

项目结构精简高效,提供自定义图片压缩率与尺寸设置,有效降低存储与带宽成本。

支持上传JPEG、PNG、GIF格式图片并转换为WEBP格式,支持上传SVG、WEBP图片。

支持本地储存,阿里云OSS储存,S3存储。可通过把储存桶挂载到本地的方式解锁更多储存方式。

简洁美观的前端,支持点击、拖拽、粘贴、URL、批量上传。

瀑布流管理后台,便捷查看图片信息,支持图片灯箱、AJAX无加载刷新。

支持自定义压缩率,默认60。支持设置每日上传限制,单次上传限制,文件大小限制

演示站点

 

前端:https://dev.ruom.top/

后台:https://dev.ruom.top/admin/

安装教程

 

首先下载源码ZIP,将文件上传到网站根目录,访问网址 ,填写相关信息,即可完成安装。

运行环境

 

推荐PHP 8.1 + MySQL >= 5.7

本程序依赖PHP的 Fileinfo 、 Imagick 、 exif拓展,需要自行安装。依赖 pcntl 扩展(宝塔PHP默认已安装)

要求 pcntl_signal 和 pcntl_alarm 函数可用(需主动解除禁用)

WordPress底部添加页面生成时间和数据库查询次数

前言

今天有个群友要在网站底部添加页面生成时间和数据库查询次数,虽然wpopt插件可以实现这个功能,但是仅能管理员查看

效果图

图片[1]-新锐博客

教程

1.首先在function.php 文件中添加如下代码,有子主题可以添加到子主题中

function display_query_count_with_timer() {
    $query_count = get_num_queries();
    $query_time = timer_stop(0, 3);
    $output = "<p>本次数据库查询" . $query_count . "次,页面生成花费".$query_time."秒</p>";
    return $output;
}
add_shortcode('query_timer', 'display_query_count_with_timer');

2.如果想添加在底部可以使用WordPress的小工具中的文本,只需要输入[query_timer] 即可。

给自己网站添加多语言功能

前言

群里有朋友需要网站适配多语言,但其实一个引用就可以搞定这个问题

开源地址

gitee:https://gitee.com/mail_osc/translate

教程

在需要的地方添加如下代码

<!-- 增加语言选择的下拉框 -->
<select id="language-select" onchange="changeLanguage()">
    <option value="english">English</option>
    <option value="chinese_simplified">简体中文</option>
    <option value="chinese_traditional">繁體中文</option>
</select>

<!-- 引入多语言切换的js -->
<script src="https://cdn.staticfile.net/translate.js/3.2.1/translate.js"></script>
<script>
    translate.selectLanguageTag.show = false; // 不出现的select的选择语言
    translate.service.use('client.edge'); // 设置机器翻译服务通道

    function changeLanguage() {
        const selectedLanguage = document.getElementById('language-select').value;
        translate.changeLanguage(selectedLanguage);
        translate.execute();
        localStorage.setItem('selectedLanguage', selectedLanguage); // 保存选择的语言
    }

    // 页面加载时设置选择框的值和语言
    document.addEventListener('DOMContentLoaded', function() {
        const savedLanguage = localStorage.getItem('selectedLanguage') || 'english'; // 默认选择英文
        document.getElementById('language-select').value = savedLanguage; // 设置选择框的值
        translate.changeLanguage(savedLanguage); // 设置翻译语言
        translate.execute(); // 执行翻译
    });
</script>

结语

两行代码就解决了网站需要多语言的问题

利用uptimerobot检测站点状态并且部署监控页面

前言

之前介绍过如何使用哪吒监控监控自己的服务器和站点,但那是需要服务器的。

今天教大家如何不用服务器监控自己的站点。

教程

1.首先打开uptimerobot官网,点击右上角的Register fo FREE注册一个账号

2.找到页面中的Add New monitor添加自己的网站

3.输入网站,可以选择邮件通知或其他通知方式,当你网站访问不了的时候它就会通知你

4.添加完网站就去首页的Integrations & API中找到API

5.新建一个Read-only API key,这样别人就不能通过你的API捣乱了

6.访问https://github.com/Qikaile/uptime-status项目

7.Fork到自己的仓库然后更改config.js文件里的内容

8.打开Vercel,然后添加刚刚fork的项目等待部署完成

9.到项目的setting中找到domain,然后填写自己准备好的域名即可

记一次可能因宝塔版本导致重装系统的遭遇

前言

因为习惯了宝塔的操作习惯,所以一直以来建站使用的都是宝塔。

碎语

之前安装的是宝塔的9.2.0的版本,然后日常使用中也并没有发现什么问题。

但是有天早上有人告诉我,我网站打不开了,于是我就开电脑查看,发现CPU占用一直是百分之百。

当然,这种查看是在阿里云的云监控中进行的,因为那时候宝塔连接不上去,连SSH也无法连接服务器。

幸亏我有瞎倒腾的习惯,所以在阿里云的云监控中开启了主机监控。

我还发现了不仅CPU占用达到了百分之百,硬盘的占用也是高达100M/s。

这么高的读写让我意识到了事情的不对劲,于是我先重启服务器然后连接宝塔之后在监控中查看了日志。

在cpu和硬盘达到百分百的时候,一个名为php-fpm的程序占用非常之大,但因为我是小白,所以不太懂这个是干嘛的。

但是重启服务器后就没事了,所以也就没管。但是几天后又出现了相同的情况,于是我就百度查了一下。

并且在宝塔的论坛中找了一下,发现相关的问题宝塔的工作人员要么没回复,要么就说网站可能被CC之类的了。

我就怀疑是不是我设置了啥导致的这个问题,于是我就重装了系统。但是过了一天这个问题又出现了。

最后我就怀疑是宝塔版本的bug,因为宝塔没有指定版本安装的脚本,于是我就找到了宝塔的9.0.0长期稳定版本安装了一下。

到如今已经过去四天了,问题没有出现。所以我觉得可能是宝塔9.2.0的bug。

现在就继续使用9.0.0版本然后等宝塔更新后看看更新日志会不会有相关的bug修复。

无需服务器利用vercel搭建typecho博客

前言

众所周知,vercel可以搭建静态内容,但是不知道的是也可以搭建typecho博客吧。

教程

准备工作

Github账号,Vercel账号,域名

开始

1.首先访问https://github.com/zycwer/vercel-typecho/并且fork到自己的仓库(最好是下载然后上传到自己仓库)

2.为了防止数据库的泄露,最好将仓库变成私有

3.上传主题文件到usr/theme文件夹下,上传插件到usr/plugins文件夹下

4.使用github登录vercel,点击页面右上角的ADD NEW中的Project

5.找到刚刚fork的项目或者上传的项目点击import并且点击deploy等待部署完成

6.找到项目中的storage,再点击Connect Database,选择其中的Postgres,剩下的直接点右下角的确定就行了,

7.找到项目中的settings,再点击Domains,输入框中输入自己的域名再点击ADD

8.到域名服务商处添加cname解析,记录为cname.vercel-dns.com

9.访问域名,会跳转到typecho安装,数据库选择Po驱动postgres数据库

10.数据库的地址是刚刚创建的postgres数据库中的@后面以及:5432前面的内容

11.数据库用户名是default,数据库密码是default:后面到@前面的内容,数据库名是verceldb

12.它会提示你到在github仓库中创建一个名为config.inc.php的文件,然后将代码填写到其中。

13.等待vercel重新部署完成,期间不要动任何东西,然后点击我已创建,开始安装。

14.之后就是填写管理员账号和密码就可以了。至此typecho就创建成功了。

问题

本项目的最大问题就是有些主题和插件会更改文件内容,不仅仅是更改数据库的内容,比如handsome主题插件,所以很多主题是用不了的,这就要我们一个个试。

 

WordPress利用function屏蔽搜索并且跳转到指定页面

前言

我们平时弄网站的时候会出现各种搜索词,其中包括不少敏感词,这时候就可以使用function屏蔽某些敏感词

教程

将如下代码添加到子主题的function.php中

function block_sensitive_search_terms($query) {
    if ($query->is_search && !is_admin()) {
        $file_path = ABSPATH . '/api/minganci/blocked_terms.txt';
        if (file_exists($file_path)) {
            $blocked_terms = file($file_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        } else {
            $blocked_terms = array();
        }
        // 获取搜索查询词
        $search_query = $query->query_vars['s'];

        // 检查搜索查询是否包含任何敏感词
        foreach ($blocked_terms as $blocked_term) {
            if (stripos($search_query, trim($blocked_term)) !== false) {
                // 跳转到404页面
                header("Location: /404");
                exit; // 确保脚本停止执行
            }
        }
    }
}
add_action('pre_get_posts', 'block_sensitive_search_terms');

其中ABSPATH . '/api/minganci/blocked_terms.txt' 是我列举的所有敏感词,你可以替换成自己的。

具体的敏感词可以访问https://www.xrbk.cn/api/minganci/blocked_terms.txt 来获取。

 

使用function和php实现外链跳转

前言

之前外链跳转使用的是果核的插件,现在不想用插件了,于是自己弄了个代码

教程

首先在子主题的function.php中添加如下代码

//外链跳转
function convert_external_links_to_base64($content) {
    // 使用正则表达式找到所有外部链接
    $pattern = '/<as+href=["'](http[s]?://[^"']+)["']/i';
    $content = preg_replace_callback($pattern, function($matches) {
        $url = $matches[1];
        // 对 URL 进行 Base64 编码
        $base64_url = base64_encode($url);
        // 返回新的链接,指向中间页
        return str_replace($url, site_url('/redirect.php?url=' . $base64_url), $matches[0]);
    }, $content);
    
    return $content;
}

// 将函数应用于文章和页面内容
add_filter('the_content', 'convert_external_links_to_base64');

再在网站根目录新建一个php文件命名为redirect.php ,并且添加如下代码

<?php
if (isset($_GET['url'])) {
    $link = base64_decode($_GET['url']);
}
?>
<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" type="text/css" href="static/css/style.css">
    <link rel="icon" href="https://www.xrbk.cn/favicon.png" type="image/x-icon"/><!--favicon图片地址-->
    <title>新锐博客 - 安全中心</title><!--修改文字-->
</head>

<body>
  <div class="go-wild-box">
    <div class="go-wild-container">
     <a href="https://www.xrbk.cn/">
     <img alt="新锐博客" src="/wp-content/uploads/f4a9f982d722de858fd133baf4ff14b7.webp" class="logo-img" /><!--修改Logo地址-->
      </a>
     <div class="tips-title">您即将离开新锐博客,跳转到第三方链接</div><!--修改文字-->
        <div class="address"><?php echo htmlspecialchars($link); ?></div>
      <div class="tips-subtitle">请注意您的账号和财产安全</div>
      <div class="btn-groups">
        <button onclick="try { window.close(); } catch(e) { alert('请手动关闭此页面'); }" type="button" class="ant-btn ant-btn-default">取消访问</button>
        <a href="<?php echo htmlspecialchars($link); ?>" rel="nofollow">
          <button type="button" class="ant-btn ant-btn-primary">继续访问</button>
        </a>
      </div>
    </div>
  </div>
</body>
</html>
<style>
body { 
    margin: 0; font-family: 'PingFangSC', sans-serif; background-color: #EFF4FA; }
.go-wild-box { display: flex; justify-content: center; align-items: center; height: 100vh; }
.go-wild-container { width: 770px; height: 330px; max-width: 90%; padding: 90px 15px; background-color: #fff; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); text-align: center; }
.logo-img { width: 120px; height: auto; }
.tips-title { margin: 20px 0; font-size: 22px; color: #2a3c59; font-weight: 500; }
.address { margin-bottom: 20px; padding: 15px; background-color: #EFF4FA; border-radius: 8px; color: #2a3c59; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 80%; max-width: 600px; margin: 0 auto; }
.tips-subtitle { font-size: 14px; color: #2a3c59; margin-bottom: 30px;margin-top: 20px; }
.btn-groups { display: flex; justify-content: center; gap: 10px; margin-top: 60px; }
.ant-btn { width: 152px; height: 44px; line-height: 44px; border-radius: 20px; border: none; cursor: pointer; font-size: 14px; transition: all 0.3s ease; }
.ant-btn-primary { background: linear-gradient(152deg, #07C160 0%, #07c183 100%); color: #fff; }
.ant-btn-default { background-color: #fff; color: #2a3c59; border: 1px solid #ccc; }
.ant-btn-default:hover { background-color: #fff; border-color: #07C160; color: #07C160; }
</style>

结语

这样访问文章和页面中的外部链接就可以跳转到中间页了

记一次数据库查询操作

前言

前两天有群友找到我想让我给他把一个美化插件改一下,插件本来只显示注册用户,浏览量,运行天数等信息。

他想给插件添加一个vip用户数量的信息,所以让我看看能不能搞。

过程

首先我想到的是用数据库来查询,但是需要一个关键词。

我在WordPress后台查看的时候发现虽然会员被区分为黄金会员和钻石会员,但是它们共同的点是都是永久的。

于是我打算从永久这一点来入手,而子比赋予永久会员的值为Permanent ,我就去数据库查找这个词。

wp_usermeta这个数据表中有一个vip_exp_date 的参数的值就是Permanent 。

我就用AI帮我写了一个php代码,查询到Permanent 的数量一共为73个,而WordPress后台显示的黄金会员和钻石会员的总数为70个。

经过查询发现有三个普通会员也被赋予了永久会员这一身份,所以得出结论,无论是普通会员还是黄金会员亦或者钻石会员都可以被赋予永久会员这一身份。

看来只能找其他的值来区别这一点了,最后让我发现vip_level 这一参数的值要么没有要么就是1或2,于是我就认为1代表黄金会员2则代表钻石会员。

想做就做,我就用AI帮我写了一段PHP代码,贴在下面了。

<?php
global $wpdb;
// 查询用户数量
$vipusers = $wpdb->get_var(
    $wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->usermeta} WHERE meta_key = %s AND meta_value IN (%d, %d)",
        'vip_level', 1, 2
    )
);

可以看到是在wp_usermeta这个表中查询了关于vip_level为1或2的数量,最后显示的结果是70。

结语

搭建网站的时候不可避免的需要用到数据库,所以我们得学习好怎么操作数据库才行。

IP签名档优化修改版

前言

之前发过一次ip签名档的文章,但是其作者不知道是谁,这次的IP签名档,是由我的友链广然笔记修改并且修复的。

更新

  • 新增IPv6地址识别
  • 新增随机显示背景图
  • 修复网站添加CDN获取不到IP地址问题
  • 修改一些样式的显示方式
  • 修复较长地址显示和系统信息显示重叠的问题
  • 新增两张背景图片
  • 修复一些其他显示问题

教程

1.下载并且解压到网站目录下

2.注册高德开发平台腾讯位置服务Web服务应用,获得两个 Key。

3.修改index.php中的代码。

下载地址

IP签名档-修复版

WordPress侧边栏添加信息统计

前言

刚刚写了一篇统计文章字数的文章,现在就教大家如何在侧边栏添加信息统计

教程

在子主题的function.php中添加如下代码

function display_site_stats() {
    // 获取统计数据
    $total_posts = wp_count_posts()->publish;
    $site_uptime = get_site_uptime();
    $last_update = get_last_update_time();
    $total_word_count = get_total_word_count();

    // 输出HTML
    $stats = [
        '文章数目' => ['value' => $total_posts, 'class' => 'purple'],
        '存活天数' => ['value' => $site_uptime, 'class' => 'violet'],
        '上次更新' => ['value' => $last_update, 'class' => 'red'],
        '文章字数' => ['value' => $total_word_count . ' 万', 'class' => 'red']
    ];

    $output = '<div style="background: #fff; padding: 10px; border-radius: 5px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);">';
    foreach ($stats as $text => $data) {
        $output .= sprintf(
            '<div style="display: flex; align-items: center; margin-bottom: 10px;">
                <span style="flex: 1;">%s</span>
                <span style="background: %s; color: #fff; padding: 2px 8px; border-radius: 12px; font-size: 0.9em;">%s</span>
            </div>',
            esc_html($text),
            esc_attr(get_badge_color($data['class'])),
            esc_html($data['value'])
        );
    }
    $output .= '</div>';

    return $output; // 返回输出的HTML
}

function get_badge_color($class) {
    switch ($class) {
        case 'purple':
            return '#9c27b0';
        case 'violet':
            return '#7e57c2';
        case 'red':
            return '#e53935';
        default:
            return '#e0e0e0';
    }
}

function get_site_uptime() {
    $start_date = new DateTime('2023-04-05'); // 替换为你的网站创建日期
    $interval = $start_date->diff(new DateTime());
    return $interval->days . '天'; // 直接返回存活的天数
}

function get_last_update_time() {
    $last_post = wp_get_recent_posts(['numberposts' => 1])[0];
    $time_difference = time() - strtotime($last_post['post_date']);

    if ($time_difference < 60) return '刚刚';
    if ($time_difference < 3600) return floor($time_difference / 60) . '分钟前';
    if ($time_difference < 86400) return floor($time_difference / 3600) . '小时前';
    return floor($time_difference / 86400) . '天前';
}

function get_total_word_count() {
    $posts = get_posts(['numberposts' => -1]);
    $total_word_count = array_sum(array_map(function($post) {
        return str_word_count(strip_tags($post->post_content));
    }, $posts));
    return round($total_word_count / 10000, 2); // 返回万字数
}

// 注册短代码
add_shortcode('xrbk-cbls', 'display_site_stats');

然后在WordPress小工具中添加文本,里面输入[xrbk-cbls]

截图

图片[1]-新锐博客

WordPress添加所有文章内容字数统计

前言

突发奇想,想要知道自己更新了多少字数的内容,于是就有了下面的教程。

教程

如果有子主题,请将如下代码添加到子主题的function.php中

//获取所有文章字数
function count_all_posts_word_count() {
    // 获取所有文章
    $args = array(
        'post_type'      => 'post',
        'posts_per_page' => -1, // 获取所有文章
    );

    $query = new WP_Query($args);
    $total_word_count = 0;

    // 循环遍历每篇文章
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            // 获取文章内容
            $content = get_the_content();
            // 计算字数
            $word_count = str_word_count(strip_tags($content));
            $total_word_count += $word_count;
        }
        // 重置查询
        wp_reset_postdata();
    }

    return $total_word_count;
}

// 将字数转换为以千为单位的格式
function format_word_count($count) {
    if ($count >= 1000) {
        return round($count / 1000, 1) . 'k'; // 保留一位小数
    }
    return $count; // 小于1000的直接返回
}

// 使用短代码显示字数
function display_total_word_count() {
    $total_words = count_all_posts_word_count();
    $formatted_words = format_word_count($total_words);
    return "所有文章的总字数: " . $formatted_words;
}
add_shortcode('total_word_counts', 'display_total_word_count');
?>

然后去想要显示的地方添加[total_word_counts]

结语

如果想要添加到侧边栏的话可以使用文本小工具。

利用飞书每天定时推送网站当天以及本月访问量

前言

飞书真是个好东西,可以利用它给我们推送各种各样的消息。

今天教大家如何推送网站当天以及本月的访问量。

教程

1.首先网站统计需要用umami搭建,不懂的自己网站搜索umami,有教程

2.网站目录下新建一个php文件,并将如下代码添加到其中

<?php
// 设置飞书 Webhook URL
$feishuWebhookUrl = '飞书地址'; // 替换为你的飞书 Webhook URL

// 获取访问数据的函数
function getVisitData($umiToken, $umiId) {
    $umiTime = time() * 1000; // 当前时间(毫秒)
    $todayStart = strtotime('today') * 1000; // 今日开始时间(毫秒)
    $monthStart = strtotime('first day of this month') * 1000; // 本月开始时间(毫秒)

    // 获取今日访问量和访问人数
    $todayUrl = "https://你的域名/api/websites/{$umiId}/stats?startAt={$todayStart}&endAt={$umiTime}";
    $todayData = file_get_contents($todayUrl, false, stream_context_create([
        'http' => [
            'header' => "Authorization: Bearer {$umiToken}rn" .
                        "Content-Type: application/jsonrn"
        ]
    ]));
    $todayData = json_decode($todayData, true);

    // 获取本月访问量
    $monthUrl = "https://你的域名/api/websites/{$umiId}/stats?startAt={$monthStart}&endAt={$umiTime}";
    $monthData = file_get_contents($monthUrl, false, stream_context_create([
        'http' => [
            'header' => "Authorization: Bearer {$umiToken}rn" .
                        "Content-Type: application/jsonrn"
        ]
    ]));
    $monthData = json_decode($monthData, true);

    // 返回数据
    return [
        'todayUv' => $todayData['visitors']['value'] ?? 0,
        'todayPv' => $todayData['pageviews']['value'] ?? 0,
        'monthPv' => $monthData['pageviews']['value'] ?? 0
    ];
}

// 设置 UMI Token 和 ID
$umiToken = "你的token"; // 获取到的 token
$umiId = "你的websiteid"; // 获取到的 websiteId

// 获取访问数据
$visitData = getVisitData($umiToken, $umiId);

// 获取当前时间
$currentDateTime = date('Y年m月d日 H:i:s');

// 构建消息内容
$messageContent = sprintf(
    "现在是 %s,今天的访问人数为 %d,今天的访问量为 %d,本月的访问量为 %d。",
    $currentDateTime,
    $visitData['todayUv'],
    $visitData['todayPv'],
    $visitData['monthPv']
);

// 构建请求参数
$requestData = [
    "msg_type" => "text",
    "content" => [
        "text" => $messageContent
    ]
];

// 将请求参数转换为 JSON 格式
$jsonData = json_encode($requestData);

// 初始化 cURL
$ch = curl_init($feishuWebhookUrl);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonData)
]);

// 执行请求
$response = curl_exec($ch);
curl_close($ch);

// 输出响应
echo $response;
?>

3.访问飞书官网

4.新建一个机器人,添加流程

5.选择触发器为webhook触发

6.参数填写:{"msg_type":"text","content":{"text":"request example"}}

7.选择操作为发送飞书消息

8.消息内容点击加号,然后选择webhook触发里的content.text

9.宝塔面板计划执行添加定时访问url。

截图

图片[1]-新锐博客

利用飞书和php代码推送最新地震

前言

最近安徽合肥几十次小地震,搞得人心惶惶,在地震带的朋友可能都无法第一时间获得消息,于是写了个php来推送消息

教程

此次教程分为两个接口如下

因无法测试,所以不知道是不是实时的,所以不要依赖于此,使用手机自带的地震预警

中国地震网:https://www.ceic.ac.cn/ajax/speedsearch?num=1

不知名地震API:https://api.wolfx.jp/cenc_eqlist.json

在网站目录下新建一个php文件,并且添加如下代码

其中https://www.feishu.cn/flow/api/trigger-webhook/xxxx 改为自己的飞书webhook

<?php

// 提取数据并发送飞书消息的函数
function extractDataAndSendFeishuMessage($jsonUrl, $feishuWebhookUrl) {
    // 初始化cURL会话
    $ch = curl_init($jsonUrl);

    // 设置cURL选项
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 忽略SSL证书验证
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); // 设置连接超时时间
    curl_setopt($ch, CURLOPT_TIMEOUT, 2); // 设置执行超时时间
    // 执行cURL请求
    $jsonData = curl_exec($ch);

    // 关闭cURL会话
    curl_close($ch);

    // 解析JSON数据
    $substr_start = "(";
    $substr_end = ")";
    $start_pos = strpos($jsonData, $substr_start);
    $end_pos = strpos($jsonData, $substr_end);

    if ($start_pos !== false && $end_pos !== false) {
        $start_pos = $start_pos + mb_strlen($substr_start);
        $end_pos = $end_pos;
        $middle_text = mb_substr($jsonData, $start_pos, $end_pos - $start_pos);
        $jsonData1 = $middle_text;
    } else {
        return "无法获取内容"; // 如果没有获取到内容,直接返回
    }
    
    $data = json_decode($jsonData1, true);
    
    // 获取No1
    if (isset($data['shuju'][0])) {
        $no1 = $data['shuju'][0];
        
        // 提取各项数据
        $eventTime = $no1['O_TIME'];
        $location = $no1['LOCATION_C'];
        $magnitude = $no1['M_MS'];
        
        // 将 $eventTime 转换为时间戳
        $eventTimestamp = strtotime($eventTime);
        // 获取当前时间戳
        $currentTimestamp = time();
        
        // 判断事件时间与当前时间的差异(是否在一天内)
        if (($currentTimestamp - $eventTimestamp) <= 86400 && ($currentTimestamp - $eventTimestamp) >= 0) { // 86400秒 = 1天
            // 发送信息到飞书
            $data = json_encode(array(
                'msg_type' => 'text',
                'content' => array(
                    'text' => "$eventTime 在 $location 发生了 $magnitude 震级地震 。"
                )
            ));

            $ch = curl_init($feishuWebhookUrl);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); // 设置连接超时时间为1秒
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 1); // 设置执行超时时间为1秒
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json'
            ));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            
            $result = curl_exec($ch);
            
            // 关闭cURL会话
            curl_close($ch);

            echo $result;
        } else {
            echo "短期内无事发生";
        }
    } else {
        echo "jsonData:".$jsonData;
    }
}

// JSON数据URL和飞书Webhook地址
$jsonUrl = 'https://www.ceic.ac.cn/ajax/speedsearch?num=1';
$feishuWebhookUrl = 'https://www.feishu.cn/flow/api/trigger-webhook/xxxx';

// 调用函数提取数据并发送飞书消息
extractDataAndSendFeishuMessage($jsonUrl, $feishuWebhookUrl);

?>

这个接口是中国地震网的,实测访问过多会被拉黑(测试时我是按秒执行的),但是第二个接口是托管于cloudflare的,我的服务器不能很好的访问。

如果你的服务器可以访问第二个接口就使用第二个接口,它的限制是每秒不能超过两次访问,足够使用了。

<?php

// 提取数据并发送飞书消息的函数
function extractDataAndSendFeishuMessage($jsonUrl, $feishuWebhookUrl) {
    // 初始化cURL会话
    $ch = curl_init($jsonUrl);

    // 设置cURL选项
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 忽略SSL证书验证
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); // 设置连接超时时间
    curl_setopt($ch, CURLOPT_TIMEOUT, 2); // 设置执行超时时间
    // 执行cURL请求
    $jsonData = curl_exec($ch);

    // 关闭cURL会话
    curl_close($ch);

    $data = json_decode($jsonData, true);
    
    // 获取No1
    if (isset($data['No1'])) {
        $no1 = $data['No1'];
        
        // 提取各项数据
        $eventTime = $no1['time'];
        $location = $no1['location'];
        $magnitude = $no1['magnitude'];
        
        // 将 $eventTime 转换为时间戳
        $eventTimestamp = strtotime($eventTime);
        // 获取当前时间戳
        $currentTimestamp = time();
        
        // 判断事件时间与当前时间的差异(是否在一天内)
        if (($currentTimestamp - $eventTimestamp) <= 86400 && ($currentTimestamp - $eventTimestamp) >= 0) { // 86400秒 = 1天
            // 发送信息到飞书
            $data = json_encode(array(
                'msg_type' => 'text',
                'content' => array(
                    'text' => "$eventTime 在 $location 发生了 $magnitude 震级地震 。"
                )
            ));

            $ch = curl_init($feishuWebhookUrl);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); // 设置连接超时时间为1秒
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 1); // 设置执行超时时间为1秒
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json'
            ));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            
            $result = curl_exec($ch);
            
            // 关闭cURL会话
            curl_close($ch);

            echo $result;
        } else {
            echo "短期内无事发生";
        }
    } else {
        echo "jsonData:".$jsonData;
    }
}

// JSON数据URL和飞书Webhook地址
$jsonUrl = 'https://api.wolfx.jp/cenc_eqlist.json';
$feishuWebhookUrl = 'https://www.feishu.cn/flow/api/trigger-webhook/xxxx';

// 调用函数提取数据并发送飞书消息
extractDataAndSendFeishuMessage($jsonUrl, $feishuWebhookUrl);
?>

飞书教程

1.访问飞书官网

2.找到创建的机器人

3.点击左边的流程设计

4.创建流程

5.选择触发器为触发webhook

6.参数填写{"msg_type":"text","content":{"text":"request example"}}
 并点击完成

7.选择操作为发送飞书消息

8.发送对象看你情况选择,我选择的是群

9.消息标题为地震预警

10.消息内容点击加号然后找到webhook触发选择content.text

11.点击完成就算部署完成了。

结语

天灾无法预料,希望各位保护好自己和家人,平安度过。

 

ThinkPHP项目提示未定义变量的解决方法

前言

在我们部署ThinkPHP项目的时候会遇到提示未定义变量:xxxxx。

教程

1.使用宝塔的搜索功能搜索这个变量,这次提示的事cdnpublic,搜索这个变量名称就行

图片[1]-新锐博客

2.找到以后根据它的内容更改一下地址就行。(一定要根据它的内容更改,而不是瞎改)

图片[2]-新锐博客

3.重新运行安装程序即可。

结语

此方法对于新手来说不是很友好,但是也未尝不是一种方法。

零艺客 - 开源的API接口管理平台

前言

零艺客API管理平台是由zeroart开发的一款API接口管理平台。

截图

图片[1]-新锐博客

教程

1.数据库信息配置在路径【config/database.php】文件中
2.导入根目录下的【data.sql】数据库文件
3.设置网站运行目录为根目录【public】目录

后台地址 /admin/login.html
账户 admin 密码 123456

伪静态在public目录下,nginx和apache分别对应文件 nginx.htaccess和.htaccess

下载地址

零艺客API管理平台源码

使用Docker搭建Umami统计,显示近一年的pv、uv数据的API搭建

因为百度统计使用unload导致浏览器报错和一系列性能问题,并且去广告插件之类的对百度统计都有屏蔽,导致无法获取真实的数据,所以决定之下还是选择了自搭建umami。这也是向访客隐私迈出的一大步,也就是说在未来我的博客将不会将访客数据传输给第三方,避免了潜在的隐私风险。

WordPress文章页侧边栏添加文章目录

前言

不少主题都支持文章页的侧边栏添加文章目录的小工具

教程

将如下代码放到子主题的function.php中

class Article_TOC_Widget extends WP_Widget {

    public function __construct() {
        parent::__construct(
            'article_toc_widget',
            '文章目录小工具',
            array( 'description' => '在文章或页面的侧边栏中显示文章目录' )
        );
    }

    public function widget( $args, $instance ) {
        global $post;
        if ( is_singular() && ! empty( $post->post_content ) ) {
            $toc = $this->get_toc( $post->post_content );
            if ( ! empty( $toc ) ) {
                echo $args['before_widget'];
                echo $args['before_title'] . '文章目录' . $args['after_title'];
                echo '<ul>' . $toc . '</ul>';
                echo $args['after_widget'];
            }
        }
    }

    public function get_toc( $content ) {
        $toc = '';
        $dom = new DOMDocument();
        @$dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );
        $xpath = new DOMXPath( $dom );
        $headers = $xpath->query( '//h2|//h3|//h4|//h5|//h6' );
        if ( $headers->length > 0 ) {
            foreach ( $headers as $header ) {
                $id = $header->getAttribute( 'id' );
                if ( empty( $id ) ) {
                    $id = sanitize_title( $header->nodeValue );
                    $header->setAttribute( 'id', $id );
                }
                $toc .= '<li><a href="#' . $id . '">' . $header->nodeValue . '</a></li>';
            }
        }
        return $toc;
    }

}
function register_article_toc_widget() {
    register_widget( 'Article_TOC_Widget' );
}
add_action( 'widgets_init', 'register_article_toc_widget' );

结语

功能不是很完善,但是可以显示了,需要其他功能自己添加

WordPress添加彩色文本渐变框

前言

CoreNext主题自带的编辑器增强内有标星面板,但是颜色有点少,所以找了个教程给WordPress添加彩色文本渐变框。

教程

1.首先将如下代码添加到CoreNext子主题的function.php 中,如果其他主题也有子主题一样操作。

 add_action('after_wp_tiny_mce', 'bolo_after_wp_tiny_mce');
 function bolo_after_wp_tiny_mce($mce_settings) {
 ?>
 <script type="text/javascript"> 
 QTags.addButton( 'z_mhz', '迷幻紫', '<div id="zm_mhz">迷幻紫</div>n', "" );
 QTags.addButton( 'z_xgh', '西瓜红', '<div id="zm_xgh">西瓜红</div>n', "" );
 QTags.addButton( 'z_tkzj', '天空之境', '<div id="zm_tkzj">天空之境</div>n', "" );
 QTags.addButton( 'z_xyz', '小宇宙', '<div id="zm_xyz">小宇宙</div>n', "" );
 QTags.addButton( 'z_gll', '橄榄绿', '<div id="zm_gll">橄榄绿</div>n', "" );
 QTags.addButton( 'z_xty', '小太阳', '<div id="zm_xty">小太阳</div>n', "" );
 QTags.addButton( 'z_yyz', '优雅紫', '<div id="zm_yyz">优雅紫</div>n', "" );
 QTags.addButton( 'z_szh', '深邃黑', '<div id="zm_szh">深邃黑</div>n', "" );
 QTags.addButton( 'z_wbk', '无边框', '<div id="zm_wbk">无边框</div>n', "" ); 
 function bolo_QTnextpage_arg1() {
 }
 </script>
 <?php
 }

2.将如下CSS代码添加到CoreNext子主题的CSS文件夹中的main.css中

/*渐变框区块*/
#zm_mhz,#zm_xgh,#zm_tkzj,#zm_xyz,#zm_gll ,#zm_xty,#zm_yyz,#zm_szh,#zm_wbk{
  /*圆角值,在此定义*/
  border-radius: 8px;
}
/*迷幻紫*/
#zm_mhz{
    color: #555555;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
    /*border-radius: 10px;*/
    box-shadow: 6px 0 12px -5px rgb(190, 196, 252), -6px 0 12px -5px rgb(189, 196, 252);
    background-color: #8EC5FC;
    background-image: linear-gradient(62deg,#8EC5FC 0%,#E0C3FC 100%);
    background-image: -webkit-linear-gradient(62deg,#8EC5FC 0%,#E0C3FC 100%);
}
/*西瓜红*/
#zm_xgh{
      color: #555555;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
    /*border-radius: 10px;*/
    box-shadow: 6px 0 12px -5px rgb(255, 176, 172), -6px 0 12px -5px rgb(255, 161, 174);
    background-color: #ff9a8b66;
    background-image: linear-gradient(220deg,#FF9A8B 0%,#ff6a8838 55%,#FF99AC 100%);
    background-image: -webkit-linear-gradient(220deg,#ff9a8b7a 0%,#ff6a88ab 55%,#ff99ac82 100%);
}
/*华为P30 天空之境*/
#zm_tkzj {
    color: #555555;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
    /*border-radius: 10px;*/
    box-shadow: 6px 0 12px -5px rgb(253, 223, 234), -6px 0 12px -5px rgb(215, 240, 243);
    background-color: #FFDEE9;
    background-image: linear-gradient(0deg,#ffdee9c4 0%,#b5fffc8f 100%);
    background-image: -webkit-linear-gradient(0deg,#ffdee9c4 0%,#b5fffc8f 100%);
}
/*小宇宙*/
#zm_xyz {
    color: #eeeeee;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
    /*border-radius: 10px;*/
    box-shadow: 6px 0 12px -5px rgb(12, 85, 141), -6px 0 12px -5px rgba(10, 58, 93, 0);
    background-image: radial-gradient( circle 263px at 100.2% 3%, rgba(12,85,141,1) 31.1%, rgba(205,181,93,1) 36.4%, rgba(244,102,90,1) 50.9%, rgba(199,206,187,1) 60.7%, rgba(249,140,69,1) 72.5%, rgba(12,73,116,1) 72.6% );
}
/*橄榄绿*/
#zm_gll {
    color: #eeeeee;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
    /*border-radius: 10px;*/
    box-shadow: 6px 0 12px -5px rgb(68, 110, 92), -6px 0 12px -5px rgb(204, 212, 163);
    background-image: linear-gradient( 102deg, rgba(68,110,92,1) 17.4%, rgba(107,156,120,1) 49.3%, rgba(154,183,130,1) 83.4%, rgba(247,237,191,1) 110.3% );
}
/*小太阳*/
#zm_xty {
    color: #ffffff;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
     /*border-radius: 10px; */
    box-shadow: 6px 0 12px -5px rgb(253, 223, 234), -6px 0 12px -5px rgb(215, 240, 243);
    background-image: radial-gradient( circle farthest-corner at -8.9% 51.2%, rgba(255,124,0,1) 0%, rgba(255,124,0,1) 15.9%, rgba(255,163,77,1) 15.9%, rgba(255,163,77,1) 24.4%, rgba(19,30,37,1) 24.5%, rgba(19,30,37,1) 66% );
}
/*优雅紫*/
#zm_yyz {
  color: #ffffff;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
    /*border-radius: 10px;*/
    box-shadow: 6px 0 12px -5px rgb(175, 160, 208), -6px 0 12px -5px rgba(177, 161, 207, 0);
    background-image: radial-gradient( circle farthest-corner at 10% 20%, rgba(95,117,227,1) 0%, rgba(188,167,205,1) 90% );
}
/*深邃黑*/
#zm_szh {
  color: #c7c7c7;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
    /*border-radius: 5px;*/
    box-shadow: 6px 0 12px -5px rgb(155, 170, 185), -6px 0 12px -5px rgba(177, 161, 207, 0);
    background-image: radial-gradient( circle farthest-corner at 10% 20%, rgba(0,0,0,1) 0%, rgba(64,64,64,1) 90.2% );
}
/*无边框*/
#zm_wbk {
    color: #000000;
    overflow: hidden;
    margin: 10px 0;
    padding: 15px 15px 15px 35px;
}
#zm_xyz a , #zm_gll a{
   color: #eeeeee;
}
#zm_szh a{
  color: #c7c7c7;  
}
#zm_xty a, #zm_yyz a{
  color: #ffffff;
}

3.现在就可以在编辑器内添加如下代码使用效果了。

<div id="zm_mhz">迷幻紫</div>
<div id="zm_xgh">西瓜红</div>
<div id="zm_tkzj">天空之境</div>
<div id="zm_xyz">小宇宙</div>
<div id="zm_gll">橄榄绿</div>
<div id="zm_xty">小太阳</div>
<div id="zm_yyz">优雅紫</div>
<div id="zm_szh">深邃黑</div>
<div id="zm_wbk">无边框</div>

演示

图片[1]-新锐博客

参考

原文地址:https://www.owwee.cn/post/212.html

使用PHP代码批量更新文章内容

前言

之前文章提到网站去除登录/评论的短代码,那如何批量去除呢?其实有不少办法,这篇文章教大家如何用php实现。

教程

在此之前请备份好数据库,以免误操作造成数据的丢失。

在网站根目录下新建一个php文件,并将如下代码放到其中

<?php
require('wp-load.php');
// 替换的关键词和对应的替换词
$replacements = array(
    '关键词1' => '替换词1',
    '关键词2' => '替换词2',
    // 继续添加需要替换的关键词和对应的替换词
);

// 获取所有文章
$args = array(
    'post_type' => 'post',  // 文章类型可以根据实际情况调整
    'posts_per_page' => -1, // 获取所有文章
);
$query = new WP_Query($args);

if ($query->have_posts()) {
    while ($query->have_posts()) {
        $query->the_post();
        $post_id = get_the_ID();
        $post_content = get_post_field('post_content', $post_id);

        // 执行替换操作
        $updated_content = str_replace(array_keys($replacements), array_values($replacements), $post_content);

        // 更新文章内容
        $post_data = array(
            'ID' => $post_id,
            'post_content' => $updated_content,
        );
        wp_update_post($post_data);
    }
    wp_reset_postdata();
} else {
    echo '没有找到文章。';
}
?>

最后访问就可以了,一定要放到网站根目录,因为需要用到WordPress的函数。

❌