You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JavaScript调用WordPress短代码执行PHP实现动态直播横幅

问题

我有一段实现YouTube频道直播时显示横幅的WordPress短代码PHP片段,需要该PHP频繁执行(最好用户每次加载页面时都调用)。代码如下:

$ytchannelID = "[YT Channel ID here";
$ytliveurl = "https://www.youtube.com/channel/".$ytchannelID."/live";
$ytchannelLIVE = '"isLive":true';
$contents = file_get_contents($ytliveurl);
$start = strpos($contents, '<meta name="title" content="') + 28;
$length = strpos($contents, '"><meta name="description" content="') - $start;
$src = substr($contents, $start, $length);
if ( strpos($contents, $ytchannelLIVE) !== false ){echo '<style type="text/css" media="screen"> * { margin: 0; padding: 0; } div#banner { top: 0; left: 0; background-color: #FFFF00; width: 100%; } div#banner-content { width: 100%; margin: 0 auto; padding: 5px; border: 1px solid #000; text-align: center; font-family: "Permanent Marker"; } </style> <div id="banner"> <div id="banner-content"> 🔴 Channel is live! 🔴 <a href="[watch url here]" style="color: #000FFF;">Tune in now: ' . $src . '</a></div> </div>';} else {echo '<div id="banner"> <div id="banner-content"></div> </div>';}
unset($ytliveurl);

这段PHP功能正常,但必须禁用页面缓存,否则直播横幅会持续显示或无法实时更新(因输出HTML被缓存而非执行服务器端PHP)。我的设想是使用可缓存的JavaScript调用该短代码对应的PHP函数,只需执行类似do_shortcode('[wpcode id="1238"]')的调用即可。

请问该方案是否可行?是否应该采用?若可行,具体如何实现?我需要在页面缓存的情况下仍能动态显示/隐藏横幅,即在静态缓存页面中实现动态内容。

方案分析与实现步骤

可行性与必要性

这个方案完全可行,且非常推荐采用。核心逻辑是:静态缓存页面仅包含触发请求的JS代码,用户每次加载页面时,JS都会主动向服务器发起新请求获取最新直播状态,完美绕过页面缓存的限制——既保留了缓存带来的性能优势,又能实现直播状态的实时更新,是缓存环境下动态内容的标准实现方式。

具体实现步骤

1. 封装PHP为AJAX接口(替代直接调用短代码)

直接调用短代码的思路不够高效,更合理的做法是将直播状态检测逻辑封装为WordPress AJAX接口,这样JS可以直接请求这个接口获取动态内容:

function check_yt_live_status() {
    // 替换为你的YouTube频道ID(修正原代码的引号错误)
    $ytchannelID = "UCxxxxxxxxx";
    $ytliveurl = "https://www.youtube.com/channel/" . $ytchannelID . "/live";
    $ytchannelLIVE = '"isLive":true';

    // 使用WordPress内置HTTP请求函数,比file_get_contents更可靠且符合规范
    $response = wp_remote_get($ytliveurl, array(
        'timeout' => 5, // 设置5秒超时,避免阻塞服务器
    ));

    // 请求失败时返回空内容
    if (is_wp_error($response)) {
        echo '';
        wp_die();
    }

    $contents = wp_remote_retrieve_body($response);
    $start = strpos($contents, '<meta name="title" content="') + 28;
    $length = strpos($contents, '"><meta name="description" content="') - $start;
    $src = substr($contents, $start, $length);

    $output = '';
    if (strpos($contents, $ytchannelLIVE) !== false) {
        // 可直接使用$ytliveurl作为观看链接,YouTube会自动跳转当前直播
        $watch_url = $ytliveurl;
        $output = '<style type="text/css" media="screen"> 
                    div#banner { top: 0; left: 0; background-color: #FFFF00; width: 100%; } 
                    div#banner-content { width: 100%; margin: 0 auto; padding: 5px; border: 1px solid #000; text-align: center; font-family: "Permanent Marker"; } 
                </style> 
                <div id="banner"> 
                    <div id="banner-content"> 🔴 频道正在直播!🔴 <a href="' . esc_url($watch_url) . '" style="color: #000FFF;">立即观看:' . esc_html($src) . '</a></div> 
                </div>';
    } else {
        $output = '<div id="banner"><div id="banner-content"></div></div>';
    }

    // 可选:添加本地缓存,10分钟更新一次,减少服务器负载和YouTube请求
    set_transient('yt_live_status_' . $ytchannelID, $output, 600);

    echo $output;
    wp_die(); // 必须调用,结束AJAX请求
}

// 注册AJAX接口,允许前台未登录用户访问
add_action('wp_ajax_nopriv_check_yt_live', 'check_yt_live_status');
add_action('wp_ajax_check_yt_live', 'check_yt_live_status');

将上述代码添加到你的主题functions.php文件中,或通过自定义代码插件添加。

2. 添加前端JS请求动态内容

在页面中插入以下JS代码(可添加到主题footer.php、自定义HTML区块,或通过自定义代码插件的前端脚本功能添加):

document.addEventListener('DOMContentLoaded', function() {
    // 创建横幅容器,插入到页面最顶部
    var bannerContainer = document.createElement('div');
    bannerContainer.id = 'yt-live-banner-container';
    document.body.insertBefore(bannerContainer, document.body.firstChild);

    // 发起AJAX请求获取横幅内容
    fetch('/wp-admin/admin-ajax.php?action=check_yt_live')
        .then(response => response.text())
        .then(html => {
            bannerContainer.innerHTML = html;
        })
        .catch(error => {
            console.error('加载直播横幅失败:', error);
        });
});

这段代码会在页面加载完成后,自动请求AJAX接口并渲染横幅内容。

3. (可选)用短代码封装JS

如果你习惯用短代码插入功能,可以将上述JS封装为短代码,这样在页面编辑器中插入[yt_live_banner]即可:

function yt_live_banner_shortcode() {
    ob_start();
    ?>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            var bannerContainer = document.createElement('div');
            bannerContainer.id = 'yt-live-banner-container';
            document.body.insertBefore(bannerContainer, document.body.firstChild);

            fetch('/wp-admin/admin-ajax.php?action=check_yt_live')
                .then(response => response.text())
                .then(html => {
                    bannerContainer.innerHTML = html;
                })
                .catch(error => {
                    console.error('加载直播横幅失败:', error);
                });
        });
    </script>
    <?php
    return ob_get_clean();
}
add_shortcode('yt_live_banner', 'yt_live_banner_shortcode');

注意事项

  • 缓存排除:确保你的服务器/CDN缓存规则中,排除/wp-admin/admin-ajax.php?action=check_yt_live这个URL,避免AJAX响应被缓存。
  • 安全优化:代码中使用了esc_url()和esc_html()做转义,避免XSS攻击,不要省略这些安全处理。
  • 性能优化:通过set_transient()添加的本地缓存可以根据需求调整时长(比如5分钟=300秒),平衡实时性和服务器负载。

内容的提问来源于stack exchange,提问作者Atra1n2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:44:53