点击购买按钮时将对应Post ID存入PHP Session的问题
问题分析与解决方案
你的问题核心在于混淆了服务器端(PHP)和客户端(JavaScript)的执行时机,加上重复的ID导致事件绑定失效,具体原因如下:
- PHP是服务器端语言,页面加载时就会执行循环里的
$_SESSION['eventId'] = get_the_ID();,循环结束后Session里自然被最后一个帖子的ID覆盖,点击按钮的JS事件根本不会触发这个赋值操作。 - 所有购买按钮都用了相同的
id="teatro-buy",HTML中ID必须唯一,这会导致JS只能绑定到最后一个按钮,或者事件完全失效。
正确的解决思路
我们需要把按钮对应的Post ID通过HTML属性存储,然后用AJAX异步请求将ID传给PHP,由PHP在请求时将ID存入Session。
修改后的完整代码
1. 更新短代码函数
function calendario_posts() { ob_start(); // 确保Session已启动 if (!session_id()) { session_start(); } // WP_Query arguments $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args = array( 'category_name' => 'calendario', 'posts_per_page' => '6', 'paged' => $paged ); // The Query $featured_post_query = new WP_Query($args); // The Loop if ($featured_post_query->have_posts()) { while ($featured_post_query->have_posts()) { $featured_post_query->the_post(); $post_id = get_the_ID(); ?> <div class="teatro-all"> <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('gallery'); ?></a> <h2 class="teatro-group teatro-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <h5 class="teatro-group teatro-fecha"><?php the_field('fecha'); ?></h5> <h5 class="teatro-group teatro-precio">Precio desde: <?php the_field('precio'); ?></h5> <center> <!-- 用data属性存储Post ID,给按钮唯一ID --> <a class="teatro-buy teatro-button" href="javascript:void(0)" id="teatro-buy-<?php echo $post_id; ?>" data-post-id="<?php echo $post_id; ?>"> COMPRAR </a> </center> <center> <a class="teatro-read-more teatro-button" href="<?php the_permalink(); ?>">LEER MAS</a> </center> <?php } // 分页链接(可选,根据需求添加) echo paginate_links(array( 'total' => $featured_post_query->max_num_pages )); } else { echo '<p>No se encontraron eventos.</p>'; } // Restore original Post Data wp_reset_postdata(); // 统一添加JS脚本,避免重复生成 ?> <script> // 给所有购买按钮绑定点击事件 document.querySelectorAll('.teatro-buy').forEach(button => { button.addEventListener('click', function() { const postId = this.getAttribute('data-post-id'); // 发送AJAX请求到PHP处理Session fetch('<?php echo admin_url('admin-ajax.php'); ?>', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-WP-Nonce': '<?php echo wp_create_nonce('store_event_id_nonce'); ?>' }, body: `action=store_event_id&post_id=${postId}` }) .then(response => response.json()) .then(data => { if (data.success) { // 成功后跳转到购票页面 window.location.href = 'http://localhost/newiga/tickets/'; } else { alert('Hubo un error al guardar el evento.'); } }) .catch(error => { console.error('Error:', error); alert('Hubo un error al procesar la solicitud.'); }); }); }); </script> <?php $output = ob_get_clean(); return $output; } function calendario_shortcode() { return calendario_posts(); } add_shortcode('calendario', 'calendario_shortcode');
2. 添加AJAX处理函数(放在functions.php中)
// 处理存储Event ID到Session的AJAX请求 add_action('wp_ajax_store_event_id', 'store_event_id_in_session'); add_action('wp_ajax_nopriv_store_event_id', 'store_event_id_in_session'); // 允许未登录用户访问(如果需要) function store_event_id_in_session() { // 验证Nonce确保请求合法 if (!wp_verify_nonce($_POST['X-WP-Nonce'], 'store_event_id_nonce')) { wp_send_json_error('Invalid nonce'); } if (!session_id()) { session_start(); } if (isset($_POST['post_id']) && is_numeric($_POST['post_id'])) { $_SESSION['eventId'] = intval($_POST['post_id']); wp_send_json_success('Event ID stored successfully'); } else { wp_send_json_error('Invalid post ID'); } }
关键修改点说明
- 按钮属性优化:给每个购买按钮添加
data-post-id存储对应Post ID,同时设置唯一ID,避免冲突;将href改为javascript:void(0)防止默认跳转,由AJAX成功后再跳转。 - AJAX异步处理:通过
fetch发送请求到WordPress的AJAX接口,用Nonce验证请求合法性,确保安全。 - Session启动:在短代码和AJAX函数中都检查并启动Session,避免Session未初始化的问题。
- 脚本统一加载:将JS脚本移到循环外部,避免重复生成,提高性能。
内容的提问来源于stack exchange,提问作者Joseph Castillo
相关产品推荐
相关产品推荐

