类文档

WP_Ajax_Response

💡 云策文档标注

概述

WP_Ajax_Response 是 WordPress 中用于生成 XML 格式 Ajax 响应的类,常用于自定义 AJAX 动作的响应处理。它通过实例化类并调用 send() 方法来输出 XML 响应,支持多种配置选项以定制响应内容。

关键要点

  • WP_Ajax_Response 类用于生成 XML 格式的 Ajax 响应,通常与 wp_ajax_ action hook 结合使用。
  • 核心属性 $responses 存储待发送的 XML 响应数组。
  • 使用类时需实例化并传递选项数组,然后调用 send() 方法输出响应。
  • 选项数组包括 what、action、id、old_id、position、data 和 supplemental 等键值对,用于定义响应结构和内容。
  • 响应格式基于 XML-RPC,包含根元素 wp_ajax 和自定义元素,支持错误处理和附加数据。
  • 主要方法包括 __construct()、add() 和 send(),其中 add() 用于追加响应数据,send() 用于输出并设置内容类型头。

代码示例

$response = array(
   'what'=>'foobar',
   'action'=>'update_something',
   'id'=>'1',
   'data'=>'Hello world!'
);
$xmlResponse = new WP_Ajax_Response($response);
$xmlResponse->send();

注意事项

  • 当 id 为 WP_Error 对象时,data 值会被忽略,自动生成 wp_error 元素。
  • position 参数可接受整数或字符串,用于指定响应位置(如 -1 表示顶部,1 表示底部)。
  • supplemental 参数为关联数组,用于传递额外信息,渲染为 supplemental 元素的子元素。
  • send() 方法会自动设置 Content-Type 头为 text/xml,并在 Ajax 上下文中调用 wp_die()。

📄 原文内容

Send XML response back to Ajax request.

More Information

Role of WP_Ajax_Response

WP_Ajax_Response is WordPress’ class for generating XML-formatted responses to Ajax requests. This is most commonly used to generate responses to custom AJAX actions when using the wp_ajax_ action hook.

Methods and Properties

NOTE: Refer source code for the complete methods and properties.

Properties

$responses()
An array that stores the XML responses to be sent.

Usage

To use WP_Ajax_Response, you need to instantiate the class with an array of options, then call the instances send() method to output the response.

The options array takes the following key=>value pairs:

‘what’
A string containing the XMLRPC response type (used as the name of the xml element).
‘action’
A boolean or string that will behave like a nonce. This is added to the response element’s action attribute.
‘id’
This is either an integer (usually 1) or a WP_Error object (if you need to return an error). Most commonly, the id value is used as a boolean, where 1 is a success and 0 is a failure.
‘old_id’
This is false by default, but you can alternatively provide an integer for the previous id, if needed.
‘position’
This is an integer or a string where -1 = top, 1 = bottom, ‘html ID’ = after, ‘-html ID’ = before
‘data’
A string containing output content or a message (such as html). This is disregarded if you pass a WP_Error object as the id.
‘supplemental’
This can an associative array of strings, which will be rendered into children of the <supplemental> element. Keys become element names, and values are embedded in CDATA within those elements. Useful for passing additional information to the browser.

Response Format

Responses are made in the XML-RPC format and may be handled by JavaScript.

A typical WordPress autosave response looks like this:


   
      
         
            
         
         
      
   

Let’s break this example down to see what it means:

This the root element of every response. All responses made by the WP_Ajax_Response class are wrapped in the <wp_ajax> element.
Immediately within the wp_ajax element is <response>, which contains the attributes ‘action’ and ‘position’. These attributes correspond to the ‘action’ and ‘position’ key=>value pairs defined in the options array.
(arbitrary)
Next, the above example shows an <autosave> element – this element matches the value of the ‘what’ key=>value pair in the options array. In your own use, this element can be named whatever you like, provided it is a valid XML element name.
/
Within the custom response element (e.g. <autosave>), there will either be a <response_data> element (with CDATA tag) or a <wp_error_data> element. If you pass a WP_Error object to WP_Ajax_Response as the ‘id’ in your options array, the <wp_error_data> element is automatically generated. Otherwise, the <response_data> element is used with whatever value you passed to WP_Ajax_Response with your option array’s “data” value.
For the most part, any content you want to pass back to the browser (such as HTML), can be passed in your option array’s “data” key=>value pair.
Finally, the <supplemental> element will contain whatever arbitrary structure you decide to pass along with your option array’s “supplemental” key=>value pair.

Methods

Name Description
WP_Ajax_Response::__construct Constructor – Passes args to WP_Ajax_Response::add().
WP_Ajax_Response::add Appends data to an XML response based on given arguments.
WP_Ajax_Response::send Display XML formatted responses.

Source

class WP_Ajax_Response {
	/**
	 * Store XML responses to send.
	 *
	 * @since 2.1.0
	 * @var array
	 */
	public $responses = array();

	/**
	 * Constructor - Passes args to WP_Ajax_Response::add().
	 *
	 * @since 2.1.0
	 *
	 * @see WP_Ajax_Response::add()
	 *
	 * @param string|array $args Optional. Will be passed to add() method.
	 */
	public function __construct( $args = '' ) {
		if ( ! empty( $args ) ) {
			$this->add( $args );
		}
	}

	/**
	 * Appends data to an XML response based on given arguments.
	 *
	 * With `$args` defaults, extra data output would be:
	 *
	 *     <response action='{$action}_$id'>
	 *      <$what id='$id' position='$position'>
	 *          <response_data></response_data>
	 *      <!--$what-->
	 *     </response>
	 *
	 * @since 2.1.0
	 *
	 * @param string|array $args {
	 *     Optional. An array or string of XML response arguments.
	 *
	 *     @type string          $what         XML-RPC response type. Used as a child element of `<response>`.
	 *                                         Default 'object' (`<object>`).
	 *     @type string|false    $action       Value to use for the `action` attribute in `<response>`. Will be
	 *                                         appended with `_$id` on output. If false, `$action` will default to
	 *                                         the value of `$_POST['action']`. Default false.
	 *     @type int|WP_Error    $id           The response ID, used as the response type `id` attribute. Also
	 *                                         accepts a `WP_Error` object if the ID does not exist. Default 0.
	 *     @type int|false       $old_id       The previous response ID. Used as the value for the response type
	 *                                         `old_id` attribute. False hides the attribute. Default false.
	 *     @type string          $position     Value of the response type `position` attribute. Accepts 1 (bottom),
	 *                                         -1 (top), HTML ID (after), or -HTML ID (before). Default 1 (bottom).
	 *     @type string|WP_Error $data         The response content/message. Also accepts a WP_Error object if the
	 *                                         ID does not exist. Default empty.
	 *     @type array           $supplemental An array of extra strings that will be output within a `<supplemental>`
	 *                                         element as CDATA. Default empty array.
	 * }
	 * @return string XML response.
	 */
	public function add( $args = '' ) {
		$defaults = array(
			'what'         => 'object',
			'action'       => false,
			'id'           => '0',
			'old_id'       => false,
			'position'     => 1,
			'data'         => '',
			'supplemental' => array(),
		);

		$parsed_args = wp_parse_args( $args, $defaults );

		$position = preg_replace( '/[^a-z0-9:_-]/i', '', $parsed_args['position'] );
		$id       = $parsed_args['id'];
		$what     = $parsed_args['what'];
		$action   = $parsed_args['action'];
		$old_id   = $parsed_args['old_id'];
		$data     = $parsed_args['data'];

		if ( is_wp_error( $id ) ) {
			$data = $id;
			$id   = 0;
		}

		$response = '';
		if ( is_wp_error( $data ) ) {
			foreach ( (array) $data->get_error_codes() as $code ) {
				$response  .= "<wp_error code='$code'></wp_error>';
				$error_data = $data->get_error_data( $code );
				if ( ! $error_data ) {
					continue;
				}
				$class = '';
				if ( is_object( $error_data ) ) {
					$class      = ' class="' . get_class( $error_data ) . '"';
					$error_data = get_object_vars( $error_data );
				}

				$response .= "<wp_error_data code='$code'$class>";

				if ( is_scalar( $error_data ) ) {
					$response .= "";
				} elseif ( is_array( $error_data ) ) {
					foreach ( $error_data as $k => $v ) {
						$response .= "<$k><!--$k-->";
					}
				}

				$response .= '</wp_error_data>';
			}
		} else {
			$response = "<response_data></response_data>";
		}

		$s = '';
		if ( is_array( $parsed_args['supplemental'] ) ) {
			foreach ( $parsed_args['supplemental'] as $k => $v ) {
				$s .= "<$k><!--$k-->";
			}
			$s = "<supplemental>$s</supplemental>";
		}

		if ( false === $action ) {
			$action = $_POST['action'];
		}
		$x  = '';
		$x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action.
		$x .= "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>";
		$x .= $response;
		$x .= $s;
		$x .= "<!--$what-->";
		$x .= '</response>';

		$this->responses[] = $x;
		return $x;
	}

	/**
	 * Display XML formatted responses.
	 *
	 * Sets the content type header to text/xml.
	 *
	 * @since 2.1.0
	 */
	public function send() {
		header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) );
		echo "<wp_ajax>";
		foreach ( (array) $this->responses as $response ) {
			echo $response;
		}
		echo '</wp_ajax>';
		if ( wp_doing_ajax() ) {
			wp_die();
		} else {
			die();
		}
	}
}

Changelog

Version Description
2.1.0 Introduced.

User Contributed Notes

  1. Skip to note 3 content

    Typical Response Example

    This demonstrates a typical response. The first code block shows the PHP required to create a simple response. The second code block shows the generated XML.

    $response = array(
       'what'=>'foobar',
       'action'=>'update_something',
       'id'=>'1',
       'data'=>'<p><strong>Hello world!</strong></p>'
    );
    $xmlResponse = new WP_Ajax_Response($response);
    $xmlResponse->send();

    The above example would output the following XML:

    
    <wp_ajax>
       <response action='update_something_1'>
          <foobar id='1' position='1'>
             <response_data></response_data>
             <supplemental></supplemental>
          </foobar>
       </response>
    </wp_ajax>

  2. Skip to note 4 content

    Error Response Example from Codex

    This demonstrates a typical error response. The first code block shows the PHP required to generate such a response, and the second code block shows the generated XML output. Note that you can just as easily give your response an id of 0 instead of generating a new WP_Error. The choice is up to you.

    $response = array(
       'what'=>'stuff',
       'action'=>'delete_something',
       'id'=>new WP_Error('oops','I had an accident.'),
       'data'=>'Whoops, there was a problem!'
    );
    $xmlResponse = new WP_Ajax_Response($response);
    $xmlResponse->send();

    The above example would output the following XML:

    
    <wp_ajax>
       <response action='delete_something_0'>
          <stuff id='0' position='1'>
             <wp_error code='oops'></wp_error>
             <supplemental></supplemental>
          </stuff>
       </response>
    </wp_ajax>

    Note how this response completely disregards our ‘data’ value.