WP_Ajax_Response Class
The WP_Ajax_Response class generates XML responses for AJAX requests. This is the legacy response format, primarily used by WordPress core for backward compatibility. For new code, prefer wp_send_json_* functions.
File: wp-includes/class-wp-ajax-response.php
Since: WordPress 2.1.0
Class Definition
#[AllowDynamicProperties]
class WP_Ajax_Response {
public $responses = array();
public function __construct($args = '');
public function add($args = '');
public function send();
}
Properties
$responses
- Type:
array - Access:
public - Description: Stores XML response strings to be sent
Methods
__construct($args = '')
Constructor that optionally passes arguments to add().
Parameters:
$args(string|array) – Optional. Arguments to pass toadd()
Example:
// Create and immediately add a response
$response = new WP_Ajax_Response(array(
'what' => 'comment',
'id' => 42,
'data' => 'Comment saved successfully',
));
add($args = '')
Appends data to the XML response. Returns the XML string for the added response.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
what |
string | 'object' |
XML element type, becomes child of <response> |
action |
string|false | false |
Action attribute value; defaults to $_POST['action'] if false |
id |
int|WP_Error | 0 |
Response ID; if WP_Error, data is extracted from it |
old_id |
int|false | false |
Previous ID for updates; false hides attribute |
position |
string | 1 |
Position hint: 1 (bottom), -1 (top), HTML ID (after), -HTML ID (before) |
data |
string|WP_Error | '' |
Response content; WP_Error outputs error codes/messages |
supplemental |
array | array() |
Extra data output in <supplemental> element |
Return: string – The XML response fragment
Example:
$response = new WP_Ajax_Response();
// Simple success
$response->add(array(
'what' => 'row',
'id' => 123,
'data' => '<tr><td>New row content</td></tr>',
));
// With supplemental data
$response->add(array(
'what' => 'item',
'id' => 456,
'data' => 'Item created',
'supplemental' => array(
'total_count' => 42,
'timestamp' => time(),
),
));
// Error response
$response->add(array(
'what' => 'item',
'id' => new WP_Error('create_failed', 'Could not create item'),
));
send()
Outputs the complete XML response and terminates execution.
Behavior:
- Sets
Content-Type: text/xmlheader - Outputs XML declaration and
<wp_ajax>wrapper - Outputs all accumulated responses
- Calls
wp_die()(if AJAX) ordie()
Example:
$response = new WP_Ajax_Response();
$response->add(array(
'what' => 'comment',
'id' => $comment_id,
'data' => $comment_html,
));
$response->send(); // Outputs XML and exits
XML Output Format
Basic Structure
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<wp_ajax>
<response action='my_action_123'>
<object id='123' position='1'>
<response_data><![CDATA[Response content here]]></response_data>
</object>
</response>
</wp_ajax>
With Supplemental Data
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<wp_ajax>
<response action='save_item_456'>
<item id='456' position='1'>
<response_data><![CDATA[Item saved]]></response_data>
<supplemental>
<count><![CDATA[42]]></count>
<timestamp><![CDATA[1609459200]]></timestamp>
</supplemental>
</item>
</response>
</wp_ajax>
Error Response
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<wp_ajax>
<response action='create_item_0'>
<item id='0' position='1'>
<wp_error code='create_failed'><![CDATA[Could not create item]]></wp_error>
</item>
</response>
</wp_ajax>
With Error Data
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<wp_ajax>
<response action='save_0'>
<object id='0' position='1'>
<wp_error code='validation_error'><![CDATA[Invalid input]]></wp_error>
<wp_error_data code='validation_error'>
<field><![CDATA[email]]></field>
<reason><![CDATA[Invalid format]]></reason>
</wp_error_data>
</object>
</response>
</wp_ajax>
Complete Usage Example
PHP Handler
add_action('wp_ajax_add_item', 'handle_add_item');
function handle_add_item() {
check_ajax_referer('add_item_nonce', 'security');
if (!current_user_can('edit_posts')) {
$response = new WP_Ajax_Response(array(
'what' => 'item',
'id' => new WP_Error('permission_denied', 'You cannot add items'),
));
$response->send();
}
$item_id = create_item($_POST['data']);
if (is_wp_error($item_id)) {
$response = new WP_Ajax_Response(array(
'what' => 'item',
'id' => $item_id, // Pass WP_Error directly
));
$response->send();
}
$response = new WP_Ajax_Response(array(
'what' => 'item',
'id' => $item_id,
'data' => render_item_row($item_id),
'position' => 1, // Add at bottom
'supplemental' => array(
'total' => get_item_count(),
),
));
$response->send();
}
JavaScript Handler
jQuery.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'add_item',
security: nonce,
data: itemData
},
dataType: 'xml',
success: function(xml) {
var $response = jQuery(xml).find('response');
var $item = $response.find('item');
// Check for errors
var $error = $item.find('wp_error');
if ($error.length) {
alert('Error: ' + $error.text());
return;
}
// Get response data
var id = $item.attr('id');
var html = $item.find('response_data').text();
var total = $item.find('supplemental total').text();
// Insert based on position
var position = $item.attr('position');
if (position === '1') {
jQuery('#item-list').append(html);
} else if (position === '-1') {
jQuery('#item-list').prepend(html);
}
jQuery('#total-count').text(total);
}
});
Position Values
| Value | Meaning | Typical Use |
|---|---|---|
1 |
Bottom | Append to list |
-1 |
Top | Prepend to list |
html_id |
After element | Insert after #html_id |
-html_id |
Before element | Insert before #html_id |
Multiple Responses
You can add multiple responses before sending:
$response = new WP_Ajax_Response();
// Add multiple items
foreach ($items as $item) {
$response->add(array(
'what' => 'item',
'id' => $item->ID,
'data' => render_item($item),
));
}
$response->send();
When to Use
Use WP_Ajax_Response When:
- Maintaining legacy code that expects XML
- Working with existing WordPress admin list tables
- Need structured multi-part responses
Use wp_send_json_* Instead When:
- Building new AJAX handlers
- Working with modern JavaScript
- Need simpler response handling
- Building REST-like APIs
Core Usage
WordPress core uses WP_Ajax_Response extensively in admin list tables for:
- Adding/deleting comments
- Adding/editing tags
- Inline editing posts
- Managing menu items
- Widget operations
Example from core (wp-admin/includes/ajax-actions.php):
function wp_ajax_add_tag() {
// ... validation ...
$tag = wp_insert_term($tag_name, $taxonomy, $args);
if (is_wp_error($tag)) {
$x = new WP_Ajax_Response(array(
'what' => 'taxonomy',
'data' => $tag,
));
$x->send();
}
// ... build response ...
$x = new WP_Ajax_Response(array(
'what' => 'taxonomy',
'supplemental' => $supplemental,
'id' => $tag['term_id'],
'data' => $tag_row,
));
$x->send();
}