I'm working on a script that will be used to show a progress bar when large amounts of data are exported. For this to work you need to know how many location you have in total, and keep that number somewhere.

When I run the below code outside of WordPress, then it works as expected.

It shows this output.

{"uncoded":"123"}
not null
not null
not null
not null 

It's null on the first loop, so it grabs the value and after that the $total value is set, so it's not null anymore. But when I call it through AJAX the getTotal() is always null. It should be null the first time, but not after that. It should contain the total amount of rows on the second attempt.

This is the code I'm using.

class progress {

    private static $total = null;

    public function getTotal() {
        return self::$total;
    }

    public static function setTotal() {
        self::$total = '123';
    }
}

class batch extends progress {

    function __construct() {
        add_action( 'wp_ajax_batch_actions',        array( $this, 'run' ) );
        add_action( 'wp_ajax_nopriv_batch_actions', array( $this, 'run' ) );
    }

    public function run() {

        if ( is_null( $this->getTotal() ) ) {
            $this->setTotal();

            $total = $this->getTotal();
            echo json_encode( array( 'uncoded' => $total ) );
        } else {
            echo 'not null';
        }

        exit();
    }
}

I'm a bit confused why this works fine without AJAX in WordPress, but as soon as you use the AJAX action it fails to remember the $total value. It's always null?

Does anyone have any idea why, and also how to make it work correctly with AJAX?

  • What do you mean "remember the $total value"? Do you mean over multiple AJAX requests? Of course it won't remember it, that's not how PHP works. If you want to remember a value over multiple requests the value needs to be stored in a database. – Jacob Peattie Sep 29 at 9:46
  • Yes, multiple batched AJAX request that are each individually triggered once the previous one is finished and the progress bar is updated. If you make 5 requests in a row without AJAX, then it does remember it. But I probably have to think of another solution. – tijmen Sep 29 at 17:29
  • It wouldn’t work without AJAX either. Nothing is remembered between requests in PHP.without a database or cookie. How were you doing these ‘requests’? – Jacob Peattie Sep 29 at 17:53
  • @tijmen, "5 requests in a row without AJAX" — I think you meant 5 requests on the same page load and not 5 different page loads, which with AJAX, each request is a new page load/request, except that it's done without actually reloading the page (not reloaded by the browser). So your $total persists or is "remembered" only on the same page load. – Sally CJ Sep 29 at 22:20

Instead of a static class property, you could use a PHP session:

class progress {

    public function __construct() {
        session_start();
    }

    public function getTotal() {
        return $_SESSION[ 'total' ];
    }

    public static function setTotal() {
        $_SESSION[ 'total' ] = '123';
    }
}

If you're doing more complex stuff, a session wrapper like Symfony's might be a good idea.

  • 1. it does not actually answer the question 2. sessions should never be used in polite php enviroment. If you think you need a session, just use a cookie – Mark Kaplun Sep 29 at 15:12
  • @Mark Kaplun I see that PHP sessions are not a good solution for modern web applications with lots of parallel requests. So what do you suggest for this use case - cookies, maybe transients? – Michael Sep 29 at 16:45
  • If you have a one server setup, sessions are basically cookies. if you have multi server setup you need to store thing in the DB. For example WC has a session class for that and it stores session data as user meta – Mark Kaplun Sep 29 at 17:42

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.