Introduction to writing a REST server in PHP

This article is the second in my SOAP and REST API series, following on from my SOAP vs. REST API Implementation article and will fill in some more of the details around implementing a REST server in PHP.

This article is intended to give a basic introduction and a guide to push you in the right direction with your REST server implementation. As such, the examples used in this article are somewhat abstracted from real world uses. If there is demand for it I will write a much more in-depth “ultimate” REST server implementation article at a later date.

If you’re not familiar with the concept of REST, before we move on I’d suggest that you get up to speed with a bit of background reading. Some possible sources are:

Getting started
This should really go without saying but I’ll say it anyway. Before hitting the code to implement a REST server you should work out a few things about what you’re implementing:

  1. Make a list of ALL of your API methods.
  2. Work out which request methods (GET, POST, PUT and DELETE) the methods are used with – It is possible that they will be used with more than one request method.
  3. Work out your URL scheme for the API. What URL maps to what API method?

To keep things simple in this article we will be working with 4 methods. One for each request method listed above. Let’s call them:

  1. my_get
  2. my_post
  3. my_put
  4. my_delete

It is quite obvious which API method ties in with each request method so I won’t go into that. Each of the methods will be mapped to a URL of the same name. For example my_get will be mapped to http://www.mydomain.com/rest/my-get, my_post will be mapped to http://www.mydomain.com/rest/my-post and so forth.

Setting up the “server”
In a real world implementation I would suggest setting up a REST server class that handles all of the method/url mapping, request/response headers, data manipulation, errors etc. In fact, I’ve actually got such a class that is just about ready for release.

For this article I’m staying right away from any such class in order to keep the examples simple. So our REST server will look something like this:

<?php

function RESTServer() {
    // find the function/method to call
    $callback = NULL;
    if (preg_match('/rest\/([^\/]+)/', $_SERVER['REQUEST_URI'], $m)) {
        if (isset($GLOBALS['RESTmap'][$_SERVER['REQUEST_METHOD']][$m[1]])) {
            $callback = $GLOBALS['RESTmap'][$_SERVER['REQUEST_METHOD']][$m[1]];
        }
    }

    if (is_callable($callback)) {
        // get the request data
        $data = NULL;
        if ($_SERVER['REQUEST_METHOD'] == 'GET') {
            $data = $_GET;
        } else if ($tmp = file_get_contents('php://input')) {
            $data = json_decode($tmp);
        }

        // execute the function/method and return the results
        header("{$_SERVER['SERVER_PROTOCOL']} 200 OK");
        header('Content-Type: text/plain');
        print json_encode(call_user_func($callback, $data));
    } else {
        header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found");
        // print 404 page here
        exit;
    }
}

So there’s 3 main parts to this function. The first section checks if there’s a function for the current request method and URI in the map of functions. The second section gets the current request data and the third section executes the matching function/method.

I’ve made the executive decision that all data (both request and response) will be in JSON format because the encoding and decoding functions are readily available in PHP. The function above handles the encoding and decoding of data using json_encode and json_decode.

Plugging in our 4 functions
In the RESTServer function above, the code looks for the appropriate function/method to call in the RESTmap global variable. So to map the URLs we defined above to the appropriate functions we need to add them to this variable.

Note: this assumes you have already configured your web server to rewrite the URL’s appropriately. For more information on this see the examples in SOAP vs. REST API Implementation and URL rewriting with Apache and PHP.

Our 4 functions:

<?php

function my_get() { }
function my_post() { }
function my_put() { }
function my_delete() { }

And adding them to the RESTmap:

<?php

$GLOBALS['RESTmap'] = array();
$GLOBALS['RESTmap']['GET'] = array('my-get' => 'my_get');
$GLOBALS['RESTmap']['POST'] = array('my-post' => 'my_post');
$GLOBALS['RESTmap']['PUT'] = array('my-put' => 'my_post');
$GLOBALS['RESTmap']['DELETE'] = array('my-delete' => 'my_delete');

A few notes

  • The data for GET request method is handled differently. This is because data for the GET method will ALWAYS be sent through in the query string (e.g. tacked on to the end of the URL)
  • The PUT request method is generally disabled in Apache by default. If it is disabled for you, you will need to enable it either in the Apache configuration or in a .htaccess file (See SOAP vs. REST API Implementation).
  • You will notice that the my_put and my_post functions both map to the my-post URL. This is simply to show that you can have various request methods using the same URL.

Putting it all together
As I mentioned before, this is not necessarily the best way to go in a real world implementation. This article just shows the various components involved in setting up an API. Hopefully it will be useful to anyone needing somewhere to start.

If you thought this article was too simple, too complex, too long, too short or otherwise I would love to hear your thoughts. Please leave comments and feedback. If you’re interested in reading a more thorough implementation article please let me know. Also, as I mentioned above we will be releasing a REST server library some time in the future so keep an eye out for that.

  • Many things can be taken away from this - and certainly much of which is only to the edification of the vast majority who accept what is offered with an open heart and mind.  

  • Its a wonderful time being in ur blog to learn something useful and even helpful.

  • Thanks for sharing your ideas and thoughts, i like your blog and bookmark this blog for further use thanks again.

  • Thanks for sharing such an informative post. Its really helpful to me..

  • Great informative post and i really likes your information, most of the peoples are likes your blog because its having the good knowledge. thanks for your good informative post

blog comments powered by Disqus