I am creating an in-house plugin that will offer a filtering mechanism using AJAX for any post type depending on the configuration, which I have stored in a JSON.

When the plugin is loaded, I need to set the callback for the AJAX call, and I set that right away (I'm sticking to OOP):

$gfb = FilterBuilder::get_instance();
$action_filter_reg_instance = new ActionFilterRegistration();
$action_filter_reg_instance->add_action( 'wp_ajax_process_filters', $gfb, 'process_filters_callback' );

That sets the callback and it works fine...but that instance of $gbf is lost when the page that displays the posts loads and I need to set more properties when the template is loaded.

For instance, when the page that displays the posts loads, I create a new FilterBuilder object and pass it the query args which are then stored on the instance as a property of the class.

When the callback is invoked, it's dealing with its own instance of a FilterBuilder, so anything I defined in the template does not exist in this class instance.

This puts me in a bit of a pickle because I would like to have access to the query args that were defined when that particular instance was created.

I have resorted for the time being to use transients so I can have a common place to access the query args that the template instance defined from the callback function, but this just feels wrong. Furthermore, I believe transients have a max length and therefore this might explode if that limit is reached.

What other options are there? Maybe serializing the template class instance into a JSON and load it from the callback? That also sounds ... a bit meh.

I do not want to use global variables...interested in what you think would be an elegant approach to circumvent this issue.

Thanks for taking the time to read this! 👍🏽

  • There's not enough information in the question to properly understand what you're attempting. FilterBuilder and ActionFilterRegistration are completely opaque. That being said, if I understand your issue correctly, I think your basic approach is wrong. If you want to process filters in an AJAX request, then you should be sending all the query arguments alongside the AJAX request, and using those, rather than trying to persist them across requests. Commented Apr 4, 2020 at 8:11
  • Hey, thanks for the reply. I don't think you need to know what those classes are doing...basically the question is: how do you share the properties of two class instances that are created in different spaces : 1st instance when the hook is added when plugin is loaded, 2nd instance: when the template is loaded and I have enough information about the query to perform. I do send the all arguments to the AJAX request...I think I just figured it out, lol..I'll send the AJAX request a serialised version of the query args, and then send that as POST arguments to the callback function.
    – csaborio
    Commented Apr 5, 2020 at 1:47

1 Answer 1


Ok, so this is how I did it, and it's not an awful hack.

So my problem was passing values (in this case, query args) to a callback function from a instance of a class that was created BEFORE the query args existed.

The transient approach worked but can break anytime.

So when the function query value exists, I simply assigned it as the value of an hidden input field that belongs to the form that holds the filters, namely:

echo( '<input type="hidden" name="wp-query-args" value="' . $encoded_query_args . '">' );

At this stage the $encoded_query_args contains the serialised query using wp_json_encode.

When the AJAX call is made, it sends the form data serialised to the callback function using POST:

function requestSetup($,formId,ajaxURL) {
    $('#saf_submit').on('click', function(){
        var filter = $(formId);
            data:filter.serialize(), // form data

The callback can then received this information and decode query args into its original form:

$query_args = self::decode_query_args( $_POST['wp-query'] );

No transients, no limits, it simply works! :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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