REST API – A Simple PHP Tutorial

A REST API allows your users to interact with your website from anything that can send an HTTP request. The Twitter feed displayed on the right side of this blog is using a REST API from twitter. It allows me to pull my latest tweets and display them.

REST-style architectures consist of clients and servers. Clients initiate requests to servers; servers process requests and return appropriate responses. Requests and responses are built around the transfer of representations of resources. Requests utilize HTTP verbs (GET, POST, PUT, DELETE, etc.) which are used to manage the state of resources. The responses can be sent as XML or JSON. Since REST uses HTTP, it can be used practically for any programming language and is easy to test.

There’s more to REST like constraints and best practices which I wont get into. For more information I recommend you visit http://www.restapitutorial.com.

PHP Example

I’m going to attempt to explain how to create a REST API in the simplest way I can. First thing I’ll do is create the API which I’ll call api.php.

<?php
// This is the API, 2 possibilities: show the app list or show a specific app by id.
// This would normally be pulled from a database but for demo purposes, I will be hardcoding the return values.

function get_app_by_id($id)
{
  $app_info = array();

  // normally this info would be pulled from a database.
  // build JSON array.
  switch ($id){
    case 1:
      $app_info = array("app_name" => "Web Demo", "app_price" => "Free", "app_version" => "2.0"); 
      break;
    case 2:
      $app_info = array("app_name" => "Audio Countdown", "app_price" => "Free", "app_version" => "1.1");
      break;
    case 3:
      $app_info = array("app_name" => "The Tab Key", "app_price" => "Free", "app_version" => "1.2");
      break;
    case 4:
      $app_info = array("app_name" => "Music Sleep Timer", "app_price" => "Free", "app_version" => "1.9");
      break;
  }

  return $app_info;
}

function get_app_list()
{
  //normally this info would be pulled from a database.
  //build JSON array
  $app_list = array(array("id" => 1, "name" => "Web Demo"), array("id" => 2, "name" => "Audio Countdown"), array("id" => 3, "name" => "The Tab Key"), array("id" => 4, "name" => "Music Sleep Timer")); 

  return $app_list;
}

$possible_url = array("get_app_list", "get_app");

$value = "An error has occurred";

if (isset($_GET["action"]) && in_array($_GET["action"], $possible_url))
{
  switch ($_GET["action"])
    {
      case "get_app_list":
        $value = get_app_list();
        break;
      case "get_app":
        if (isset($_GET["id"]))
          $value = get_app_by_id($_GET["id"]);
        else
          $value = "Missing argument";
        break;
    }
}

//return JSON array
exit(json_encode($value));
?>

The API has two functions: get_app_by_id() and get_app_list(). get_app_by_id() expects an additional parameter called id to return the app info while get_app_list() returns a array of apps. The API requires an action parameter to determine which function to call. Requests made to this API utilize the GET HTTP verb and all responses are returned using JSON. In the real world, your API would most likely return data from a database. For this example the return data is hardcoded into the page.

Next I’ll create the client page that will be using the API.

<html>
 <body>

<?php
if (isset($_GET["action"]) && isset($_GET["id"]) && $_GET["action"] == "get_app") 
{
  $app_info = file_get_contents('http://{Your Website}/api.php?action=get_app&id=' . $_GET["id"]);
  $app_info = json_decode($app_info, true);
  ?>
    <table>
      <tr>
        <td>App Name: </td><td> <?php echo $app_info["app_name"] ?></td>
      </tr>
      <tr>
        <td>Price: </td><td> <?php echo $app_info["app_price"] ?></td>
      </tr>
      <tr>
        <td>Version: </td><td> <?php echo $app_info["app_version"] ?></td>
      </tr>
    </table>
    <br />
    <a href="http://{Your Website}/REST_Client.php?action=get_app_list" alt="app list">Return to the app list</a>
  <?php
}
else // else take the app list
{
  $app_list = file_get_contents('http://{Your Website}/api.php?action=get_app_list');
  $app_list = json_decode($app_list, true);
  ?>
    <ul>
    <?php foreach ($app_list as $app): ?>
      <li>
        <a href=<?php echo "http://{Your Website}/REST_Client.php?action=get_app&id=" . $app["id"]  ?> alt=<?php echo "app_" . $app_["id"] ?>><?php echo $app["name"] ?></a>
    </li>
    <?php endforeach; ?>
    </ul>
  <?php
} ?>
 </body>
</html>

As you can see, to use the API you’d simply send an HTTP request like so: http://{Your Website}/api.php?action=get_app_list. This URL would call the get_app_list() and return data in JSON. PHP has a useful json_decode() function that takes a JSON encoded string and converts it into a PHP variable. You can then loop through your variable to display the data.

This is the simplest way to create and use a REST API. You can view a live demo of this at http://demos.ijasoneverett.com/REST_Client.php.

57 thoughts on “REST API – A Simple PHP Tutorial

  1. Pingback: A RESTful Client with Angular.js | Dev Notes

  2. This is no REST-API – or at least it is badly designed. In REST each URI describes a resource. You retrieve it with the HTTP-Verb GET and e.g. delete it with – *surprise* – DELETE. You, on the other hand, specify the action as well as the resource in the QueryString which is, as mentioned, a bad design. Good would be for example: http://{Your Website}/api/apps and http://{Your Website}/api/apps/{id} for a single app
    And if you would like to add a new app you can just POST to the same URI – this verb isn’t idempodent so it is perfectly valid to simply add a new item to the collection…

    • Yes, the URL design is bad but the purpose of the article was to explain REST as simple as possible. There’s a link with best practices that shows proper URL examples.

    • You’re right about the actions and the correct working of REST API.
      Could you share a bit of code that does what you said?

  3. Hi, thanks for simple tutorial. But you have probably a mistake into row :

    <a href= alt=>

    Shouldn’t be there $app[“id”] variable without _ ?

  4. Hi, Can anyone help me? Please? Something is wrong running this sample on my computer. I have a server on my LAN at an fixed IP address. Ok I replace {Your Website} with my server IP address. Ok I replace “REST_Client” with “api” 🙂 and my browser shows me this:
    App Name:
    Price:
    Version:

    Return to the app list
    alt=>

    and nothing seems to work. What am I doing wrong?
    Thanks in advance. (From Barinas-Venezuela)

  5. Very nice tutorial, although I’m sure the boring REST purists will nitpick it to death.
    But then, when is the last time you learned ANYTHING from a purist?
    DS

  6. Hi!
    You mentioned “normally this info would be pulled from a database” in your codes above. Could you please show examples of how do I actually extract information from my remote server database instead of hardcoding? I’ve tried several examples but failed. Can anyone help? Thanks!

    • Thank you for your reply! Appreciate if it can be up as soon as possible as I’m really stuck for my project I’m currently working on. 🙁 Please notify me to the link here so that I can refer. Many thanks!

    • THIS IS HOW I RE-WROTE THE SCRIPT:

      /*DB settings*/
      define(‘MYSQL_HOST’, ‘hostnameE.G localhost’);
      define(‘MYSQL_USER’, ‘YourDbUserName’);
      define(‘MYSQL_PASS’, ”);
      define(‘MYSQL_DATABASE’, ‘YourDbName’);
      $results=array();
      $result=array();
      function get_app_by_id($id)
      {
      $sql = “SELECT * from table where id=$id”;
      try {
      $dbh = new PDO(“mysql:host=”.MYSQL_HOST.”;dbname=”.MYSQL_DATABASE.”;charset=utf8″, MYSQL_USER, MYSQL_PASS);
      $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $stmt = $dbh->query($sql);
      $result = $stmt->fetchAll(PDO::FETCH_OBJ);
      $dbh = null;
      } catch(PDOException $e) {
      }

      $app_info = $result;
      return $app_info;
      }

      function get_app_list()
      {
      $sql = “SELECT * FROM table”;
      try {
      $dbh = new PDO(“mysql:host=”.MYSQL_HOST.”;dbname=”.MYSQL_DATABASE.”;charset=utf8″, MYSQL_USER, MYSQL_PASS);
      $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $stmt = $dbh->query($sql);
      $results = $stmt->fetchAll(PDO::FETCH_OBJ);
      $dbh = null;
      } catch(PDOException $e) {
      }
      $app_list = $results;
      return $app_list;
      }

  7. Thank you very much, this was easy to understand. I was able to modify it so I could get infomation from my database on one urls to my client application.

    Unfortunately, any one going to my site and running the server file can also get the information. My next challenge is to keep it so others can not use the server-side api. Any thoughts on how to implement this.

  8. Very useful, thank you. I wrote a JavaScript/html version of the client that I will try to include in this comment.

    $(function() {
    /*
    A simple example of a RESTful client.

    Calls local webservice “api.php” and then lists JSON response from “api.php”.
    API’s:
    “action=get_app_list”
    “action=get_app&id=n” (1 <= n

    Modelled after:
    http://blog.ijasoneverett.com/2013/02/rest-api-a-simple-php-tutorial/
    */

    var query = window.location.search.substr(1);
    var thisScript = window.location.href.replace(“?”+query, ”);
    var service = “http://localhost/{Your Path}/api.php”;

    if (query.length === 0 ) { // Default
    var query = “action=get_app_list”;
    }

    if (query.indexOf(“get_app_list”) > 0) {
    $.getJSON(service, query, listAllApps);
    }
    else if (query.indexOf(“get_app&id=”) > 0) {
    $.getJSON(service, query, listOneApp);
    }
    else {
    alert(“Incorrect query string”);
    throw new Error(“Incorrect query string”);
    }

    function listOneApp(data) {
    /*
    Callback function. Lists JSON response
    */
    var str = “”;
    str += ” App Name: ” + “” + data.app_name + “”;
    str += ” Price: ” + “” + data.app_price + “”;
    str += ” Version: ” + “” + data.app_version + “”;
    str += “”;
    str += “”;
    str += “” +
    “Return to the app list
    “;
    $(“#here”).html(str);
    }

    function listAllApps(data) {
    /*
    Callback function. Lists JSON response
    */
    var str = “”;
    for (key in data) {
    str += “” +
    ” + data[key].name + “”;
    }
    str += “”;
    $(“#here”).html(str);
    }
    });

    • When I open the html file “REST_Client.html” (containing the JavaScript/jQuery above) in Firefox, it opens with the “file://” protocol as:
      file:///C:/xampp/htdocs/{myPath}/REST_Client.html
      The JavaScript opens in the call “$.getJSON(…)” the file:
      http://localhost/{myPath}/api.php
      (I have locally XAMPP/Apache installed that recognizes this).
      Firefox sees the protocols “file://” and “http://” as different origins and refuses to open api.php for security reasons. However, when I add
      header(‘Access-Control-Allow-Origin: *’);
      to the top of api.php (before any output) , then the cross-origin violation is resolved.
      I hope this remark is helpful.

      • One more thing: the jQuery/JavaScript that I posted here on March 28, 2015 was embedded in html. It contained:

        [body] [div id=”here”][/div][/body]

        (Replace square brackets by angular brackets).

  9. Tutorial is good but I think, This is not rest API , this is just Json-RPC.
    Please describe how to use Rest methods.

  10. This is not a RESTful api. Actions are represented by http verbs. Also a rest api uses Hypermedia As the Engine Of Application State (HATEOAS). As far as im aware that is basically one of the main characteristics of a rest api. Otherwise, nice simple code. But very misleading.

  11. i need to create a a form in my wesitethat use api to give the possibility who buy an our sub account to create it self.. i have seen the script api jason:
    {
    “authentication”: {
    “apiKey”: “apiKeyAsSetInAccountSettings”
    },
    “createAccount”: [
    {
    “username”: “username”,
    “password”: “password”,
    “apiKey”: “YourKeyToUseForTheNewAccount”,
    “email”: “[email protected]”,
    “role”: “0”
    }
    ]
    }
    but this maybe create an account i need to create a sub account because we are a reseller .
    can you say me if is possible and how i combine this script to put in a form?

    to submit at this form in this url
    https://office.bookinguide.cloud/api/json/createAccount
    anyone can help me please?

  12. i need to create a a form in my website that connect with this url api : https://api.beds24.com/json/createAccount to give the possibility who buy an our sub account to create it self.. i have seen the script api jason: {
    “authentication”: {
    “apiKey”: “apiKeyAsSetInAccountSettings”
    },
    “createAccount”: [
    {
    “username”: “username”,
    “password”: “password”,
    “apiKey”: “YourKeyToUseForTheNewAccount”,
    “email”: “[email protected]”,
    “role”: “0”
    }
    ]
    }
    There is a sample PHP script here to modify property details: https://api.beds24.com/json/modifyProperty
    It could be modified to work with the createAccount function and my form.

  13. i need to create a form in my web page where the custmer nedd to add 4 element:
    username”: “username”,
    “password”: “password”,
    “apiKey”: “YourKeyToUseForTheNewAccount”,
    “email”: “[email protected]”,

    “role”: “0”

    the role is standard for hall and must be hide from the form
    so also my api key for example
    “authentication”: {
    “apiKey”: “apiKeyAsSetInAccountSettings”

    this code in the form need to point to this page https://office.bookinguide.cloud/api/json/createAccount

    and retur in other url wit the eco of the new value

    this i an action new sub account

    here the complete script jason
    {
    “authentication”: {
    “apiKey”: “apiKeyAsSetInAccountSettings”
    },
    “createAccount”: [
    {
    “username”: “username”,
    “password”: “password”,
    “apiKey”: “YourKeyToUseForTheNewAccount”,
    “email”: “[email protected]”,
    “role”: “0”
    }
    ]
    }

  14. I upload api.php and client.php on a web server at the same directory, and open the client.php with Google Chrome. Nothing happen. total blank. Did I miss something ??

  15. $url=”http://www.thomas-bayer.com/sqlrest/CUSTOMER/”;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL,$url);
    $result=curl_exec($ch);
    curl_close($ch);
    var_dump($result);

    function get_details($url){
    ob_start();
    $process = curl_init($url);
    curl_setopt($process, CURLOPT_USERPWD, “user:password”);
    curl_setopt($process, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
    $response = curl_exec($process);
    curl_close($process);
    $data = json_decode(ob_get_contents());
    ob_end_clean();
    return $data;
    }

  16. get_details(\’http://192.168.0.240/ANGLERCRM/api/data/v8.0/systemusers(\’.$Account_owner1.\’)?$select=internalemailaddress\’);

  17. Super-great article, even if it’s 4 years old! Still it’s one of the simplest, most to-the-point examples out there of building your own API. I used the main ideas herein to build out a simple API in a Joomla! context & it all worked great. Basically, if you can code, this all makes a lot of sense and can be easily built upon. 🙂 Just wanted to leave a positive note after reading some of the ridiculous nitpickery in these comments.

  18. Great Post man. Thank you for giving us a way forward as Jim Dee mentioned.

    Question: How would one enforce authentication on this?

Leave a Reply

Your email address will not be published. Required fields are marked *

Please Do the Math      
 

*