How To Build A Simple REST API in PHP - Envato Tuts+
How To Build A Simple REST API in PHP - Envato Tuts+
Advertisement
In this tutorial, I'll teach you how to build a simple REST API with PHP and
MySQL.
REST has become the de facto standard when it comes to exposing data via
APIs and building web services. In fact, most web applications these days
access and expose data via REST APIs. With the popularity of front-end
frameworks that can consume REST APIs effortlessly, it’s always going to be a
plus for you if your web application exposes REST APIs.
In this article, we’ll build a simple demo application, which allows you to fetch a
list of users from the MySQL database via a REST endpoint.
1 ├── Controller
2 │ └── Api
3 │ ├── BaseController.php
4 │ └── UserController.php
5 ├── inc
6 │ ├── bootstrap.php
7 │ └── config.php
8 ├── index.php
9 └── Model
10 ├── Database.php
11 └── UserModel.php
So that’s the basic setup that we are going to implement in the rest of the post.
You could also use a tool like phpMyAdmin if you prefer working with your
databases that way.
Once the rest_api_demo database is created, go ahead and create the users
table by running the following statements.
1 $use rest_api_demo;
2 $CREATE TABLE `users` (
3 `user_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
4 `username` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
5 `user_email` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
6 `user_status` int(11) NOT NULL DEFAULT '0',
7 PRIMARY KEY (`user_id`)
8 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
That should create the users table in the rest_api_demo database. You will
also want to populate this table with a few dummy records for testing
purposes. Insert a few records, and you’re good to go!
1 <?php
2 class Database
3 {
4 protected $connection = null;
5
6 public function __construct()
7 {
8 try {
9 $this->connection = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWOR
10
11 if ( mysqli_connect_errno()) {
12 throw new Exception("Could not connect to database.");
13 }
14 } catch (Exception $e) {
15 throw new Exception($e->getMessage());
16 }
17 }
18
19 public function select($query = "" , $params = [])
20 {
21 try {
22 $stmt = $this->executeStatement( $query , $params );
23 $result = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
24 $stmt->close();
25
26 return $result;
27 } catch(Exception $e) {
28 throw New Exception( $e->getMessage() );
29 }
30 return false;
31 }
32
33 private function executeStatement($query = "" , $params = [])
34 {
35 try {
36 $stmt = $this->connection->prepare( $query );
37
38 if($stmt === false) {
39 throw New Exception("Unable to do prepared statement: " . $
40 }
41
42 if( $params ) {
43 $stmt->bind_param($params[0], $params[1]);
44 }
45
46 $stmt->execute();
47
48 return $stmt;
49 } catch(Exception $e) {
50 throw New Exception( $e->getMessage() );
51 }
52 }
53 }
Next, let’s create the Model/UserModel.php class with the following contents.
1 <?php
2 require_once PROJECT_ROOT_PATH . "/Model/Database.php";
3
4 class UserModel extends Database
5 {
6 public function getUsers($limit)
7 {
8 return $this->select("SELECT * FROM users ORDER BY user_id ASC LIMI
9 }
10 }
It’s important to note that the UserModel class extends the Database class.
Apart from that, it contains the getUsers method, which allows us to select
users from the MySQL database. It’s mandatory to pass the $limit parameter,
which makes sure that it won’t select all records at once.
Of course, you could define more methods in the UserModel class as per your
requirements. We’ll keep things simple in the context of this tutorial.
So now we have our database and model classes set up. In the next section,
we’ll see how to create controllers and the remaining files in our demo
application.
Advertisement
Create Application Layer Components
In this section, we’ll create the remaining files that are required for our demo
application to work.
1 <?php
2 define("DB_HOST", "localhost");
3 define("DB_USERNAME", "demo");
4 define("DB_PASSWORD", "demo");
5 define("DB_DATABASE_NAME", "rest_api_demo");
Make sure to update all the values with the actual ones that you’re using in
your installation.
Next, go ahead and create the inc/bootstrap.php file with the following
contents.
1 <?php
2 define("PROJECT_ROOT_PATH", __DIR__ . "/../");
3
4 // include main configuration file
5 require_once PROJECT_ROOT_PATH . "/inc/config.php";
6
7 // include the base controller file
8 require_once PROJECT_ROOT_PATH . "/Controller/Api/BaseController.php";
9
10 // include the use model file
11 require_once PROJECT_ROOT_PATH . "/Model/UserModel.php";
12 ?>
Firstly, we’ve initialized the PROJECT_ROOT_PATH constant with the directory
root of our application. In this way, we could use the PROJECT_ROOT_PATH
constant to prepare absolute paths in our application. Next, we’ve included the
config.php file, which holds the database connection information. Finally,
we've included controller and model files.
1 <?php
2 class BaseController
3 {
4 /**
5 * __call magic method.
6 */
7 public function __call($name, $arguments)
8 {
9 $this->sendOutput('', array('HTTP/1.1 404 Not Found'));
10 }
11
12 /**
13 * Get URI elements.
14 *
15 * @return array
16 */
17 protected function getUriSegments()
18 {
19 $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
20 $uri = explode( '/', $uri );
21
22 return $uri;
23 }
24
25 /**
26 * Get querystring params.
27 *
28 * @return array
29 */
30 protected function getQueryStringParams()
31 {
32 return parse_str($_SERVER['QUERY_STRING'], $query);
33 }
34
35 /**
36 * Send API output.
37 *
38 * @param mixed $data
39 * @param string $httpHeader
40 */
41 protected function sendOutput($data, $httpHeaders=array())
42 {
43 header_remove('Set-Cookie');
44
45 if (is_array($httpHeaders) && count($httpHeaders)) {
46 foreach ($httpHeaders as $httpHeader) {
47 header($httpHeader);
48 }
49 }
50
51 echo $data;
52 exit;
53 }
54 }
The __call method is a magic method, and it’s called when you try to call a
method that doesn't exist. We’re using this opportunity to throw the HTTP/1.1
404 Not Found error when someone tries to call a method which we haven’t
implemented. If this sounds confusing to you, don't worry—it will make more
sense when we test our application in the next section.
1 <?php
2 class UserController extends BaseController
3 {
4 /**
5 * "/user/list" Endpoint - Get list of users
6 */
7 public function listAction()
8 {
9 $strErrorDesc = '';
10 $requestMethod = $_SERVER["REQUEST_METHOD"];
11 $arrQueryStringParams = $this->getQueryStringParams();
12
13 if (strtoupper($requestMethod) == 'GET') {
14 try {
15 $userModel = new UserModel();
16
17 $intLimit = 10;
18 if (isset($arrQueryStringParams['limit']) && $arrQueryStrin
19 $intLimit = $arrQueryStringParams['limit'];
20 }
21
22 $arrUsers = $userModel->getUsers($intLimit);
23 $responseData = json_encode($arrUsers);
24 } catch (Error $e) {
25 $strErrorDesc = $e->getMessage().'Something went wrong! Ple
26 $strErrorHeader = 'HTTP/1.1 500 Internal Server Error';
27 }
28 } else {
29 $strErrorDesc = 'Method not supported';
30 $strErrorHeader = 'HTTP/1.1 422 Unprocessable Entity';
31 }
32
33 // send output
34 if (!$strErrorDesc) {
35 $this->sendOutput(
36 $responseData,
37 array('Content-Type: application/json', 'HTTP/1.1 200 OK')
38 );
39 } else {
40 $this->sendOutput(json_encode(array('error' => $strErrorDesc)),
41 array('Content-Type: application/json', $strErrorHeader)
42 );
43 }
44 }
45 }
The listAction method is used to get a list of users from the MySQL
database. It contains the whole logic of the /user/list REST endpoint.
Lastly, we’ve used the sendOutput method to send the JSON response to the
user. It’s important to note that the response content-type header value is set
to application/json since we’re sending the JSON response.
Similarly, you could define other methods for other endpoints as well.
Advertisement
The index.php File
The index.php file is the entry-point of our application. Let’s see how it looks.
1 <?php
2 require __DIR__ . "/inc/bootstrap.php";
3
4 $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
5 $uri = explode( '/', $uri );
6
7 if ((isset($uri[2]) && $uri[2] != 'user') || !isset($uri[3])) {
8 header("HTTP/1.1 404 Not Found");
9 exit();
10 }
11
12 require PROJECT_ROOT_PATH . "/Controller/Api/UserController.php";
13
14 $objFeedController = new UserController();
15 $strMethodName = $uri[3] . 'Action';
16 $objFeedController->{$strMethodName}();
17 ?>
With that, we’ve created all the necessary files in our demo REST application. In
the next section, we’ll see how to call it from the end-user perspective.
If you recall the index.php file, we checked if the $uri[2] variable is set to
user . Also, the $uri[3] variable value would act as a method name. In the
above case, the $uri[3] variable is set to list . Thus, it would end up calling
the listAction method of the UserController class.
1 [
2 {
3 "user_id":1,
4 "username":"Bob",
5 "user_email":"[email protected]",
6 "user_status":0
7 },
8 {
9 "user_id":2,
10 "username":"John",
11 "user_email":"[email protected]",
12 "user_status":1
13 },
14 {
15 "user_id":3,
16 "username":"Mark",
17 "user_email":"[email protected]",
18 "user_status":1
19 },
20 {
21 "user_id":4,
22 "username":"Ville",
23 "user_email":"[email protected]",
24 "user_status":0
25 }
26 ]
As you can see, it returns a list of users as a JSON object. Apart from that, if
there’s any application error, it would be returned as a JSON object as well for
debugging purposes.
Conclusion
Today, we discussed how you can build a REST application with PHP and
MySQL. For demonstration purposes, we created a demo application which
allows you to fetch a list of users from a MySQL database via a REST API.
Yes No
Subscribe below and we’ll send you a weekly email summary of all new
Code tutorials. Never miss out on learning about the next big thing.
Sign up
Sajal Soni
Software Engineer, FSPL, India
Drupal Commerce.
I also like to attend community tech conferences, and as a part of that, I
attended the 2016 Joomla World Conference held in Bangalore (India)
and 2018 DrupalCon which was held in Mumbai (India). Apart from this,
I like to travel, explore new places, and listen to music!
sajalsoni
Advertisement Advertisement
WordPress Plugins PHP Scripts
From $5 From $5
ENVATO TUTS+ HELP
Envato Envato Elements Envato Market Placeit by Envato All products Careers Sitemap
© 2024 Envato Pty Ltd. Trademarks and brands are the property of their respective owners.