WordPress用Cookie替代PHP Session后数据库冗余条目问题
原本使用PHP Session,因插件冲突改用Cookie实现会话管理。现有代码可创建Cookie并写入数据库表,条目能正确保存和更新,但页面每次加载都会生成额外的数据库冗余条目,以下是问题分析与修复方案:
原代码
add_action('init', 'init_jamer_cookies'); function init_jamer_cookies () { global $wpdb; global $wp; global $woocommerce; $jamer_session_id=$_COOKIE['jamer_session_id']; if(!isset($jamer_session_id)) { $time=current_time( 'timestamp' ) + ( DAY_IN_SECONDS * 7 ); $randomString=generateRandomString(20); setcookie('jamer_session_id', $randomString, $time, COOKIEPATH, COOKIE_DOMAIN); $tablename='jamercookies'; $tablename_all = $wpdb->prefix.$tablename; $wpdb->insert($tablename_all, array('jamer_session_id' => $randomString, 'schoolid' => '' )); } return; } function generateRandomString($length ) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } add_shortcode('mc_check_access1','mc_check_access'); // Checks access function mc_check_access() { global $wpdb; global $wp; global $woocommerce; $url = wc_get_page_permalink( 'home' ); if ($_POST["submit"] ) { $schoolname = $_POST["SchoolName"]; $schoollogin = $_POST["SchoolLogin"]; $schoolset==0; $schoolset = set_jamer_session ($schoolname, $schoollogin); if ($schoolset==1 ) { $_POST=array(); $schoolset=0; $url = wc_get_page_permalink( 'shop' ); wp_redirect( $url ); exit; } } return; } // Sets up Session Variables function set_jamer_session ($postedschoolname, $postedschoollogin) { global $wpdb; global $wp; $schoolset=0; $tablename="schools"; $tablename_all = $wpdb->prefix.$tablename; $querycode="select schoolid, password from $tablename_all where schoolid='$postedschoolname' and password='$postedschoollogin'"; $rs=$wpdb->get_results($querycode); $rscount=count($rs); if ($rscount=1) { $count=1; foreach($rs as $r) { $schoolid= trim($r->schoolid); $schoolidpassword= trim($r->password); } $schoolset=1; $tablename2="jamercookies"; $tablename_all2 = $wpdb->prefix.$tablename2; $jamercookieid=$_COOKIE['jamer_session_id']; if(isset($jamercookieid)) { $wpdb->update($tablename_all2, array( 'schoolid' => $schoolid), array('jamer_session_id' => $jamercookieid)); } } return $schoolset; } function mc_find_schoolid() { global $wpdb; global $wp; global $woocommerce; $schoolid="No School Set"; $jamercookieid=$_COOKIE['jamer_session_id']; if(isset($jamercookieid)) { $tablename="jamercookies"; $tablename_all = $wpdb->prefix.$tablename; $querycode="select schoolid from $tablename_all where jamer_session_id ='$jamercookieid'"; $rs=$wpdb->get_results($querycode); $rscount=count($rs); if ($rscount=1) { $count=1; foreach($rs as $r) { $schoolid= trim($r->schoolid); }}} return $schoolid; }
问题根源
Cookie存在性判断逻辑错误:
原代码先执行$jamer_session_id=$_COOKIE['jamer_session_id'];,当Cookie不存在时,会触发PHP警告且$jamer_session_id被赋值为null。随后!isset($jamer_session_id)返回true(因为isset(null)为false),导致每次请求都进入创建Cookie和插入数据库的逻辑,生成冗余条目。赋值操作误用作比较:
代码中多处出现if ($rscount=1),这是赋值操作而非比较操作,会导致无论查询结果数量多少,条件都会成立,引发逻辑错误。SQL注入风险:
直接将用户输入拼接到SQL语句中,存在安全隐患。
修复方案
1. 修正Cookie存在性判断
直接检查$_COOKIE数组中是否存在目标键,避免提前赋值导致的判断错误,同时增加重复条目校验:
add_action('init', 'init_jamer_cookies'); function init_jamer_cookies () { global $wpdb; if (!isset($_COOKIE['jamer_session_id'])) { $time = current_time('timestamp') + (DAY_IN_SECONDS * 7); $randomString = generateRandomString(20); setcookie('jamer_session_id', $randomString, $time, COOKIEPATH, COOKIE_DOMAIN); // 插入前校验是否已存在,防止异常重复插入 $tablename_all = $wpdb->prefix . 'jamercookies'; $existing_count = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $tablename_all WHERE jamer_session_id = %s", $randomString )); if ($existing_count == 0) { $wpdb->insert($tablename_all, array( 'jamer_session_id' => $randomString, 'schoolid' => '' )); } } return; }
2. 修正赋值为比较操作
将set_jamer_session和mc_find_schoolid中的if ($rscount=1)改为if ($rscount == 1):
// 在set_jamer_session函数中 if ($rscount == 1) { // 原有逻辑 } // 在mc_find_schoolid函数中 if ($rscount == 1) { // 原有逻辑 }
3. 修复SQL注入风险
使用$wpdb->prepare处理用户输入:
// 在set_jamer_session函数中替换查询语句 $querycode = $wpdb->prepare( "SELECT schoolid, password FROM $tablename_all WHERE schoolid = %s AND password = %s", $postedschoolname, $postedschoollogin ); // 在mc_find_schoolid函数中替换查询语句 $querycode = $wpdb->prepare( "SELECT schoolid FROM $tablename_all WHERE jamer_session_id = %s", $jamercookieid );
4. 移除未使用的全局变量
删除代码中未实际使用的$wp、$woocommerce全局变量,减少资源占用。
内容的提问来源于stack exchange,提问作者Merche
相关产品推荐
相关产品推荐

