WordPress中表单提交后会话丢失

11

表单提交后,我设置的会话丢失了。

我已经建立了一个会话类来设置新的会话、取消等等,在WordPress模板的function.php中。

function.php

if (!session_id()) {
    session_start();
}
include get_template_directory() . "/custom/session.php";

Session.php

class session {
    function __construct() {

    }

    function set_flashdata($name, $value) {
        $_SESSION[$name] = $value;
    }

    function flashdata($name) {
        if (isset($_SESSION[$name])) {
            $str = $_SESSION[$name];
            return $str;
        } else {
            return FALSE;
        }
    }

    function userdata($name) {
        if (isset($_SESSION[$name])) {
            return $_SESSION[$name];
        } else {
            return FALSE;
        }
    }

    function set_userdata($name, $value) {
        $_SESSION[$name] = $value;
    }

    function unset_userdata($name) {
        if (isset($_SESSION[$name])) {
            unset($_SESSION[$name]);
        }
    }
}

我尝试设置会话为:

<?php 
    $sess = new session();
    $sess->set_userdata('sess_name',"some value");
?>
<form action="get_permalink(212);">
    //input buttons
</form>
提交表单后,它会转到永久链接(212)。然后我尝试了一下。
<?php
    $sess = new session();
    $value = $sess->userdata('sess_name');
    var_dump($value);      //returns false. That means session is lost after form submit. Why?
?>

你使用的是哪个主机?一些主机在处理PHP会话和WordPress时可能会出现问题。也许可以尝试使用这个插件:https://wordpress.org/plugins/wp-native-php-sessions/ - Ty Bailey
6个回答

8

每次请求都必须调用session_start()。

session_start()的任务是:

  • 创建新会话
  • 重新启动现有会话

这意味着,如果您已经创建了一个会话,并且没有调用session_start()方法,则变量$_SESSION将不会被填充。

除非: 如果在您的php.ini文件中将选项session.auto_start设置为1,则不需要调用session_start(),因为变量$_SESSION隐式地被填充。


8

您需要将会话的开始/恢复移动到会话构造函数中。

操作步骤如下:

class session
{
    function __construct()
    {
        if (! session_id()) {
            session_start();
        }
    }

还有一件需要提到的事情,每次你执行 new Session,你将会得到一个具有相同功能并且使用相同全局变量 $_SESSION 的对象。

你不需要多个 $session 对象,现在是学习 单例模式 的好时机。


在参考了单例模式并将设计模式更改为我的会话类的单例后,我的问题得到了解决。但是它是如何解决我的错误的,我不明白。这是因为类的单个对象吗? - user254153
嗨@user254153(称呼您的名字会更好)。问题通常是由于未启动/恢复相同的会话而引起的。修复算法是确保每次查询Session对象时都启动/恢复会话,因此我给出了将会话启动/恢复移动到__constructor的示例。单例模式在这里非常有效,因为您希望全局访问Session对象而不创建多个实例。 - rock3t
没错。在使用单例模式之后,我每次调用session时就不需要再创建新的对象了。 - user254153

3
听起来好像在 get_permalink(212) 所指向的页面开头没有设置 session_start()
虽然我对 WP 的了解很少,但是我可能误解了 get_permalink() 的功能。

3
可能是由于您网站域名以www.开头。请确保这两个页面使用相同的结构。

另外,我曾经遇到过类似的问题,当表单将数据发送到一个安全地址(https://)时。

希望这两个建议能够帮到您。


3
你需要使用WordPress全局变量来判断会话是否设置,例如:
您需要使用 WordPress 全局变量来判断会话是否设置,类似于以下内容:
global $session;
if (!session_id()) {
    session_start();
}
include get_template_directory() . "/custom/session.php";

为什么要使用 $session。 - user254153
WordPress有很多全局变量,因此可以在WP代码的任何地方使用。 - Mohsin khan
仍然存在wp_session变量的问题。 - user254153
你需要在session.php中的构造函数中使用session_start(),像这样:function __construct() { session_start(); } - Mohsin khan

0

我同意@rock3t的答案,在类的构造函数中初始化会话,但每次类对象被实例化时,它都会去检查会话!

相反,如果您愿意,最简单的访问会话的方法是在调用 wp-settings 之前将以下行添加到您的 wp-config.php 文件中:

if (!session_id())
    session_start();

这将在全局设置/初始化会话,您无需在类的构造函数中设置/检查session_start。
谢谢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接