Creating basic PHP API endpoint

PHP API JSON

The modern web standard(s) is the era of APIs and microservices. This article is about a mini project to show how to create a PHP API endpoint which returns JSON data object. Thus backend and frontend can be separated firmly. For the backend we will check three rather different client implementations (C# console application, C# WPF application and VueJS application). We will only use and cover GET requests, so requesting data from the API.


Creating PHP backend

For running .php files we will need a webserver. For demo purposes a simple localhost is fine, for this I’d suggest Xampp or Wamp. After the webserver is running, we can create the .php file in the root or in a dedicated folder.

In the PHP backend we will need some sort of database, for this we will use a simple array which holds a few records, but if you want you can use your own database for that and fetch the records from there.

Creating JSON response

We simple get this array and returning it back (note: instead of using the return keyword, we simply echo it out) after we passing it through the json_encode function. That’s it, we are (almost) done with it! One additional step can be implemented: setting the header. This can be a nice touch to help identify that this response from the server is a JSON type. You can test the difference if you are using for example this JSON Formatter plugin in your browser. If this plugin is installed and enabled, then when you have a json header typed response it will automatically format is as json; otherwise (if you comment out the header section) you will only see the raw version of the echo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
    header('Content-Type: application/json');
    $database = array (
        array (
            "name" => "John Doe",
            "age" => 35,
            "job" => "Full-stack web developer",
            "salary" => 4000
        ),
        array (
            "name" => "Claudia",
            "age" => 22,
            "job" => "Frontend web designer",
            "salary" => 2000
        )
    );
    echo json_encode($database);
?>

Adding filter functions

Most APIs are not only returning back the full dataset, but they let us to have some filters used additionally. For example we can ask for all the users who are x years old. For this feature, we can add a GET parameter to the backend. Based on this logic, you can create as many filters as much you want or need to create.

This get parameter can be called from browser or from client code like this http://my_dummy_website.net/api.php?age=22. From the backend side we check for this filter value and selecting the valid items. (Note: using the right htaccess rule, you can get rid of the .php extension part, so if you see that …/api?age=22 it is basically the same.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
    // ... all the codes from previously
    if(isset($_GET['age']))
    {
        $filter = array();
        for ($i=0; $i < count($database); $i++)
            if($database[$i]["age"] == $_GET['age'])
                array_push($filter, $database[$i]);

        echo json_encode($filter);
    }
    else
        echo json_encode($database);
?>

Creating C# console app client

I think a simple and easy, yet powerful way for testing is a basic console application. It’s fast and lightweight for quick prototyping.

In the console application we will have the following classes (but removing the classes, simple methods could be enough if you prefer that way):

  • Person: representing the object, we will use it for parsing
  • DataFetcherService: the main logic to download the JSON content
  • Program: in the main function we call everything

DataFetcherService will be the key point, inside the FetchData method we will have a WebClient which we can use to get the data from the api endpoint, then with NewtonSoft’s json library we will parse the data to Person objects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Job { get; set; }
    public int Salary { get; set; }

    public override string ToString()
    { return $"{Name} - {Age} - {Job} - {Salary}"; }
}

class DataFetcherService
{
    public List<Person> FetchData()
    {
        string url = "https://siposm.hu/demo/api/endpoint.php";
        WebClient wc = new WebClient();
        string x = wc.DownloadString(url);
        return JsonConvert.DeserializeObject<List<Person>>(x);
    }

}

class Program
{
    static void Main(string[] args)
    {
        DataFetcherService dfs = new DataFetcherService();
        dfs.FetchData().ForEach(x => Console.WriteLine(x));
    }
}

Creating C# WPF app client

For the WPF project the same classes / methods can be used from above, nothing will change. Instead of writing out to the console, we will place the items into a listbox. (For this reason I don’t paste the code here.)

Creating the VueJS app client

For quick prototyping we will have a basic vue application, with index.html and vue.js files. In the html file, the important part is the two CDN sources around the bottom, one is for vue and the other is for axios (which will be used for fetching data from the API).

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue client app</title>
</head>
<body>
    <p><strong>! watch console to see full output !</strong></p>
    <hr>
    <h3>USERS:</h3>
    <div id="users"></div>
    <hr>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="vue.js"></script>
</body>
</html>

vue.js

In the javascript we create a new Vue instance, create a function which runs as the instance is created and that’s all, nothing else is needed. The forEach part can be left out totally, if you want to log to the console only. The other part creates paragraph elements inside the selected div with the name of each person/user.

1
2
3
4
5
6
7
8
9
10
11
12
13
new Vue({
    created: function () {
        axios.get('https://siposm.hu/demo/api/endpoint.php').then(response => {
                console.log(response.data)
                response.data.forEach(element => {
                    let newNode = document.createElement("p")
                    let textNode = document.createTextNode(element.name)
                    newNode.appendChild(textNode)
                    document.getElementById("users").appendChild(newNode)
                })
            })
    }
})

CORS problem in JavaScript

Using JS (on localhost or on a different server (than where the API endpoint is hosted)) CORS errors can occur. According to Wikipedia: “Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.”. At the moment our problem is simple: our localhost (where the vuejs is running) is under a different domain compared to the API endpoint. For this, there are options in the Vue framework which can solve this (proxies); but for now we will use a different approach: adjusting the .htaccess file on the webserver.

If there is no htaccess we can create and paste this line inside: Header set Access-Control-Allow-Origin "*"

Please note: this is not the best way to handle this, and not the most secure way neither! But in this article, it is fine.

Live API endpoint

You can use my endpoint here:

  • basic: https://siposm.hu/demo/api/endpoint.php
  • filtered for age: https://siposm.hu/demo/api/endpoint.php?age=X where X needs to be an integer (eg. 22 or 40)

Downloadables

  • you can download from: this link
  • or use CLI: git clone https://github.com/siposm/basic-php-api-endpoint.git