$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>php - Unset session variable on page reloadsetup but exclude AJAX|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

php - Unset session variable on page reloadsetup but exclude AJAX

matteradmin8PV0评论

I'm currently trying to unset a session variable in WordPress if the page get's reloaded. I've tried a lot but it's not working like I want it. This is my function:

/**
 * Unset filter session if page get's reloaded
 */
add_action( 'wp', 'unset_filter_session' );
function unset_filter_session() {
    //Reset sessions on refresh page
    unset( $_SESSION['expenditure_filter'] );
}

It's working but it's working too good. Because when I reload the content-area in WordPress via AJAX, the session get's unset too which should be avoided:

jQuery('#content-area').load(location.href + ' #content-area>*', '');

So how can I do the unset of the session just on page load and exclude AJAX reloads?

I'm currently trying to unset a session variable in WordPress if the page get's reloaded. I've tried a lot but it's not working like I want it. This is my function:

/**
 * Unset filter session if page get's reloaded
 */
add_action( 'wp', 'unset_filter_session' );
function unset_filter_session() {
    //Reset sessions on refresh page
    unset( $_SESSION['expenditure_filter'] );
}

It's working but it's working too good. Because when I reload the content-area in WordPress via AJAX, the session get's unset too which should be avoided:

jQuery('#content-area').load(location.href + ' #content-area>*', '');

So how can I do the unset of the session just on page load and exclude AJAX reloads?

Share Improve this question asked Dec 5, 2018 at 0:05 Johnny97Johnny97 2147 silver badges18 bronze badges 4
  • I'd keep in mind that sessions don't work on all hosts, and are incompatible with a lot of caching mechanisms, with an added server overhead, which is why WP uses cookies and user meta – Tom J Nowell Commented Dec 5, 2018 at 0:43
  • User meta is not possible for not registered users. Cookies might be a solution but what if the user disabled cookies? – Johnny97 Commented Dec 5, 2018 at 0:46
  • I wouldn't expect any site to be able to track what I'm doing if I set cookies, which is kind of the point. At that point you could create table entries or posts and pass around a transaction ID, but then you would need the users consent to store data about them to comply with data protection legislation, else it could be illegal in some states/countries/continents, e.g. California, or the EU – Tom J Nowell Commented Dec 5, 2018 at 0:57
  • Additionally, you can use URLs, a filtered view can have a filter endpoint on the end so it remains unique, this also improves compatibility with fullpage caching – Tom J Nowell Commented Dec 5, 2018 at 0:58
Add a comment  | 

2 Answers 2

Reset to default 2

Try using wp_doing_ajax() like so:

function unset_filter_session() {
    if ( ! wp_doing_ajax() ) {
        //Reset sessions on refresh page
        unset( $_SESSION['expenditure_filter'] );
    }
}

UPDATE

You can check the answer's revision for this update part..

UPDATE #2

Sorry, I didn't realize that you're loading a page fragment (#content-area) using the jQuery.load() method. Or that you're not using the admin-ajax.php to handle the AJAX request.

So if you're not using the wp_ajax_{action} or wp_ajax_nopriv_{action} action, or with the way you do the AJAX request, you can check whether the X-Requested-With header is set and that its value is XMLHttpRequest, and if so, you can cancel the session unsetting, like so:

function unset_filter_session() {
    if ( empty( $_SERVER['HTTP_X_REQUESTED_WITH'] ) ||
        'XMLHttpRequest' !== $_SERVER['HTTP_X_REQUESTED_WITH'] ) {
        //Reset sessions on refresh page, if not doing AJAX request
        unset( $_SESSION['expenditure_filter'] );
    }
}

That should work because jQuery always sets that header, unless you explicitly remove it — or change its value.

See the headers option on the jQuery.ajax() reference:

The header X-Requested-With: XMLHttpRequest is always added, but its default XMLHttpRequest value can be changed

Note: The header name is X-Requested-With, but in the superglobal $_SERVER, its key is HTTP_X_REQUESTED_WITH. I.e. Don't use $_SERVER['X-Requested-With'].

UPDATE #3

As suggested by Lawrence Johnson, you (ahem, we) should use filter_input():

function unset_filter_session() {
    if ( 'XMLHttpRequest' !== filter_input( INPUT_SERVER, 'HTTP_X_REQUESTED_WITH' ) ) {
        //Reset sessions on refresh page, if not doing AJAX request
        unset( $_SESSION['expenditure_filter'] );
    }
}

(but I kept the previous code for reference)

One thing you could consider doing is adding a header variable to your AJAX requests. Even a GET or POST param would likely to the trick. Perhaps something like this:

/**
 * Unset filter session if page get's reloaded
 */
add_action( 'wp', 'unset_filter_session' );
function unset_filter_session() {
    //Reset sessions on refresh page
    if (!filter_input(INPUT_POST, 'isContentLoader', FILTER_SANITIZE_NUMBER_INT)) {
        unset( $_SESSION['expenditure_filter'] );
    }
}

And then

jQuery('#content-area').load(location.href + ' #content-area>*', { isContentLoader: 1 });
Post a comment

comment list (0)

  1. No comments so far