February 07, 2019
Create a REST API in PHP
REST stands for REpresentational State Transfer. Which is only a stateless representation of information among different resources. Where as API stands for Application Programming Interface which is an interface that allows different platforms to communicate.
REST API in PHP is used to share information in a certain representation format using proper methods. Normally these interfaces use JSON format to exchange information. In this post we will be using our employees data which we have been using in previous posts. I will be using four basic and mostly used methods over http requests.
- GET - To get a single or multiple records
- POST - To add a new record
- PUT - To update a record
- DELELTE - To delete a single record
define.php
<?php define("DB_HOST", "DATABASE_HOST"); // Your database host define("DB_NAME", "DATABASE_NAME"); // Your database name define("DB_USER", "DATABASE_USERNAME"); // Username for database define("DB_PASSWORD", "DATABASE_PASSWORD"); // Password for database define("REST_TOKEN", "API_AUTHORIZATION_TOKEN"); // Authorization token ?>
abstraction.php
<?php // Disable error reporting error_reporting(0); include("define.php"); global $dbcon; // Open database connection $dbcon = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) OR die(mysqli_connect_error()); /************************************** * Function to fetch records from table, * $param = "SELECT * FROM TABLE_NAME" **************************************/ function db_get($query){ global $dbcon; $rs = mysqli_query($dbcon,$query); if($rs){ $result = mysqli_fetch_all($rs,MYSQLI_ASSOC); }else{ $result = mysqli_error($dbcon); } return $result; } /************************************** * Function to add record to database table, * $table = table name * $data = Associative array of key/value (record name / record value) **************************************/ function db_insert($table,$data){ global $dbcon; $keys = array_keys($data); // Escaping values before insert $values = array_map(function($value){ global $dbcon; return mysqli_real_escape_string($dbcon,$value); },array_values($data)); $query = "INSERT INTO $table (".implode(",",$keys).") VALUES ('".implode("','",$values)."')"; $rs = mysqli_query($dbcon,$query); if($rs){ $result = mysqli_insert_id($dbcon); }else{ $result = mysqli_error($dbcon); } return $result; } /************************************** * Function to update record in database table, * $table = table name * $data = Associative array of key/value (record name / record value) * $where = String i.e employee_id = '1' **************************************/ function db_update($table,$data,$where = ''){ global $dbcon; $bind = []; foreach($data as $key => $value){ $value = mysqli_real_escape_string($dbcon,$value); $bind[] = "$key = '$value'"; } $query = "UPDATE $table SET ".implode(', ',$bind)." WHERE $where"; $rs = mysqli_query($dbcon,$query); if($rs){ $result = true; }else{ $result = mysqli_error($dbcon); } return $result; } /************************************** * Function to delete record from database table, * $table = table name * $where = String i.e employee_id = '1' **************************************/ function db_delete($table,$where){ global $dbcon; $query = "DELETE FROM $table WHERE $where"; $rs = mysqli_query($dbcon,$query); if($rs){ $result = true; }else{ $result = mysqli_error($dbcon); } return $result; } ?>
api.php
<?php include("abstraction.php"); // SET application hearder, allowed methods & headers header("Content-Type: application/json; charset=UTF-8"); header("Access-Control-Allow-Methods: GET,POST,PUT,DELETE"); header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With"); header("Cache-Control: no-cache,no-store,must-revalidate"); header("Pragma: no-cache"); // Get all request headers & and lower case header keys to handle case sensitivity $request_headers = array_change_key_case(getallheaders(), CASE_LOWER); // Set initial response code to current code $reponse_code = http_response_code(); // Check if request contains authorization token if(!isset($request_headers["authorization"]) || ($request_headers["authorization"] !== REST_TOKEN)){ $res = ["success" => 0, "message" => "Unauthorized request"]; http_response_code(401); die(json_encode($res)); } // Check if request contains proper content type if(!isset($request_headers["content-type"]) || (($request_headers["content-type"] !== "application/x-www-form-urlencoded") && ($request_headers["content-type"] !== "application/json"))) { $res = ["success" => 0, "message" => "Set content-type to applicaton/x-www-form-urlencoded or applicaton/json"]; http_response_code(400); die(json_encode($res)); } // Get the method used to call API $request_method = $_SERVER['REQUEST_METHOD']; // Raw input received in request $input_raw = file_get_contents("php://input"); // Prepare input for both json/x-www-form-urlencoded $input_json = json_decode($input_raw,true); // Decode input to json parse_str($input_raw,$input_arr); // Parse x-www-form-urlencoded to arrays if(is_array($input_json)){ // If input was json set this input to be used in script $input = $input_json; }elseif(is_array($input_arr)){ // If input was x-www-form-urlencoded set this input to be used in script $input = $input_arr; } switch($request_method){ case "GET": $where = "WHERE 1=1"; // If employee id was passed , Fetch record against that id only if(intval($_GET['employee_id'])){ $where .= " AND employee_id = '".intval($_GET['employee_id'])."'"; } $employees = db_get("SELECT employee_id,fullname,gender,email,designation FROM employees $where"); $total = count($employees); // Set json response after getting employee record(s) $res = ["suceess" => 1, "data" => $employees, "total" => $total]; $reponse_code = 400; break; case "POST": // Set json response if fullname & email was empty if(empty($input["fullname"]) && empty($input["email"])){ $res = ["success" => 0, "message" => "Employee name and email can not be empty"]; $reponse_code = 400; break; } $data = []; $data["fullname"] = $input["fullname"]; $data["email"] = $input["email"]; $data["gender"] = $input["gender"]; $data["designation"]= $input["designation"]; db_insert("employees", $data); // Return json response after adding employee $res = ["success" => 1, "message" => "Employee has been added"]; $reponse_code = 200; break; case "PUT": // Set json response if no employee id was provided to update against if(!isset($_GET["employee_id"])){ $res = ["success" => 0, "message" => "Missing parameter employee_id"]; $reponse_code = 400; break; } // Set json response if fullname or email was provided empty if(empty($input["fullname"]) || empty($input["email"])) { $res = ["success" => 0, "message" => "Employee name and email can not be empty"]; $reponse_code = 400; break; } $where = "employee_id = '".intval($_GET["employee_id"])."'"; $data["fullname"] = $input["fullname"]; $data["email"] = $input["email"]; $data["gender"] = $input["gender"]; $data["designation"]= $input["designation"]; db_update("employees",$data,$where); // Set json response after updating employee $res = ["success" => 1, "message" => "Employee has been updated"]; $reponse_code = 200; break; case "DELETE": // Set json response if no employee id was provided to delete record against if(!isset($input["employee_id"])){ $res = ["success" => 0, "message" => "Missing parameter employee_id"]; $reponse_code = 400; break; } $where = "employee_id = '".intval($input["employee_id"])."'"; db_delete("employees",$where); // Set json response after deleting employee $res = ["success" => 1, "message" => "Employee has been deleted"]; $reponse_code = 200; break; default: // If requested method was other than GET,POST,PUT,DELETE, return an error message $res = ["success" => 0, "message" => "Invalid request"]; $reponse_code = 400; break; } // Set response status code http_response_code($reponse_code); // Return final json response echo json_encode($res); ?>Now that everything is ready to use our API lets play with .htaccess to write pretty URLs.
DirectoryIndex api.php RewriteEngine On ## Replace Rewritebase to directory where you place downloaded files RewriteBase /create-rest-api-in-php/ RewriteRule ^api/([\d]+) api.php?employee_id=$1 [L] RewriteRule ^api/? api.php [L]This will change our url as http://yourdomain.com/apifolder/api. Now open up postman and try all methods one by one. Responses should match as in screenshots below:
- GET / All Records
- GET / Single Record
- POST / Add New Record