REST API in PHP


Starting the PHP REST API

I will start creating the REST API by first creating our file lets call it:

testing.php

Setting up the database

I will be using MySQL to hold my data that can be queried throught he API so here is the setup for it on the PHP page:

//defining the variables needed to access the MySQL database
define('DB_USER', 'packet');
define('DB_PASS', 'packet-password');
define('DB_HOST', 'localhost');
define('DB_NAME', 'packet-database');

//creating the database connection
$pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS);

Creating a SQL query

I want the API to query some data (a user's email) from my SQL database so I will need to setup a function to trigger an SQL query:

$payload_username = "username";

//query function
function queryData($payload_username) {
  global $pdo;
  $stmt = $pdo->prepare("SELECT email FROM users WHERE username = :username");
  $stmt->bindParam("username", $payload_username);
  $stmt->execute();
  return $stmt->fetch();
}

Grabbing JSON data & Triggering a SQL query function

I want to grab any JSON data sent to the REST API to then use it to do my SQL query function, so I will first need to grab any data being received:

//grab received data
$payload = file_get_contents('php://input');

However the data I wanted to be grabbed was going to be sent in the JSON format so I will need to decode it so I can use the data from it.

//grab received data & decode the json data
$payload = json_decode(file_get_contents('php://input'),1);
//get the json value from the username key
$payload_username = $payload[username];

//query function
function queryData($payload_username) {
  global $pdo;
  $stmt = $pdo->prepare("SELECT email FROM users WHERE username = :username");
  $stmt->bindParam("username", $payload_username);
  $stmt->execute();
  return $stmt->fetch();
}

//triggering function
$query = queryData($payload_username);

Securing the REST API:

I want to secure it by having an API key so only authenticated people can use the API. So I want the authentication to be done by a header called Authorization so I will be grabbing all the headers being received by the API and search for the API key.

//grabbed all headers
$headers = apache_request_headers();
//get api key header
$api = $headers['Authorization'];

Now that we can see the API key we have to verify if it's valid or not.

//query function
function checkApiKey($api) {
    global $pdo;
    $stmt = $pdo->prepare("SELECT api_key FROM api_access WHERE api_key = :api");
    $stmt->bindParam("api", $api);
    $stmt->execute();
    return $stmt->fetch();
}

//trigger function
$api_check = checkApiKey($api);

//if provided api key is present in the database then var = True else it's False
if ($api_check == api){
  $key_valid = True
}
else {
  $key_valid = False
}

As we can now see if the API key used is valid or not when doing an API request, we can only trigger the function when its valid.

if ($key_valid = True) {
  //run function only when api key is valid
  $query = queryData($payload_username);
  //form the output message
  $json_data = array("status" => "200", "query" => $query);
  //output the array as a json
  print_r(json_encode($json_data));

}
else {
  //api key used is invalid message
  $json_data = array("status" => "200", "message" => "The API key used is invalid.");
  //output the array as a json 
  print_r(json_encode($json_data));
}

Output HTTP Header

I want the output to be JSON data so the sending header should be the following:

header("Content-Type: application/json; charset=UTF-8");

The Content-Type is quite important for telling the requesting user/client the content type of the returned data. You can read more about it in here:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type

Full code

The full code of the page should look similar to this:

//defining the variables needed to access the MySQL database
define('DB_USER', 'packet');
define('DB_PASS', 'packet-password');
define('DB_HOST', 'localhost');
define('DB_NAME', 'packet-database');
//creating the database connection
$pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS);

//grabbed all headers
$headers = apache_request_headers();
//output header specifying content-type
header("Content-Type: application/json; charset=UTF-8");
//get api key header
$api = $headers['Authorization'];

//grab received data & decode the json data
$payload = json_decode(file_get_contents('php://input'),1);
//get the json value from the username key
$payload_username = $payload[username];

//query function
function queryData($payload_username) {
  global $pdo;
  $stmt = $pdo->prepare("SELECT email FROM users WHERE username = :username");
  $stmt->bindParam("username", $payload_username);
  $stmt->execute();
  return $stmt->fetch();
}

//triggering function
$query = queryData($payload_username);

//query function
function checkApiKey($api) {
    global $pdo;
    $stmt = $pdo->prepare("SELECT api_key FROM api_access WHERE api_key = :api");
    $stmt->bindParam("api", $api);
    $stmt->execute();
    return $stmt->fetch();
}

//trigger function
$api_check = checkApiKey($api);

//if provided api key is present in the database then var = True else it's False
if ($api_check == api){
  $key_valid = True
}
else {
  $key_valid = False
}

if ($key_valid = True) {
  //run function only when api key is valid
  $query = queryData($payload_username);
  //form the output message
  $json_data = array("status" => "200", "query" => $query);
  //output the array as a json
  print_r(json_encode($json_data));

}
else {
  //api key used is invalid message
  $json_data = array("status" => "200", "message" => "The API key used is invalid.");
  //output the array as a json 
  print_r(json_encode($json_data));
}

Last updated: February 14, 2022