Setting up an API “listening” page

The question:

I need to create a PHP script that will receive data from another application via an HTTP post, process that data, and update the WordPress database. This script will run silently (i.e., no HTTP output). What is the best way to set up such a page? I thought about creating a custom template file with the PHP script and assigning that template to a blank WordPress page, but is there a better method I should use?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I would use the Rewrite API and the template_redirect action to respond to API requests.

As an example, if I wanted to respond to requests directed to the url: example.com/example-path/ with logic in my theme or plugin’s endpoint.php file I would create a rewrite rule and template redirect hook like so:

add_action( 'init', 'example_rewrite_rules' );
add_action( 'template_redirect', 'example_template_route' );

/**
 * Add rewrite rules for Example endpoint.
 */
function example_rewrite_rules()
{
    add_rewrite_rule(
        'example-path/?$',
        'index.php',
        'top'
   );
}

function example_template_route( $default_template ) {
    global $wp, $wp_rewrite;

    if ( $wp->matched_rule == 'example-path/?$' ) {
        // call function or include template view here.
        include dirname( __FILE__ ) . '/endpoint.php';
        exit();   
    }
}

Depending on the data being posted from your API you may also want to add a rewrite_tag to be able to access query strings passed to your example-path route.

Method 2

Seems like you’re asking for a couple of things. I’ll try my best to help.

  1. I need to create a PHP script that will receive data from another application via an HTTP post, process that data, and update the WordPress database

    • You’ll need a .htaccess rule to direct all requests for a particular url pattern to a certain script. What would make sense to me is matching api/version_number/api_resource to a particular php script.

      Example: Use .htaccess to map api/v1/user requests to wp-contentthemesyour_themeapiv1user.php. Now your user can do www.philosophyguy.com/api/v1/user?id=1337&action=upvote and your script will upvote user #1337. You can set it up to collect POST requests instead of GET. Or both, if you like. It all depends on your user.php file.

    • Here’s a snippet from a recent project that pretty much does the same thing.

    <?php

    if( !$_POST || !$_POST['t'] ){ die("FORGOT TO SEND A TRANSACTION, DID YOU?"); }
    
    require_once('utils.php');
    
    // required variables
        $connection = db_server_connect();
        $transaction_id = get_hashsum($_POST['t']);
        $transaction = json_decode($_POST['t']);
    
    // get DB
        mysql_select_db(DB_NAME, $connection);
    
    // filter
        if(get_transaction($transaction_id)){ die("TRANSACTION ALREADY PROCESSED"); }
    
  2. This script will run silently (i.e., no HTTP output)

    • What you want is to return HTTP Status Code 204. It lets the browser know everything went well, but don’t expect any content back with this reply. Here’s an example of how I did mine:

    <?php

    // No Content Header
        header('HTTP/1.0 204 No Response', true, 204);
    
    // Don't Cache Server-Check
        header( 'Cache-Control: no-store, no-cache, must-revalidate' );
        header( 'Access-Control-Allow-Origin: *' ); 
        header( 'Pragma: no-cache' ); 
    

    ?>


Now there’s no need to create a custom WordPress template to handle this operation. It’s all being managed separately outside of the WordPress environment. To do the necessary save and update WordPress stuff, there’s a few guides on how to load up the WordPress environment externally. I think this one will help tons.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment