PHP RESTful Web Service API – Part 1 – Introduction with Step-by-step Example

by Vincy. Last modified on July 6th, 2022.

Part 1 of a three-part series to help you learn RESTful web services using PHP. These tutorials will be comprehensive, by following them through you can build your own web services easily and consume external services.

In this tutorial, we will see how to create a PHP RESTful web service without using any framework. Most of the time I do prefer to write custom code without depending on frameworks since this approach has a lot of advantages. Mainly, this will take you deeper in learning the concepts and you can keep things sleek and effective.

REST or Representational State Transfer is one of the popular architectural styles used to develop web services. This style of architecture contains constraints or rules to design web services that can be accessed from external apps or web applications.

The objective of this PHP RESTful web service example

The objective is to build a RESTful web service in PHP to provide resource data based on the request with the network call by the external clients. Also, the following list of steps is implemented while customizing this example without depending on any framework.

  • Create request URI with patterns that follow REST principles.
  • Make the RESTful service to be capable of responding to the requests in JSON, XML, and HTML formats.
  • Demonstrate the use of HTTP Status code based on different scenarios.
  • Demonstrate the use of Request Headers.
  • Test the RESTful web service using a REST client.

How it is made?

An array of mobile brand names are the resource data that will be targeted by the REST clients. I have this resource in a domain class of this PHP RESTful example.

For accessing these data via this web service, the client will send the request by setting URI, parameters with the selected method, and more information.

The resource handlers of the web service will prepare the response in JSON, XML or HTML format based on the request. Then, the response will be sent to the client.

On the Internet, I have seen web services tutorials and most of the time they all turn out to be error-prone or incomplete. I tested those RESTful services using a REST client and mostly they fail.

View Demo

What is inside?

  1. What is RESTful?
  2. RESTful web services vs RPC web services
  3. RESTful web services API architecture
  4. Uses of RESTful API
  5. PHP RESTful web service example
  6. File structure of RESTful example service
  7. RESTful services URI mapping
  8. UML sequence diagram for the example RESTful service
  9. RESTful web service controller
  10. A simple RESTful base class
  11. RESTful web service handler
  12. RESTful web service client
  13. RESTful Web Service Output

What is RESTful?

REST stands for Representational State Transfer and it is an architectural style that enables the communication between systems. The term REST was first coined by Roy T. Fielding in his PhD. dissertation.

The concept of REST is defined by certain rules, constraints or principles. The system, application, services or whatever satisfies these REST principles are called RESTful.

Web services that follow the RESTful principles are RESTful services. The URI is used to access RESTful services to get the resources.

In the RESTful glossary, the resources are nothing but the data and functions. So eventually we will call the web services via URI to access functions and thereby get the resource data.

REST Constraints

The following constraints define the RESTfulness of an application or service.

  • Client-Server architecture
  • Statelessness
  • Uniform interface
  • Layered system
  • Cacheability
  • Code on Demand

RESTful web services vs RPC web services

The following table shows the comparison of RESTful and RPC-style web services. This comparison is made by factors like service request URI, request methods, data transmission, service handlers and more.

RESTful-Style RPC-Style
Request URI The request URI will differ based on the resource. Same URI for all resources.
Request methods The service request parameters can be sent via GET, PUT, and POST request methods. Supports only the POST method.
Service methods or handlers Same method for all resources. Methods and parameters are posted on request.
Target on The service request using this style targets resources. The target is methods.
Response data transmission Over HTTP wrapped with the requested methods and parameters.

RESTful web services API architecture

The following diagram shows a RESTful web service architecture. In this diagram, the request-response flow among the client-server is represented.

In this diagram, the database is shown as a resource. Based on the web service the resource can be XML feed, JSON data extracted from the file system or any.

RESTful Web Services API Architecture

Uses of RESTful API

RESTful API provides services to access resources from external applications or REST clients. Some of the predominant uses of the RESTful API are listed below.

  • As an interface with multi-platform support which is used to access resources from outside applications coded in various programming languages like PHP, JAVA, Android and more.
  • REST is the simple architectural style for transmitting data over HTTP.
  • The REST API is the most suitable resource provider for an AJAX-based application interface which requires data to update UI without page reload.
  • By meeting more of the REST constraints, the web applications or services can support a wide range of clients.

PHP RESTful web service example

In the PHP RESTful web service example, the following domain class contains the resource data array and service handlers. These handlers are called based on the request sent by the REST client or external apps.

In the next section, we can see all the file structures and the purpose of each file of this example.

<?php

/*
 * A domain Class to demonstrate RESTful web services
 */
class Mobile
{

    private $mobiles = array(
        1 => 'Apple iPhone 6S',
        2 => 'Samsung Galaxy S6',
        3 => 'Apple iPhone 6S Plus',
        4 => 'LG G4',
        5 => 'Samsung Galaxy S6 edge',
        6 => 'OnePlus 2'
    );

    /*
     * you should hookup the DAO here
     */
    public function getAllMobile()
    {
        return $this->mobiles;
    }

    public function getMobile($id)
    {
        $mobile = array(
            $id => ($this->mobiles[$id]) ? $this->mobiles[$id] : $this->mobiles[1]
        );
        return $mobile;
    }
}
?>

The file structure of RESTful example service

The below file structure shows the simplicity of creating a RESTful web service example.

As discussed above Mobile.php is the domain class which is having resource array and handlers to get the resource.

PHP RESTful Web Service File Structure

The .htaccess file is used for mapping the request URI to the REST service endpoint.

In the following sections, we will see how the URI is mapped, and how the service handler is invoked to get resource data from the domain.  – URI RFC 3986

RESTful services URI mapping

Every resource is identified via a URI (Uniform Resource Identifier).

A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource.

RestController.php shown in the above file structure is the PHP endpoint to which the request is to be forwarded.

I provide two URIs for accessing this web service from external applications or REST clients in this example. One URI will be used to get the complete array of mobile names in a JSON format and the other is to get a particular mobile name based on the ident passed via the request URI.

URI Method Type Description
http://localhost/restexample/mobile/list/ GET JSON To get the list of mobile brand names in a JSON array.
http://localhost/restexample/mobile/list/{id}/ GET JSON To get a single mobile data array by ident passed via URL.

The following URIs are mapped to the real file via the .htaccess file.

URI to get the list of all mobiles:

http://localhost/restexample/mobile/list/

URI to get a particular mobile’s detail using its id:

In the below URI the number ‘2’ is the id of a mobile. The resource domain class can get the particular data with the reference of this id parameter.

http://localhost/restexample/mobile/list/2/

The below code, snippet shows the complete rules and URL mappings created for this PHP RESTful web service example in its .htaccess  file.

# Turn rewrite engine on
Options +FollowSymlinks
RewriteEngine on

# map neat URL to internal URL
RewriteRule ^mobile/list/$   RestController.php?view=all [nc,qsa]
RewriteRule ^mobile/list/([0-9]+)/$   RestController.php?view=single&id=$1 [nc,qsa]

RESTful web service controller

In the.htaccess file, we are forwarding all the requests to the RestController.php file.

While forwarding the request the parameters are sent to execute a required part of the REST controller. This parameter is the key named ‘view’.

The value of the key parameter can be either “all” or “single” based on the request URI.

Following is the RestController.php file that receives the request and gets the view parameter. Based on this parameter value, the appropriate control case will be executed.

In the controller cases, the request is dispatched to respective methods created in the REST handler class.

<?php
require_once ("MobileRestHandler.php");

$view = "";
if (isset($_GET["view"]))
    $view = $_GET["view"];
/*
 * controls the RESTful services
 * URL mapping
 */
switch ($view) {

    case "all":
        // to handle REST Url /mobile/list/
        $mobileRestHandler = new MobileRestHandler();
        $mobileRestHandler->getAllMobiles();
        break;

    case "single":
        // to handle REST Url /mobile/show/<id>/
        $mobileRestHandler = new MobileRestHandler();
        $mobileRestHandler->getMobile($_GET["id"]);
        break;

    case "":
        // 404 - not found;
        break;
}
?>

A simple RESTful base class

The following class has a couple of methods that can be commonly used for the RESTful service handlers.

The getHttpStatusMessage() method is used to get the HTTP status message to construct the response. It contains the HTTP status code and message mapping array.

By receiving the status code, it returns the appropriate header response message. If the invalid status code is passed to this function or no such code is found in the mapping array, then the “Invalid Server Error” will be returned in the response.

These methods can be commonly used in the base class of simple PHP RESTful web services.

<?php

/*
 * A simple RESTful web service base class
 * Use this as a template and build upon it
 */
class SimpleRest
{

    private $httpVersion = "HTTP/1.1";

    public function setHttpHeaders($contentType, $statusCode)
    {
        $statusMessage = $this->getHttpStatusMessage($statusCode);

        header($this->httpVersion . " " . $statusCode . " " . $statusMessage);
        header("Content-Type:" . $contentType);
    }

    public function getHttpStatusMessage($statusCode)
    {
        $httpStatus = array(
            100 => 'Continue',
            101 => 'Switching Protocols',
            200 => 'OK',
            201 => 'Created',
            202 => 'Accepted',
            203 => 'Non-Authoritative Information',
            204 => 'No Content',
            205 => 'Reset Content',
            206 => 'Partial Content',
            300 => 'Multiple Choices',
            301 => 'Moved Permanently',
            302 => 'Found',
            303 => 'See Other',
            304 => 'Not Modified',
            305 => 'Use Proxy',
            306 => '(Unused)',
            307 => 'Temporary Redirect',
            400 => 'Bad Request',
            401 => 'Unauthorized',
            402 => 'Payment Required',
            403 => 'Forbidden',
            404 => 'Not Found',
            405 => 'Method Not Allowed',
            406 => 'Not Acceptable',
            407 => 'Proxy Authentication Required',
            408 => 'Request Timeout',
            409 => 'Conflict',
            410 => 'Gone',
            411 => 'Length Required',
            412 => 'Precondition Failed',
            413 => 'Request Entity Too Large',
            414 => 'Request-URI Too Long',
            415 => 'Unsupported Media Type',
            416 => 'Requested Range Not Satisfiable',
            417 => 'Expectation Failed',
            500 => 'Internal Server Error',
            501 => 'Not Implemented',
            502 => 'Bad Gateway',
            503 => 'Service Unavailable',
            504 => 'Gateway Timeout',
            505 => 'HTTP Version Not Supported'
        );
        return ($httpStatus[$statusCode]) ? $httpStatus[$statusCode] : $httpStatus[500];
    }
}
?>

The RESTful web service handler

This is the service class of this PHP example that handles the REST request dispatched from the controller.

First, we have to decide about the response format in which the resource data has to be prepared. It is based on the request header parameters.

In the request header, the “Accept” parameter will have the specification about the response content format or type.

The protocol here is, that when the request is sent, it should set the Request header parameter “Accept” and send it. The values can be like “application/json” or “application/xml” or “text/html”.

Based on these values the response data will be ready by invoking appropriate methods encodeJson(), encodeXML(), encodeHTML() shown below.

Then, the status code has to be returned to the client with the response data. On success, the status code will be 200.

Similarly, there are different status codes available and they should be used accordingly to set the response header as we discussed in the above section.

<?php
require_once ("SimpleRest.php");
require_once ("Mobile.php");

class MobileRestHandler extends SimpleRest
{

    function getAllMobiles()
    {
        $mobile = new Mobile();
        $rawData = $mobile->getAllMobile();

        if (empty($rawData)) {
            $statusCode = 404;
            $rawData = array(
                'error' => 'No mobiles found!'
            );
        } else {
            $statusCode = 200;
        }

        $requestContentType = $_SERVER['HTTP_ACCEPT'];
        $this->setHttpHeaders($requestContentType, $statusCode);

        if (strpos($requestContentType, 'application/json') !== false) {
            $response = $this->encodeJson($rawData);
            echo $response;
        } else if (strpos($requestContentType, 'text/html') !== false) {
            $response = $this->encodeHtml($rawData);
            echo $response;
        } else if (strpos($requestContentType, 'application/xml') !== false) {
            $response = $this->encodeXml($rawData);
            echo $response;
        }
    }

    public function encodeHtml($responseData)
    {
        $htmlResponse = "<table border='1'>";
        foreach ($responseData as $key => $value) {
            $htmlResponse .= "<tr><td>" . $key . "</td><td>" . $value . "</td></tr>";
        }
        $htmlResponse .= "</table>";
        return $htmlResponse;
    }

    public function encodeJson($responseData)
    {
        $jsonResponse = json_encode($responseData);
        return $jsonResponse;
    }

    public function encodeXml($responseData)
    {
        // creating object of SimpleXMLElement
        $xml = new SimpleXMLElement('<?xml version="1.0"?><mobile></mobile>');
        foreach ($responseData as $key => $value) {
            $xml->addChild($key, $value);
        }
        return $xml->asXML();
    }

    public function getMobile($id)
    {
        $mobile = new Mobile();
        $rawData = $mobile->getMobile($id);

        if (empty($rawData)) {
            $statusCode = 404;
            $rawData = array(
                'error' => 'No mobiles found!'
            );
        } else {
            $statusCode = 200;
        }

        $requestContentType = $_SERVER['HTTP_ACCEPT'];
        $this->setHttpHeaders($requestContentType, $statusCode);

        if (strpos($requestContentType, 'application/json') !== false) {
            $response = $this->encodeJson($rawData);
            echo $response;
        } else if (strpos($requestContentType, 'text/html') !== false) {
            $response = $this->encodeHtml($rawData);
            echo $response;
        } else if (strpos($requestContentType, 'application/xml') !== false) {
            $response = $this->encodeXml($rawData);
            echo $response;
        }
    }
}
?>

RESTful web service client

There are various stand-alone REST clients available in the market. These client interfaces are used to test a RESTful web service.

The Advanced Rest Client extension can be added to the Chrome installed on your machine.

We can also write our own custom client to test a RESTful web service.

I used this Google Chrome extension REST client for testing this PHP RESTful web service example.

PHP RESTful web service output

The below screenshot shows how to call RESTful web service. In this screenshot, the circled sections highlight the request URI, the selected request method, Header’s Accept param, and more details.

By clicking the send button, the response will be returned from the PHP RESTful web service.

XML Response

I set the application/xml as the response type. So the resultant resource data is prepared in the requested format as shown in the response section of the below screenshot.

RESTful Web Service GET

PHP RESTful web service JSON response

RESTful-Web-Service-JSON-Output

Conclusion

In this three-part tutorial series on RESTful web services using PHP, you will learn the RESTful implementation in detail using this comprehensive material. This first part has given you a complete introduction to the concepts with step-by-step examples.

With the knowledge that you have acquired from this tutorial, about the rules and principles of RESTfulness, you can build a RESTful API easily. Though there are frameworks for developing RESTful API, it can be done by using plain core PHP which will be effective and provide good performance.

In the coming part, you will be seeing about all aspects of developing a CRUD RESTful web services API using PHP for an entity.

View DemoDownload

Comments to “PHP RESTful Web Service API – Part 1 – Introduction with Step-by-step Example”

Leave a Reply

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

↑ Back to Top

Share this page