Hi everyone, here is a PHP Rest API Example for you all. From this post we will learn using PHP and MySQL for our iOS Application’s Back End.
If you think backend as your database only then it is not the case here. For a mobile application we need a server where we store and manage all the data. And for doing this we create a Backend Server.
You may find some application that do not require a backend server but many apps do require a backend. For example an eCommerce App, we store all the products information in the database residing in our server, and from there our app fetches everything.
For building a backend server, you can choose any technology like Ruby Rails, Python, Java, NodeJS, PHP. But in this post we are going to use PHP with MySQL.
Contents
What is REST API?
The term “REST API” consists of two words, REST and API. To understand REST API you need to understand what is REST and what is API first.
REST
REST stands for REpresentational State Transfer. It is an architectural style, that gives an standard of communication between systems.
A REST Compliant System, is also called RESTful system. REST is language independent and we can develop RESTful services using any language like Java, Python, PHP etc.
REST works on HTTP (Hyper Text Transfer Protocol) protocol.
API
API stands for Application Programming Interface. And we can say that API is a set of operations that developers can use.
API is used for communicating between different applications. For example we can integrate Facebook Login in our application then our application is communicating with facebook to fetch the user data, and it happens using API that facebook provides. So basically facebook provides a method that developer uses to integrate facebook login in application.
RESTful API
Our final term, REST API or RESTful API is an API that works on HTTP protocol (GET, POST, PUT, DELETE). In iOS Development, we create RESTful API or it is also called Web Services for communicating with our backend server. Our backend server has a set of method to perform many operations that we call using HTTP request.
In this post we will not get into the theoretical stuffs related to REST API, but we will directly create a RESTful API for our iOS Application.
Pre-Requisites
Before moving ahead make sure you have the following tools that we are going to use for this tutorial.
- XAMPP Server
- Visual Studio Code
Other than the above mentioned tools, we will use SLIM Framework to build our API.
PHP Rest API Example : Video Series
I have also published a complete video series that will explain every step of building this API. You can go through this PlayList as well to understand the things more easily.
PHP Rest API Example
Now let’s start building our REST API and then in the next post we will learn how we can consume these APIs in our iOS Application.
Creating Database
The first thing that we need is a database. Below is the model of our database that we are going to use for this example.
To create the above database go to localhost/PhpMyAdmin and run the below given query.
CREATE TABLE users ( id int NOT NULL AUTO_INCREMENT, email varchar(200) NOT NULL, password text NOT NULL, name varchar(500) NOT NULL, school varchar(1000) NOT NULL, CONSTRAINT users_pk PRIMARY KEY (id) );
Creating a SLIM Project
To create a SLIM Project we need to install composer in our system. You can follow these steps to install composer.
- Go inside htdocs directory in terminal and run the following command.
composer create-project slim/slim-skeleton MyApi
- In the above command MyApi is the name of the project, you can change it if you want.
- The above command will take some time to create the project depending upon the internet speed.
- Once the project is created you can open it in any source code editor, here I am using Visual Studio Code. You will see the following directory structure of your project.
- In the above directory structure you can see a folder named, includes. It is not a part of SLIM and I created it. So you have to create this folder as well.
Database Connection
- First we will create a file named Constants.php. In this file we will store all the required constants for our Web Service.
<?php define('DB_HOST', 'localhost'); define('DB_USER', 'root'); define('DB_PASSWORD', ''); define('DB_NAME', 'myapi'); define('USER_CREATED', 101); define('USER_EXISTS', 102); define('USER_FAILURE', 103); define('USER_AUTHENTICATED', 201); define('USER_NOT_FOUND', 202); define('USER_PASSWORD_DO_NOT_MATCH', 203); define('PASSWORD_CHANGED', 301); define('PASSWORD_DO_NOT_MATCH', 302); define('PASSWORD_NOT_CHANGED', 303);
- Now inside the folder that we just created (includes) we will create a new PHP file. Create a PHP file named DbConnect.php and write the following code inside.
<?php class DbConnect{ private $con; function connect(){ include_once dirname(__FILE__) . '/Constants.php'; $this->con = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); if(mysqli_connect_errno()){ echo "Failed to connect " . mysqli_connect_error(); return null; } return $this->con; } }
- The above class is having a method named connect() that will simply establishing a connection to the database and when we will call this method it will return us the connection link.
Database Operation
- Finally we need to perform some operations in our database, for this example we will perform the basics CRUD operations which means (Create, Read, Update and Delete).
- And to perform all the database related operations, again we will create a separate class. So create a new file named DbOperations.php and write the following code inside.
<?php /* Author: Belal Khan Post: PHP Rest API Example using SLIM */ class DbOperations{ //the database connection variable private $con; //inside constructor //we are getting the connection link function __construct(){ require_once dirname(__FILE__) . '/DbConnect.php'; $db = new DbConnect; $this->con = $db->connect(); } /* The Create Operation The function will insert a new user in our database */ public function createUser($email, $password, $name, $school){ if(!$this->isEmailExist($email)){ $stmt = $this->con->prepare("INSERT INTO users (email, password, name, school) VALUES (?, ?, ?, ?)"); $stmt->bind_param("ssss", $email, $password, $name, $school); if($stmt->execute()){ return USER_CREATED; }else{ return USER_FAILURE; } } return USER_EXISTS; } /* The Read Operation The function will check if we have the user in database and the password matches with the given or not to authenticate the user accordingly */ public function userLogin($email, $password){ if($this->isEmailExist($email)){ $hashed_password = $this->getUsersPasswordByEmail($email); if(password_verify($password, $hashed_password)){ return USER_AUTHENTICATED; }else{ return USER_PASSWORD_DO_NOT_MATCH; } }else{ return USER_NOT_FOUND; } } /* The method is returning the password of a given user to verify the given password is correct or not */ private function getUsersPasswordByEmail($email){ $stmt = $this->con->prepare("SELECT password FROM users WHERE email = ?"); $stmt->bind_param("s", $email); $stmt->execute(); $stmt->bind_result($password); $stmt->fetch(); return $password; } /* The Read Operation Function is returning all the users from database */ public function getAllUsers(){ $stmt = $this->con->prepare("SELECT id, email, name, school FROM users;"); $stmt->execute(); $stmt->bind_result($id, $email, $name, $school); $users = array(); while($stmt->fetch()){ $user = array(); $user['id'] = $id; $user['email']=$email; $user['name'] = $name; $user['school'] = $school; array_push($users, $user); } return $users; } /* The Read Operation This function reads a specified user from database */ public function getUserByEmail($email){ $stmt = $this->con->prepare("SELECT id, email, name, school FROM users WHERE email = ?"); $stmt->bind_param("s", $email); $stmt->execute(); $stmt->bind_result($id, $email, $name, $school); $stmt->fetch(); $user = array(); $user['id'] = $id; $user['email']=$email; $user['name'] = $name; $user['school'] = $school; return $user; } /* The Update Operation The function will update an existing user from the database */ public function updateUser($email, $name, $school, $id){ $stmt = $this->con->prepare("UPDATE users SET email = ?, name = ?, school = ? WHERE id = ?"); $stmt->bind_param("sssi", $email, $name, $school, $id); if($stmt->execute()) return true; return false; } /* The Update Operation This function will update the password for a specified user */ public function updatePassword($currentpassword, $newpassword, $email){ $hashed_password = $this->getUsersPasswordByEmail($email); if(password_verify($currentpassword, $hashed_password)){ $hash_password = password_hash($newpassword, PASSWORD_DEFAULT); $stmt = $this->con->prepare("UPDATE users SET password = ? WHERE email = ?"); $stmt->bind_param("ss",$hash_password, $email); if($stmt->execute()) return PASSWORD_CHANGED; return PASSWORD_NOT_CHANGED; }else{ return PASSWORD_DO_NOT_MATCH; } } /* The Delete Operation This function will delete the user from database */ public function deleteUser($id){ $stmt = $this->con->prepare("DELETE FROM users WHERE id = ?"); $stmt->bind_param("i", $id); if($stmt->execute()) return true; return false; } /* The Read Operation The function is checking if the user exist in the database or not */ private function isEmailExist($email){ $stmt = $this->con->prepare("SELECT id FROM users WHERE email = ?"); $stmt->bind_param("s", $email); $stmt->execute(); $stmt->store_result(); return $stmt->num_rows > 0; } }
API Calls
The last thing is we need to call the above methods that we created in DbOperations.php. And to call the methods we will define the URL EndPoints to that we can make an HTTP request to perform the operations.
- To do this come inside index.php file, you will find this file inside the public folder. Delete everything that is there by default and write the following code.
<?php use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; require '../vendor/autoload.php'; require '../includes/DbOperations.php'; $app = new \Slim\App([ 'settings'=>[ 'displayErrorDetails'=>true ] ]); $app->post('/createuser', function(Request $request, Response $response){ if(!haveEmptyParameters(array('email', 'password', 'name', 'school'), $request, $response)){ $request_data = $request->getParsedBody(); $email = $request_data['email']; $password = $request_data['password']; $name = $request_data['name']; $school = $request_data['school']; $hash_password = password_hash($password, PASSWORD_DEFAULT); $db = new DbOperations; $result = $db->createUser($email, $hash_password, $name, $school); if($result == USER_CREATED){ $message = array(); $message['error'] = false; $message['message'] = 'User created successfully'; $response->write(json_encode($message)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(201); }else if($result == USER_FAILURE){ $message = array(); $message['error'] = true; $message['message'] = 'Some error occurred'; $response->write(json_encode($message)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(422); }else if($result == USER_EXISTS){ $message = array(); $message['error'] = true; $message['message'] = 'User Already Exists'; $response->write(json_encode($message)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(422); } } return $response ->withHeader('Content-type', 'application/json') ->withStatus(422); }); $app->post('/userlogin', function(Request $request, Response $response){ if(!haveEmptyParameters(array('email', 'password'), $request, $response)){ $request_data = $request->getParsedBody(); $email = $request_data['email']; $password = $request_data['password']; $db = new DbOperations; $result = $db->userLogin($email, $password); if($result == USER_AUTHENTICATED){ $user = $db->getUserByEmail($email); $response_data = array(); $response_data['error']=false; $response_data['message'] = 'Login Successful'; $response_data['user']=$user; $response->write(json_encode($response_data)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); }else if($result == USER_NOT_FOUND){ $response_data = array(); $response_data['error']=true; $response_data['message'] = 'User not exist'; $response->write(json_encode($response_data)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); }else if($result == USER_PASSWORD_DO_NOT_MATCH){ $response_data = array(); $response_data['error']=true; $response_data['message'] = 'Invalid credential'; $response->write(json_encode($response_data)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); } } return $response ->withHeader('Content-type', 'application/json') ->withStatus(422); }); $app->get('/allusers', function(Request $request, Response $response){ $db = new DbOperations; $users = $db->getAllUsers(); $response_data = array(); $response_data['error'] = false; $response_data['users'] = $users; $response->write(json_encode($response_data)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); }); $app->put('/updateuser/{id}', function(Request $request, Response $response, array $args){ $id = $args['id']; if(!haveEmptyParameters(array('email','name','school'), $request, $response)){ $request_data = $request->getParsedBody(); $email = $request_data['email']; $name = $request_data['name']; $school = $request_data['school']; $db = new DbOperations; if($db->updateUser($email, $name, $school, $id)){ $response_data = array(); $response_data['error'] = false; $response_data['message'] = 'User Updated Successfully'; $user = $db->getUserByEmail($email); $response_data['user'] = $user; $response->write(json_encode($response_data)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); }else{ $response_data = array(); $response_data['error'] = true; $response_data['message'] = 'Please try again later'; $user = $db->getUserByEmail($email); $response_data['user'] = $user; $response->write(json_encode($response_data)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); } } return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); }); $app->put('/updatepassword', function(Request $request, Response $response){ if(!haveEmptyParameters(array('currentpassword', 'newpassword', 'email'), $request, $response)){ $request_data = $request->getParsedBody(); $currentpassword = $request_data['currentpassword']; $newpassword = $request_data['newpassword']; $email = $request_data['email']; $db = new DbOperations; $result = $db->updatePassword($currentpassword, $newpassword, $email); if($result == PASSWORD_CHANGED){ $response_data = array(); $response_data['error'] = false; $response_data['message'] = 'Password Changed'; $response->write(json_encode($response_data)); return $response->withHeader('Content-type', 'application/json') ->withStatus(200); }else if($result == PASSWORD_DO_NOT_MATCH){ $response_data = array(); $response_data['error'] = true; $response_data['message'] = 'You have given wrong password'; $response->write(json_encode($response_data)); return $response->withHeader('Content-type', 'application/json') ->withStatus(200); }else if($result == PASSWORD_NOT_CHANGED){ $response_data = array(); $response_data['error'] = true; $response_data['message'] = 'Some error occurred'; $response->write(json_encode($response_data)); return $response->withHeader('Content-type', 'application/json') ->withStatus(200); } } return $response ->withHeader('Content-type', 'application/json') ->withStatus(422); }); $app->delete('/deleteuser/{id}', function(Request $request, Response $response, array $args){ $id = $args['id']; $db = new DbOperations; $response_data = array(); if($db->deleteUser($id)){ $response_data['error'] = false; $response_data['message'] = 'User has been deleted'; }else{ $response_data['error'] = true; $response_data['message'] = 'Plase try again later'; } $response->write(json_encode($response_data)); return $response ->withHeader('Content-type', 'application/json') ->withStatus(200); }); function haveEmptyParameters($required_params, $request, $response){ $error = false; $error_params = ''; $request_params = $request->getParsedBody(); foreach($required_params as $param){ if(!isset($request_params[$param]) || strlen($request_params[$param])<=0){ $error = true; $error_params .= $param . ', '; } } if($error){ $error_detail = array(); $error_detail['error'] = true; $error_detail['message'] = 'Required parameters ' . substr($error_params, 0, -2) . ' are missing or empty'; $response->write(json_encode($error_detail)); } return $error; } $app->run();
- And thats it our task is finalised.
Testing the API
For testing the API that we created you can use any REST Client. You will find a number of REST extensions for Google Chrome and Mozilla Firefox. You will also find some standalone tools and for this example I will be using a REST Tool which is POSTMAN.
You can use browser plugin or whatever you want, but Postman is the most widely used tool for API development.
In the above screenshot you can see the /createuser call is working fine. The same way you can test all the other URLs as well.
PHP Rest API Example Source Code
Having confusions? Having issues?
Don’t worry here is my working source code for you all. You can go through it.
PHP Rest API Example Source Code Download
So that is all for this PHP REST Api Example friends. In the next post we will create an iOS Application to consume these APIs. Meanwhile you create the API and for any question, leave your comments.
If you like my work, then please SHARE this with your friends. Thank You 🙂
Leave a Reply