Via the “Annotate” function the the Trac, you can see that this was added three years ago, after the request for a generic POST handler that plugins can use.
Google code search tells me that at least Akismet uses this hook, and it appeared there at the time it was introduced in core. It works by calling admin.php
directly (and not the plugin page). From there it can just do a redirect at the end. The trick is thus to call admin.php?action=your_action
, other URLs are not guaranteed to work.
Many (but not all) admin pages include admin.php
, as a sort of initialization. In this case your action would be fired before any output is sent, because the admin page includes admin-header.php
after admin.php
. This won’t work on every admin page: not all of them include admin.php
, and others have checks for “rogue” action
query variables, and give you a “Are you sure you want to do that?” warning (due to missing nonces?). For a plugin page admin.php
does everything: it displays the header (unless the noheader
query variable is in the URL), calls your page, and displays the footer (unless you called exit()
in your code!). admin.php
then calls exit()
itself, so the admin_action_
hook is not even called there.