The previous day How to create REST API for Android app using PHP, Slim and MySQL – Day ½, we have learned fundamental concepts about REST API and preparing your development environment ready by installing the required tools needed. I hope everyone got good knowledge about REST and other technical areas. Also I am assuming that you got all the required tools installed.

Today we are going to learn how to setup a PHP project and writing the actual code for REST API. Also we’ll learn writing necessary SQL queries to perform database CRUD operations.

android rest api design using php mysql slim

8. Starting PHP Project

As we all know IDEs make development process easier. So I recommend you use an IDE for developing the PHP project instead of using plain notepad. You can go for Eclipse, Aptana Studio, PhpStorm or Netbeans. But I personally felt very comfortable using Netbeans for PHP projects.

PHP Project directory structure
The following diagram will give you an idea about the directory structure of the project which we are going to develop now.

task manager rest api php project directory structure

libs – All the third party libraries goes here. In our case we place Slim library here
include – All the helpers classes we build placed here
index.php – Takes care of all the API requests
.htaccess – Rules for url structure and other apache rules

Now let’s start the PHP project

1. Go to the directory where WAMP is installed. In general wamp will be installed in C:\wamp. (If you have installed any other software rather than WAMP, you should go to the directory recommended by that software).

2. As a first step we start with creating required directories. Inside wamp folder go to www folder (c:\wamp\www\) and create a folder named task_manager. This folder will be the parent directory of our project. Inside task_manager create two more folders named libs, include and v1.

3. Now the paste the Slim library inside libs folder. The download link for Slim is provided in previous part.

4. Normally Slim framework works when index.php includes in the url which makes url not well-formed. So using the .htacess rules we can get rid of index.php from the url and make some friendly urls. Inside v1 folder create a file named .htaccess and paste the following code. (Note that this file name shouldn’t include any additional extension in the name like .txt)

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]

8.1 Preparing Helper Classes

First we start writing set of helper classes required in this project. These helper classes provides necessary functions required to interact with the database.

5. Inside include folder create file named Config.php with following content. This file contains the entire project configuration like database connection parameters and other variables.

<?php
/**
 * Database configuration
 */
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_HOST', 'localhost');
define('DB_NAME', 'task_manager');

define('USER_CREATED_SUCCESSFULLY', 0);
define('USER_CREATE_FAILED', 1);
define('USER_ALREADY_EXISTED', 2);
?>

6. Create another class named DbConnect.php This class file mainly takes care of database connection.

<?php

/**
 * Handling database connection
 *
 * @author Ravi Tamada
 */
class DbConnect {

    private $conn;

    function __construct() {        
    }

    /**
     * Establishing database connection
     * @return database connection handler
     */
    function connect() {
        include_once dirname(__FILE__) . './Config.php';

        // Connecting to mysql database
        $this->conn = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);

        // Check for database connection error
        if (mysqli_connect_errno()) {
            echo "Failed to connect to MySQL: " . mysqli_connect_error();
        }

        // returing connection resource
        return $this->conn;
    }

}

?>

Encrypting the password
7. The best way to secure the user passwords is not store them as plain text, instead all the passwords should be encrypted before storing in db. The following class takes care of encrypting the user password. Create another file named PassHash.php and paste the following code.

<?php

class PassHash {

    // blowfish
    private static $algo = '$2a';
    // cost parameter
    private static $cost = '$10';

    // mainly for internal use
    public static function unique_salt() {
        return substr(sha1(mt_rand()), 0, 22);
    }

    // this will be used to generate a hash
    public static function hash($password) {

        return crypt($password, self::$algo .
                self::$cost .
                '$' . self::unique_salt());
    }

    // this will be used to compare a password against a hash
    public static function check_password($hash, $password) {
        $full_salt = substr($hash, 0, 29);
        $new_hash = crypt($password, $full_salt);
        return ($hash == $new_hash);
    }

}

?>

8. Now create another class named DbHandler.php This class is one of the important files in our project which provides necessary functions to perform CRUD operations on the database. Every function is self explanatory by it’s name and comments, I don’t have to have to explain much about them.

<?php

/**
 * Class to handle all db operations
 * This class will have CRUD methods for database tables
 *
 * @author Ravi Tamada
 */
class DbHandler {

    private $conn;

    function __construct() {
        require_once dirname(__FILE__) . './DbConnect.php';
        // opening db connection
        $db = new DbConnect();
        $this->conn = $db->connect();
    }

    /* ------------- `users` table method ------------------ */

    /**
     * Creating new user
     * @param String $name User full name
     * @param String $email User login email id
     * @param String $password User login password
     */
    public function createUser($name, $email, $password) {
        require_once 'PassHash.php';
        $response = array();

        // First check if user already existed in db
        if (!$this->isUserExists($email)) {
            // Generating password hash
            $password_hash = PassHash::hash($password);

            // Generating API key
            $api_key = $this->generateApiKey();

            // insert query
            $stmt = $this->conn->prepare("INSERT INTO users(name, email, password_hash, api_key, status) values(?, ?, ?, ?, 1)");
            $stmt->bind_param("ssss", $name, $email, $password_hash, $api_key);

            $result = $stmt->execute();

            $stmt->close();

            // Check for successful insertion
            if ($result) {
                // User successfully inserted
                return USER_CREATED_SUCCESSFULLY;
            } else {
                // Failed to create user
                return USER_CREATE_FAILED;
            }
        } else {
            // User with same email already existed in the db
            return USER_ALREADY_EXISTED;
        }

        return $response;
    }

    /**
     * Checking user login
     * @param String $email User login email id
     * @param String $password User login password
     * @return boolean User login status success/fail
     */
    public function checkLogin($email, $password) {
        // fetching user by email
        $stmt = $this->conn->prepare("SELECT password_hash FROM users WHERE email = ?");

        $stmt->bind_param("s", $email);

        $stmt->execute();

        $stmt->bind_result($password_hash);

        $stmt->store_result();

        if ($stmt->num_rows > 0) {
            // Found user with the email
            // Now verify the password

            $stmt->fetch();

            $stmt->close();

            if (PassHash::check_password($password_hash, $password)) {
                // User password is correct
                return TRUE;
            } else {
                // user password is incorrect
                return FALSE;
            }
        } else {
            $stmt->close();

            // user not existed with the email
            return FALSE;
        }
    }

    /**
     * Checking for duplicate user by email address
     * @param String $email email to check in db
     * @return boolean
     */
    private function isUserExists($email) {
        $stmt = $this->conn->prepare("SELECT id from users WHERE email = ?");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }

    /**
     * Fetching user by email
     * @param String $email User email id
     */
    public function getUserByEmail($email) {
        $stmt = $this->conn->prepare("SELECT name, email, api_key, status, created_at FROM users WHERE email = ?");
        $stmt->bind_param("s", $email);
        if ($stmt->execute()) {
            $user = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            return $user;
        } else {
            return NULL;
        }
    }

    /**
     * Fetching user api key
     * @param String $user_id user id primary key in user table
     */
    public function getApiKeyById($user_id) {
        $stmt = $this->conn->prepare("SELECT api_key FROM users WHERE id = ?");
        $stmt->bind_param("i", $user_id);
        if ($stmt->execute()) {
            $api_key = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            return $api_key;
        } else {
            return NULL;
        }
    }

    /**
     * Fetching user id by api key
     * @param String $api_key user api key
     */
    public function getUserId($api_key) {
        $stmt = $this->conn->prepare("SELECT id FROM users WHERE api_key = ?");
        $stmt->bind_param("s", $api_key);
        if ($stmt->execute()) {
            $user_id = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            return $user_id;
        } else {
            return NULL;
        }
    }

    /**
     * Validating user api key
     * If the api key is there in db, it is a valid key
     * @param String $api_key user api key
     * @return boolean
     */
    public function isValidApiKey($api_key) {
        $stmt = $this->conn->prepare("SELECT id from users WHERE api_key = ?");
        $stmt->bind_param("s", $api_key);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }

    /**
     * Generating random Unique MD5 String for user Api key
     */
    private function generateApiKey() {
        return md5(uniqid(rand(), true));
    }

    /* ------------- `tasks` table method ------------------ */

    /**
     * Creating new task
     * @param String $user_id user id to whom task belongs to
     * @param String $task task text
     */
    public function createTask($user_id, $task) {        
        $stmt = $this->conn->prepare("INSERT INTO tasks(task) VALUES(?)");
        $stmt->bind_param("s", $task);
        $result = $stmt->execute();
        $stmt->close();

        if ($result) {
            // task row created
            // now assign the task to user
            $new_task_id = $this->conn->insert_id;
            $res = $this->createUserTask($user_id, $new_task_id);
            if ($res) {
                // task created successfully
                return $new_task_id;
            } else {
                // task failed to create
                return NULL;
            }
        } else {
            // task failed to create
            return NULL;
        }
    }

    /**
     * Fetching single task
     * @param String $task_id id of the task
     */
    public function getTask($task_id, $user_id) {
        $stmt = $this->conn->prepare("SELECT t.id, t.task, t.status, t.created_at from tasks t, user_tasks ut WHERE t.id = ? AND ut.task_id = t.id AND ut.user_id = ?");
        $stmt->bind_param("ii", $task_id, $user_id);
        if ($stmt->execute()) {
            $task = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            return $task;
        } else {
            return NULL;
        }
    }

    /**
     * Fetching all user tasks
     * @param String $user_id id of the user
     */
    public function getAllUserTasks($user_id) {
        $stmt = $this->conn->prepare("SELECT t.* FROM tasks t, user_tasks ut WHERE t.id = ut.task_id AND ut.user_id = ?");
        $stmt->bind_param("i", $user_id);
        $stmt->execute();
        $tasks = $stmt->get_result();
        $stmt->close();
        return $tasks;
    }

    /**
     * Updating task
     * @param String $task_id id of the task
     * @param String $task task text
     * @param String $status task status
     */
    public function updateTask($user_id, $task_id, $task, $status) {
        $stmt = $this->conn->prepare("UPDATE tasks t, user_tasks ut set t.task = ?, t.status = ? WHERE t.id = ? AND t.id = ut.task_id AND ut.user_id = ?");
        $stmt->bind_param("siii", $task, $status, $task_id, $user_id);
        $stmt->execute();
        $num_affected_rows = $stmt->affected_rows;
        $stmt->close();
        return $num_affected_rows > 0;
    }

    /**
     * Deleting a task
     * @param String $task_id id of the task to delete
     */
    public function deleteTask($user_id, $task_id) {
        $stmt = $this->conn->prepare("DELETE t FROM tasks t, user_tasks ut WHERE t.id = ? AND ut.task_id = t.id AND ut.user_id = ?");
        $stmt->bind_param("ii", $task_id, $user_id);
        $stmt->execute();
        $num_affected_rows = $stmt->affected_rows;
        $stmt->close();
        return $num_affected_rows > 0;
    }

    /* ------------- `user_tasks` table method ------------------ */

    /**
     * Function to assign a task to user
     * @param String $user_id id of the user
     * @param String $task_id id of the task
     */
    public function createUserTask($user_id, $task_id) {
        $stmt = $this->conn->prepare("INSERT INTO user_tasks(user_id, task_id) values(?, ?)");
        $stmt->bind_param("ii", $user_id, $task_id);
        $result = $stmt->execute();
        $stmt->close();
        return $result;
    }

}

?>

8.2 Handling the API calls

Now we have all the required classes for the REST API. Now we can start the code to handle all individual api calls.

8. Inside v1 folder create a file named index.php and add the following code. Here we are including required libraries and other helper functions.

verifyRequiredParams() – This function verifies the mandatory parameters in the request.
validateEmail() – Verifies whether email address is valid one or not.
echoRespnse() – This function will echo the JSON response with a status code.

<?php

require_once '../include/DbHandler.php';
require_once '../include/PassHash.php';
require '.././libs/Slim/Slim.php';

\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

// User id from db - Global Variable
$user_id = NULL;

/**
 * Verifying required params posted or not
 */
function verifyRequiredParams($required_fields) {
    $error = false;
    $error_fields = "";
    $request_params = array();
    $request_params = $_REQUEST;
    // Handling PUT request params
    if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
        $app = \Slim\Slim::getInstance();
        parse_str($app->request()->getBody(), $request_params);
    }
    foreach ($required_fields as $field) {
        if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
            $error = true;
            $error_fields .= $field . ', ';
        }
    }

    if ($error) {
        // Required field(s) are missing or empty
        // echo error json and stop the app
        $response = array();
        $app = \Slim\Slim::getInstance();
        $response["error"] = true;
        $response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
        echoRespnse(400, $response);
        $app->stop();
    }
}

/**
 * Validating email address
 */
function validateEmail($email) {
    $app = \Slim\Slim::getInstance();
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $response["error"] = true;
        $response["message"] = 'Email address is not valid';
        echoRespnse(400, $response);
        $app->stop();
    }
}

/**
 * Echoing json response to client
 * @param String $status_code Http response code
 * @param Int $response Json response
 */
function echoRespnse($status_code, $response) {
    $app = \Slim\Slim::getInstance();
    // Http response code
    $app->status($status_code);

    // setting response content type to json
    $app->contentType('application/json');

    echo json_encode($response);
}

$app->run();
?>

The JSON response

On calling every API request a JSON response will be issued with a HTTP status code. On the client side you have to verify the response http status code. If the status is 200, the request is processed successfully. Also you can notice a “error” node in the response. If the error value is true, that means some error occurred while processing the user data.

Api Calls without Authentication (without API key in the request header)

These calls don’t have to include Api Key in the request header. The main purpose of these calls is to interact with database without any authentication. User registration and login comes under this category.

⇒ User Registration

In order to interact with the API, the user has to register in our system first. Once he registered an API key will be generated and stored in the database. This API key will be private to that user only.

9. Add the following code in index.php. This function handles user registration.

/**
 * User Registration
 * url - /register
 * method - POST
 * params - name, email, password
 */
$app->post('/register', function() use ($app) {
            // check for required params
            verifyRequiredParams(array('name', 'email', 'password'));

            $response = array();

            // reading post params
            $name = $app->request->post('name');
            $email = $app->request->post('email');
            $password = $app->request->post('password');

            // validating email address
            validateEmail($email);

            $db = new DbHandler();
            $res = $db->createUser($name, $email, $password);

            if ($res == USER_CREATED_SUCCESSFULLY) {
                $response["error"] = false;
                $response["message"] = "You are successfully registered";
                echoRespnse(201, $response);
            } else if ($res == USER_CREATE_FAILED) {
                $response["error"] = true;
                $response["message"] = "Oops! An error occurred while registereing";
                echoRespnse(200, $response);
            } else if ($res == USER_ALREADY_EXISTED) {
                $response["error"] = true;
                $response["message"] = "Sorry, this email already existed";
                echoRespnse(200, $response);
            }
        });

In the following table you can find the API request information about the URL, HTTP method and the parameters needed to be posted.

URL /register
Method POST
Params name, email, password

Upon the successful registration the following json response will be issued.

{
    "error": false,
    "message": "You are successfully registered"
}

If the request is missing mandatory parameters the following json will be issued.

{
    "error": true,
    "message": "Required field(s) email, password is missing or empty"
}

⇒ User Login

10. Add the following code to handle user login. After verifying user credentials, the API Key for that user will be issued in the json response. The api key should be included in the request header in all remaining api calls.

/**
 * User Login
 * url - /login
 * method - POST
 * params - email, password
 */
$app->post('/login', function() use ($app) {
            // check for required params
            verifyRequiredParams(array('email', 'password'));

            // reading post params
            $email = $app->request()->post('email');
            $password = $app->request()->post('password');
            $response = array();

            $db = new DbHandler();
            // check for correct email and password
            if ($db->checkLogin($email, $password)) {
                // get the user by email
                $user = $db->getUserByEmail($email);

                if ($user != NULL) {
                    $response["error"] = false;
                    $response['name'] = $user['name'];
                    $response['email'] = $user['email'];
                    $response['apiKey'] = $user['api_key'];
                    $response['createdAt'] = $user['created_at'];
                } else {
                    // unknown error occurred
                    $response['error'] = true;
                    $response['message'] = "An error occurred. Please try again";
                }
            } else {
                // user credentials are wrong
                $response['error'] = true;
                $response['message'] = 'Login failed. Incorrect credentials';
            }

            echoRespnse(200, $response);
        });
URL /login
Method POST
Params email, password

On successful login the following json will be issued.

{
    "error": false,
    "name": "Ravi Tamada",
    "email": "ravi@gmail.com",
    "apiKey": "940bb12af8d7b040876f60f965c5be6d",
    "createdAt": "2014-01-07 23:38:35"
}

If the credentials are wrong, you can expect the following json.

{
    "error": true,
    "message": "Login failed. Incorrect credentials"
}

⇒ Verifying API Key

While dealing with task data, we need to identify the user using the API key in the request header by reading Authorization field. Basically we’ll look into database for matched API key and get the appropriate user. If the API key not present in users table, then we’ll stop the execution and echo the error json.

11. Add the following method in index.php. The method authenticate() will be executed every time before doing any task related operations on database.

/**
 * Adding Middle Layer to authenticate every request
 * Checking if the request has valid api key in the 'Authorization' header
 */
function authenticate(\Slim\Route $route) {
    // Getting request headers
    $headers = apache_request_headers();
    $response = array();
    $app = \Slim\Slim::getInstance();

    // Verifying Authorization Header
    if (isset($headers['Authorization'])) {
        $db = new DbHandler();

        // get the api key
        $api_key = $headers['Authorization'];
        // validating api key
        if (!$db->isValidApiKey($api_key)) {
            // api key is not present in users table
            $response["error"] = true;
            $response["message"] = "Access Denied. Invalid Api key";
            echoRespnse(401, $response);
            $app->stop();
        } else {
            global $user_id;
            // get user primary key id
            $user = $db->getUserId($api_key);
            if ($user != NULL)
                $user_id = $user["id"];
        }
    } else {
        // api key is missing in header
        $response["error"] = true;
        $response["message"] = "Api key is misssing";
        echoRespnse(400, $response);
        $app->stop();
    }
}

If the api key is missing in the request header, the following json will be echoed with 400 status code.

{
    "error": true,
    "message": "Api key is misssing"
}

If the api key is not valid following json will echoed with 401 status code.

{
    "error": true,
    "message": "Access Denied. Invalid Api key"
}

Api Calls with Authentication (Including API key in the request)
Following are the API calls should have an Api Key in the request header. These api calls primarily deals the user’s task data like creating, reading, updating and deleting.

⇒ Creating New Task

12. Add the follwing method to create a new task. Here you can notice that authenticate method is called to verify the Api key before inserting a new task.

/**
 * Creating new task in db
 * method POST
 * params - name
 * url - /tasks/
 */
$app->post('/tasks', 'authenticate', function() use ($app) {
            // check for required params
            verifyRequiredParams(array('task'));

            $response = array();
            $task = $app->request->post('task');

            global $user_id;
            $db = new DbHandler();

            // creating new task
            $task_id = $db->createTask($user_id, $task);

            if ($task_id != NULL) {
                $response["error"] = false;
                $response["message"] = "Task created successfully";
                $response["task_id"] = $task_id;
            } else {
                $response["error"] = true;
                $response["message"] = "Failed to create task. Please try again";
            }
            echoRespnse(201, $response);
        });
URL /tasks
Method POST
Params task

On successful creation of new task following json will be issued. If you got this json, you can see new row inserted in tasks and user_tasks tables.

{
    "error": false,
    "message": "Task created successfully",
    "task_id": 1
}

⇒ Getting All Tasks

13. Following method will list down all user’s tasks. We don’t have to submit any params for this api call.

/**
 * Listing all tasks of particual user
 * method GET
 * url /tasks          
 */
$app->get('/tasks', 'authenticate', function() {
            global $user_id;
            $response = array();
            $db = new DbHandler();

            // fetching all user tasks
            $result = $db->getAllUserTasks($user_id);

            $response["error"] = false;
            $response["tasks"] = array();

            // looping through result and preparing tasks array
            while ($task = $result->fetch_assoc()) {
                $tmp = array();
                $tmp["id"] = $task["id"];
                $tmp["task"] = $task["task"];
                $tmp["status"] = $task["status"];
                $tmp["createdAt"] = $task["created_at"];
                array_push($response["tasks"], $tmp);
            }

            echoRespnse(200, $response);
        });
URL /tasks
Method GET
Params

Following json will be issued for list of tasks. The “tasks” represents list of tasks as an array. Also if the “status” is 0, that means the task is not done yet.

{
    "error": false,
    "tasks": [
        {
            "id": 1,
            "task": "Complete REST article by Sunday",
            "status": 0,
            "createdAt": "2014-01-08 23:35:45"
        },
        {
            "id": 2,
            "task": "Book bus tickets!",
            "status": 0,
            "createdAt": "2014-01-08 23:56:52"
        }
    ]
}

⇒ Getting Single Task

14. Following method will fetch details of single task. You need to append the task id with a / to url. For an example if you want details of task 15, the url will be /tasks/15.

/**
 * Listing single task of particual user
 * method GET
 * url /tasks/:id
 * Will return 404 if the task doesn't belongs to user
 */
$app->get('/tasks/:id', 'authenticate', function($task_id) {
            global $user_id;
            $response = array();
            $db = new DbHandler();

            // fetch task
            $result = $db->getTask($task_id, $user_id);

            if ($result != NULL) {
                $response["error"] = false;
                $response["id"] = $result["id"];
                $response["task"] = $result["task"];
                $response["status"] = $result["status"];
                $response["createdAt"] = $result["created_at"];
                echoRespnse(200, $response);
            } else {
                $response["error"] = true;
                $response["message"] = "The requested resource doesn't exists";
                echoRespnse(404, $response);
            }
        });
URL /tasks/id (id should be replaced with task id)
Method GET
Params

The details of a single task will be in following json format.

{
    "error": false,
    "id": 2,
    "task": "Book bus tickets!",
    "status": 0,
    "createdAt": "2014-01-08 23:56:52"
}

If you pass a task id which is not there in the database, you will get 404 not found error.

⇒ Updating Task

15. Following code will take care of updating a task. The url for this api call is same as getting the details of single task, only difference is we should use PUT method instead of GET.

/**
 * Updating existing task
 * method PUT
 * params task, status
 * url - /tasks/:id
 */
$app->put('/tasks/:id', 'authenticate', function($task_id) use($app) {
            // check for required params
            verifyRequiredParams(array('task', 'status'));

            global $user_id;            
            $task = $app->request->put('task');
            $status = $app->request->put('status');

            $db = new DbHandler();
            $response = array();

            // updating task
            $result = $db->updateTask($user_id, $task_id, $task, $status);
            if ($result) {
                // task updated successfully
                $response["error"] = false;
                $response["message"] = "Task updated successfully";
            } else {
                // task failed to update
                $response["error"] = true;
                $response["message"] = "Task failed to update. Please try again!";
            }
            echoRespnse(200, $response);
        });
URL /tasks/id (id should be replaced with task id)
Method PUT
Params task, status (0 or 1)

Upon successful updation you will get following json.

{
    "error": false,
    "message": "Task updated successfully"
}

⇒ Deleting Task

16. Again delete task url is same as update task, but this requires DELETE method.

/**
 * Deleting task. Users can delete only their tasks
 * method DELETE
 * url /tasks
 */
$app->delete('/tasks/:id', 'authenticate', function($task_id) use($app) {
            global $user_id;

            $db = new DbHandler();
            $response = array();
            $result = $db->deleteTask($user_id, $task_id);
            if ($result) {
                // task deleted successfully
                $response["error"] = false;
                $response["message"] = "Task deleted succesfully";
            } else {
                // task failed to delete
                $response["error"] = true;
                $response["message"] = "Task failed to delete. Please try again!";
            }
            echoRespnse(200, $response);
        });
URL /tasks/id (id should be replaced with task id)
Method DELETE
Params

You will get following json if the task is deleted successfully.

{
    "error": false,
    "message": "Task deleted succesfully"
}

Here we completes the PHP and MySQL part. Now it’s time to move on to testing the API just to make sure that whatever code we have written is working.

Testing the API

Following is the list of URL we need to test using Chrome Advanced REST client extension with possible combinations of inputs.

URL Method Parameters Description
http://localhost/task_manager/v1/register POST name, email, password User registration
http://localhost/task_manager/v1/login POST email, password User login
http://localhost/task_manager/v1/tasks POST task To create new task
http://localhost/task_manager/v1/tasks GET Fetching all tasks
http://localhost/task_manager/v1/tasks/:id GET Fetching single task
http://localhost/task_manager/v1/tasks/:id PUT Updating single task
http://localhost/task_manager/v1/tasks/:id DELETE task, status Deleting single task

The following video shows you how to test the API thoroughly.

What’s Next?

Until now we have done a great job by developing fully functional REST services from scratch. But the services are limited to localhost. In other words your app can’t consume them if you want your app to be on playstore. So to make the services globally accessible, we need to host them on a public server. In the next part Android Hosting PHP, MySQL RESTful services to DigitalOcean, you will learn the complete process of buying the hosting space, deploying the services and finally mapping to a real domain URL.

Subscribe
Notify of
guest
766 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Bla Bla Bla
Bla Bla Bla
6 years ago

Ravi, does every user get a table named task created for them on the Database?

Ravi Tamada
6 years ago
Reply to  Bla Bla Bla

No, we have to create the table using the sql queries mentioned in the first part of this tutorial.

Bla Bla Bla
Bla Bla Bla
6 years ago
Reply to  Ravi Tamada

I know we did create a table in the first part, but you know we have users. So, for every user, there’ll be a table Task for them autogenerated or it’s just that table task that’ll take care of it all. I’m actually building an application and finding it hard to use the REST cause, I’m having problem structuring the Database itself, cause I’m a novice when it comes to databases. Thank You.

Ravi Tamada
6 years ago
Reply to  Bla Bla Bla

Hi,

There will be always one table tasks. For every user there won’t be a separate task table created.

Every task is inserted as a row in task table. The relation between task row and user will be stored in user_tasks table where user_id and task_id will be stored.

Bla Bla Bla
Bla Bla Bla
6 years ago
Reply to  Ravi Tamada

Ohw, now I dig. Very brilliant an idea. Thank You. And, we are waiting for the p3

xDroid
xDroid
6 years ago

I am working on Mac and using MAMP . I have created task_manager in my htdocs folder because there was no www folder there in Application/MAMP/ . I have created .htaccess file in root of task_manager and added all the code accordingly but I am not able to access my code on the server Its been started showing MAMP webpage but when I try to open that URL it just show 404!
Please help me with MAC setup or what I am doing Wrong! 🙁

xDroid
xDroid
6 years ago
Reply to  xDroid
Ravi Tamada
6 years ago
Reply to  xDroid

You need to access the full url path with correct HTTP method. If you access just http://localhost:8888/MAMP/task_manager/ you will get 404

You should access full url
http://localhost:8888/MAMP/task_manager/v1/register with POST method only.

xDroid
xDroid
6 years ago
Reply to  Ravi Tamada

I have tried with post method with full URL and just 404 !
Status
404 Not Found
This !

Ravi Tamada
6 years ago
Reply to  xDroid

Could you post the screenshot of that error.

Bakus Seifer
Bakus Seifer
6 years ago
Reply to  xDroid

Make sure “$app->run();” is the last line of code in index.php, after all the “/register”, “/login”, ….

Andrew Nyago
Andrew Nyago
5 years ago
Reply to  Ravi Tamada

By that, do you mean should have:
$app->post(‘http://192.168.43.40/androidchatter/task_manager/v1/register/’, function () use ($app) {

as my call to regster please?

My result:

404 Not Found

Not Found
The requested URL /androidchatter/task_manager/v1/register was not found on this server.

Apache/2.4.7 (Ubuntu) Server at 192.168.43.40 Port 80

John
John
6 years ago
Reply to  xDroid

The .htaccess file should be in the “v1” directory, NOT in “task_manager”.
This is clear from the image showing the project structure at the beginning of the article, but not in the text… The downloadable code archive has all files in correct locations…

Ravi Tamada
6 years ago
Reply to  John

Thanks John for the correction. Updated the article.

nasznjoka
nasznjoka
6 years ago

Hi Ravi thanks once again for this contribution to our droid life. I have this question if you can help me. What is the best way of turning a website which is not responsive into an android app? I ve been seeing parsing but i don’t exactly know how to work with it better and when you want to apply it to the website then its a disaster to me

Ravi Tamada
6 years ago
Reply to  nasznjoka

Could you tell what do you mean by “turning website into android app”?

nasznjoka
nasznjoka
6 years ago
Reply to  Ravi Tamada

I mean to parse website content into an app for example like linkedin web looks just like their android app. So i want to know how to whether native or frameworks

Ravi Tamada
6 years ago
Reply to  nasznjoka

That actually can be done using responsive page which adjusts to screen size. You have to design your page in responsive way.

Normally nobody will do a parse and prepare a page on android app. You have to use webview for it.

siddhu
siddhu
6 years ago
Reply to  Ravi Tamada

WIthout responsive page nobody cant parse

Zaphod Beeblebroks
Zaphod Beeblebroks
6 years ago
Reply to  siddhu

what is exactly meaning of “responsive page” we are talking about here? How responsive is related with parsing html? There is some misunderstanding here..

nasznjoka
nasznjoka
6 years ago
Reply to  Ravi Tamada

Thanx man, but i just wish i could know more. I ve gone through the library in here but i have not seen such a tutorial

Zaphod Beeblebroks
Zaphod Beeblebroks
6 years ago
Reply to  nasznjoka

I think I understood a bit different his question.. Let’s say there is a news portal which get updated severl times per day but it doesn’t offer rss, json, gson or smth similar, but just html.. Let’s say there is a specific table of home page of this portal which list headlines. Is it possible to make web app (Google App Engine or similar platform) which will from time to time parse that home page, get the table and generate json file which will be exposed on specific request? That why we make android app, we get the json file and we display it in app interface and all “heavy processing of parsing” is done in the cloud. Additionally android app uses less internet data by fetching just newest json instead of whole html page source. What about that? What should be used for web app? Where to host it? 10q

nasznjoka
nasznjoka
6 years ago

Yes thats what i was asking for thank Zaphod for clarifying to make an app for a site but with different organization of menus, contents to the site itself

solomon
solomon
6 years ago
Reply to  Ravi Tamada

waiting for 3rd part please make it 😀

shashi
shashi
6 years ago
Reply to  nasznjoka

i m getting ,,,,,,”Required field(s) name, email, password is missing or empty” on register

Huzoor Bux
6 years ago

Very nicely written code 🙂

Ravi Tamada
6 years ago
Reply to  Huzoor Bux

Thank you 🙂

siddhu
siddhu
6 years ago

Stunning!!!

Mat
Mat
6 years ago

You are the best Ravi!! 🙂 Thank You

meirariel
meirariel
6 years ago

What does the Slim framework add other than JSON encoding? What code did we save writing by using it?

Ravi Tamada
6 years ago
Reply to  meirariel

Hi Meirariel,

JSON encoding is not the functionality of Slim framework. json_encode() is native function of PHP.

Slim actually takes care of routing and the method of url $app->get(‘/route’) – . Also slim provides middle layer where we can execute “authenticate” method.

If you go through this doc, you can find lot more options of slim.
http://docs.slimframework.com/

meirariel
meirariel
6 years ago
Reply to  Ravi Tamada

Thanks. Your tutorials are so well thought out and clear. Much appreciated.

Ravi Tamada
6 years ago
Reply to  meirariel

You are welcome and thanks for the appreciation 🙂

derpina
derpina
6 years ago

Ravi, you are the best. Thank you for the article.

meirariel
meirariel
6 years ago

If I wanted to store the user’s picture on the cloud, together with their other account details, how would you recommend doing that?

tan hieu Huynh
tan hieu Huynh
6 years ago

I try run Advanced REST client as demo but occur error 500 Internal Server Error, Pls help me fix it. Thank!

Guest
Guest
6 years ago
Reply to  tan hieu Huynh

are you using chrome?

babazumbula
babazumbula
6 years ago

I’m also getting error 50. My Appache error log says:
[Fri Jan 24 15:51:52 2014] [alert] [client 127.0.0.1] C:/wamp/www/task_manager/.htaccess: Invalid command ‘RewriteEngine’, perhaps misspelled or defined by a module not included in the server configuration

but, still I dunno how to fix it

Stranger
Stranger
6 years ago
Reply to  babazumbula
babazumbula
babazumbula
6 years ago

Solved, I was missing line…
So I added line
LoadModule rewrite_module modules/mod_rewrite.so
in my httpd.conf

Steve
Steve
6 years ago

Love this. It will help me complete my project http://www.e-schedulebuilder.com. But my question is. Do I need oauth1.0a or 2.0 and an apikey for API protocols? I am designing software that will allow users to view there schedules, update employee information and stuff all from the mobile application.

Steve
Steve
6 years ago

Nice tutorial!
Any clue when the third part will be ready?

Ravi Tamada
6 years ago
Reply to  Steve

Hi Steve, I am facing some error in third part. I am currently solving it.

Steve
Steve
6 years ago
Reply to  Ravi Tamada

Thanks for the quick reaction.
By the end of this week?

Thanks again for the great tutorials.

Ravi Tamada
6 years ago
Reply to  Steve

Yeah, sure.

Marat Duisenov
Marat Duisenov
6 years ago
Reply to  Ravi Tamada

thank you for your work, my friend. I’m looking forward third part

Ravi Tamada
6 years ago
Reply to  Marat Duisenov

Sorry mrt sen,

I seems like I can’t post the third part as I stopped by some hosting service issues.

Marat Duisenov
Marat Duisenov
6 years ago
Reply to  Ravi Tamada

It’s a thousand pities!

Rasit Aklar
Rasit Aklar
6 years ago
Reply to  Marat Duisenov

10,000!!!

zxzx
zxzx
6 years ago
Reply to  Ravi Tamada

any update on these issues?

Евгений Храмов
Евгений Храмов
6 years ago

When i try register new user i hav an error “Required field(s) …. is missing or empty”
Then I was trying to check fields by print print_r($_REQUEST)
In my case $_REQUEST is empty.

John
John
6 years ago

Thank for the great write up Ravi – I’m also getting the same issue as above…. any ideas?

Ravi Tamada
6 years ago
Reply to  John

In the error message it will clearly shows you what are the parameters are missing while posting to that url.

If it says “Required fields(s) name, email missing”, then you should add name=’your name’ and email=’youremail@gmai.com’ in the request parameters.

Check the testing video to know how I added parameters while making the request.

Евгений Храмов
Евгений Храмов
6 years ago
Reply to  Ravi Tamada

I was checking parameters in chome/firefox plugins and Fiddrer2
In my case all parameters was sended to server, byt on the server side is empty.

jujusous3
jujusous3
6 years ago

same problem, any solution ?

Guest
Guest
6 years ago

In Advance REST Client, the drop-down list of ‘Set “Content-Type” header to overwrite this value.’ leave it as “application/x-www-form-urlencoded”

shyam
shyam
6 years ago

where is third part of your tutorial

andlab
andlab
6 years ago
Reply to  shyam

Im also really waiting for it :)))
thanks anyway

San
San
6 years ago

This is one of the great tutorial! Thank you very much Ravi!!!

Marcus
Marcus
6 years ago

Hi, i have downloaded the code and uploaded it to my webserver and using chrome to test as per the example but i receive a server 500 message stating that the Response does not contain any data.Any ideas why i would be receiving this message. Thanks

Ravi Tamada
6 years ago
Reply to  Marcus

Might be some php errors. Check your server php / apache error log file.

Oscar Serna
Oscar Serna
6 years ago
Reply to  Marcus

Hey Marcus!, I’m facing the same problem. How did you solve it? what kind of error did you find? was it a directory issue or definitly it was a code error?

thank you!

Jao
Jao
6 years ago

when will be the third?

Marat Duisenov
Marat Duisenov
6 years ago
Reply to  Jao

He can’t post the third part as He stopped by some hosting service issues.

dev
dev
6 years ago

nice tutorial

but i m getting ,,,,,,”Required field(s) name, email, password is missing or empty” on register

Евгений Храмов
Евгений Храмов
6 years ago
Reply to  dev

I posted the same issue 12 days ago and no luck.

Marat Duisenov
Marat Duisenov
6 years ago

this example works for me

Евгений Храмов
Евгений Храмов
6 years ago
Reply to  Marat Duisenov

Good for you!

Marat Duisenov
Marat Duisenov
6 years ago

I meant it works

Marat Duisenov
Marat Duisenov
6 years ago
Reply to  Marat Duisenov

Asking the right question is half the answer

meirariel
meirariel
6 years ago
Reply to  dev

Make sure you’re sending the required fields in the body of the request and not as headers.

ZiLang
ZiLang
6 years ago
Reply to  meirariel

I got the same problem. (I posted the 3 parameters as shown in video in body). Any other possible reason ?

shanice
shanice
6 years ago
Reply to  ZiLang

In Advance REST Client, the drop-down list of “Set Content-Type header to overwrite this value.” leave it as “application/x-www-form-urlencoded”

akhil nair
akhil nair
6 years ago

nice tutorial….waiting for last part………

dev
dev
6 years ago

can any one tell me ,how to solve ,,,,,,,,,,,,,,,,,

Required field(s) name, email, password is missing or empty” on register

Hao Zhou
Hao Zhou
6 years ago

This is very nice tutorial. But I have two questions:

1. Why do you use Slim ? I found it’s difficult to debug when there is one more layer there in php code
2. Is there a way to separate different functions into different php files instead of all functions in index.php? Because it’ll be very difficult to find the functions if there are too many functions in the API.

dr tarik
dr tarik
6 years ago

thanks for all your effort your are realy one reference
one Q : how to change content-type to application/xml

Ravi Tamada
6 years ago
Reply to  dr tarik

For this you have to do the changes in index.php file in “echoRespnse” function

1. Change the line $app->contentType(‘application/json’); to $app->contentType(‘application/xml’);

2. Follow this link to convert an array to xml
http://stackoverflow.com/questions/1397036/how-to-convert-array-to-simplexml

Thank You

dr tarik
dr tarik
6 years ago
Reply to  Ravi Tamada

Great thanks

Guest
Guest
6 years ago

How to get JSON from your php in eclipse?

Dhiren
Dhiren
6 years ago

Kindly, Give me some knowledge for SLIP Framework.

Dhiren
Dhiren
6 years ago

SLIM* Framework

akhil nair
akhil nair
6 years ago

Nice Tut….. I’m looking forward third part

brokenOval
brokenOval
6 years ago

Great article, thanks for the post. Keep getting a strange error on Ubuntu. I can make Slim work for something simple like “Hello world”, however when it tries to call the include files I get an internal server error 500 – checked the error log and got the following message whenever I try to run (for example the /register API): “PHP Fatal error: DbHandler::__construct(): Failed opening required ‘/var/www/include./DbConnect.php’ (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/include/DbHandler.php on line 14”

Anyone have an idea how to fix? Can confirm that Pear is installed on php and database is set up properly.

Jason Shen
Jason Shen
6 years ago
Reply to  brokenOval

check your case as linux is case sensitie cheers

brokenOval
brokenOval
5 years ago
Reply to  Jason Shen

Thanks Jason – all lowercase. I’m using an ubuntu distribution of apache if that helps. Any other ideas?

stephen
stephen
6 years ago

amazing tutorial bro..keep up the good work

ape364
ape364
6 years ago

Hi Ravi, good tutorial, thanks. can u tell why you need field ‘status’ in users table? i didnt find any use of this

Andrew
Andrew
6 years ago

Just wanted to say thank you! With minimum work on my end, I could just DL the code, change my DB config, and it worked, that easy! Read the Day 1 and Day2 of the article twice to get to know web services abit better too, but the video at the end really helped. Great job! For anyone having issues, just check your ReWrite module is working and edit the DB file, that’s it, great job!

zxzx
zxzx
6 years ago

So no 3rd part now?

neetu
neetu
6 years ago

Your tutorial is great and very helpful.Can you post the third article if you not..then please tell me how to call rest webservice from android.I am so confused..

zxzx
zxzx
6 years ago

Any news about the 3rd part?

zxzx
zxzx
6 years ago

looks like the 3rd part ain’t coming.. 😉 thanx Ravi for all that u do

Hanimex
Hanimex
6 years ago

Good tutorial. I ran through it on IIS8 (because I’m a masochist). I got to grips with the IIS URL Rewrite module and had to add in PUT and DELETE as allowed verbs for my PHP handler mapping but other than that it all worked. Thanks.

zxzx
zxzx
6 years ago
Reply to  Hanimex

Can u plz post what u added Thx

Hanimex
Hanimex
6 years ago
Reply to  zxzx

Well, for what it’s worth… I ended up with the following web.config file in my Task_Manager directory.

Notes:
1/ I created a “Task_Manager” application within a local website – the web.config changes were to that application only.
2/ Instead of having to modify the .htaccess file that Apache uses, I had to use the URL Rewrite module (which sometimes isn’t installed by default on IIS) to create the “Task_ManagerApi Rule” above.
3/ PHP is installed on *my* system using FastCGI – it might not be FastCGI on your setup and the .exe will be in a different location but, wherever it is, there will be a handler mapping for *.php files. The problem here is that IIS doesn’t allow PUT and DELETE verbs as default. I had to override this.
4/ I used the IIS Manager to make the web.config changes above – I did not write the web.config file by hand (although you can if you are careful).

Shivendra Dubey
Shivendra Dubey
6 years ago

Hi there i need your help, m constantly getting an error for as “Fatal error: Call to undefined method mysqli_stmt::get_result()” even though the mysqli and mysqlnd are enabled and running with latest php version. why the error is continue..

Shivendra Dubey
Shivendra Dubey
6 years ago

please reply…

Douglas Roos
Douglas Roos
6 years ago

I had the same issue but with GoDaddy hosting, So i’ve changed the $stmt->get_result()->$fetch_assoc() to $stmt->bind_result($id);

while ($stmt->fetch()){

$user_id = array(“id”=>$id);

}

And that’s it

Jason Shen
Jason Shen
6 years ago
Reply to  Douglas Roos

Hi Gouglas
just wondering how did you change your get task function to make it to work with bind_result instead of get_result, i am like stuck on that at the moment any help would be awesome cheers
jason

Hoàng Bảo Dương Hùng
Hoàng Bảo Dương Hùng
6 years ago

Hi,
I want upload image via rest api for android using php slim :(. Please guide for me.

gnuManiac
gnuManiac
6 years ago

Hi,
great job but i need your help.
For me “getting all tasks” it’s broken (500 Internal error – Response does not contain any data).

Getting single task with no problems.

gnuManiac
gnuManiac
6 years ago
Reply to  gnuManiac

get_result() failure.
Solved installing php5-mysqlnd

Muhammad Awais
Muhammad Awais
6 years ago

Mannnn !!! u r Awesome !!!! Thanksss alot for restful api tutorial.. :))) carry on

Guest
Guest
6 years ago

Hi,

Thanks for the Tutorial. I am having an issue when i Register an new user. I modified the parameters but i get the following message when i execute the request, “Response does not contain any data.”

Could you kindly help me out. Thanks

Craig Daly
Craig Daly
6 years ago

Is anyone getting an ‘500 Internal Server Error’ message while using the Advanced Rest Client? I’m using MAMP on a Mac running OS X 10.9.2 Mavericks. Great tutorial, btw!!

Eugene Kiver
Eugene Kiver
6 years ago
Reply to  Craig Daly

You shoul’ve check your wamp directory for apache logs, I found the error desciption and googled for solution, in wamp you can click on it in windows bottom tray (or how they all it) then go to Apache->Apache Modules->Rewrite module. It turns out that it is disabled by default.

Craig Daly
Craig Daly
6 years ago

@walox checked the httpd.conf file & everything looks fine. here’s my output:

Status
500 Internal Server Error Loading time: 35
Request headers
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.4 Safari/537.36
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
Authorization: bf45c093e542f057caee68c47787e7d6
Content-Type: application/x-www-form-urlencoded
Accept: */*
DNT: 1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: SQLiteManager_currentLangue=2

Response headers
Date: Sun, 30 Mar 2014 19:56:22 GMT
Server: Apache/2.2.26 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.6 PHP/5.5.10 mod_ssl/2.2.26 OpenSSL/0.9.8y DAV/2 mod_perl/2.0.8 Perl/v5.18.0
X-Powered-By: PHP/5.5.10
Content-Length: 1980
Connection: close
Content-Type: text/html

and here’s the response callback:
Slim Application Error
#1 /Applications/MAMP/htdocs/manage_tasks/include/DbConnect.php(31): DbConnect::connect()
#2 /Applications/MAMP/htdocs/manage_tasks/include/DbHandler.php(19): DbConnect->connect()
#3 /Applications/MAMP/htdocs/manage_tasks/v1/index.php(74): DbHandler->__construct()
#4 [internal function]: {closure}()
#5 /Applications/MAMP/htdocs/manage_tasks/libs/Slim/Route.php(436): call_user_func_array(Object(Closure), Array)
#6 /Applications/MAMP/htdocs/manage_tasks/libs/Slim/Slim.php(1307): SlimRoute->dispatch()
#7 /Applications/MAMP/htdocs/manage_tasks/libs/Slim/Middleware/Flash.php(85): SlimSlim->call()
#8 /Applications/MAMP/htdocs/manage_tasks/libs/Slim/Middleware/MethodOverride.php(92): SlimMiddlewareFlash->call()
#9 /Applications/MAMP/htdocs/manage_tasks/libs/Slim/Middleware/PrettyExceptions.php(67): SlimMiddlewareMethodOverride->call()
#10 /Applications/MAMP/htdocs/manage_tasks/libs/Slim/Slim.php(1254): SlimMiddlewarePrettyExceptions->call()
#11 /Applications/MAMP/htdocs/manage_tasks/v1/index.php(339): SlimSlim->run()
#12 {main}

I can’t tell if it’s a php coding error based in the 1st 2 lines of the response callback or if it’s an MAMP issue.

Mert Aksoy
Mert Aksoy
6 years ago

PHP Fatal error: Call to undefined function apache_request_headers() in /public_html/task_manager/v1/index.php on line 20

added this function:

if(!function_exists(‘apache_request_headers’)) {
function apache_request_headers() {

$headers = array();

foreach($_SERVER as $key => $value) {

if(substr($key, 0, 5) == ‘HTTP_’) {

$headers[str_replace(‘ ‘, ‘-‘, ucwords(str_replace(‘_’, ‘ ‘, strtolower(substr($key, 5)))))] = $value;

}else if($key == “Authorization”){

$headers[$key] = $value;

}

}

return $headers;

}

}

now i couldnt see the value authorization in headers

Jesús Expósito
Jesús Expósito
6 years ago
Reply to  Mert Aksoy

Any fix to this issue? I use a similar function but the result is the same. Can’t see the auth header.

if(!function_exists(‘apache_request_headers’)){

function apache_request_headers(){

static $arh = array();

if (!$arh){

$rx_http = ‘/AHTTP_/’;

foreach ($_SERVER as $key => $val){

if(preg_match($rx_http, $key)){

$arh_key = preg_replace($rx_http, ”, $key);

$rx_matches = array();

// do some nasty string manipulations to restore the original letter case

// this should work in most cases

$rx_matches = explode(‘_’, $arh_key);

if( count($rx_matches) > 0 and strlen($arh_key) > 2 ){

foreach($rx_matches as $ak_key => $ak_val)

{

$rx_matches[$ak_key] = ucfirst($ak_val);

}

$arh_key = implode(‘-‘, $rx_matches);

}

$arh[$arh_key] = $val;

}

}

}

return $arh;

}

}

dfdsafsdds
dfdsafsdds
6 years ago

what r u doing bro 🙂

Brendan
Brendan
6 years ago
Reply to  Mert Aksoy

Ravi,

A million thanks for this – it is easily the best example on the net of an authorization based restful api for PHP.

Also it is brilliantly presented and coded – big kudos to you!!!

Hi – I’ve just got this working on PHP 5.3 install – where the apache_request_headers does not exist.

You need to follow up with two changes.

1. Update your .htaccess file with

RewriteRule .* – [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

This will add the variable HTTP_AUTHORIZATION such that $_Server will report on it.

2. In the replacement function – the process to produce first character uppercase needs changed

From:
$rx_matches[$ak_key] = ucfirst($ak_val);

To:
$rx_matches[$ak_key] = ucfirst(strtolower($ak_val));

Basically the function ucfirst does not work if the variable is already uppercase.

Do both of these changes and voila – Authorization is presented and the scripts work.

Lesly de Domilys
6 years ago

Hi there are 2 errors in the DbHandler.php and DbConnect php files. You need to remove the “.” in the “./DbHandler” and “./Config.php” expression at lines 15.

Dũng
Dũng
6 years ago

how to register direct on url
example api other: domain/Servers/Login/password:12z/username:12z

how to use in your project.
please help me.

endder
endder
6 years ago

Any news about the 3rd part?

jpgrassi
jpgrassi
6 years ago

Great post, thanks!

I have only one question, all your methods use the parameters in the body. What changes do I need to make to accept json as parameters instead of body parameters?

schlocke
schlocke
6 years ago
Reply to  jpgrassi

I believe all request have a body, so instead of:

parse_str($app->request()->getBody(), $request_params);

you would do:

$array = array();
$array = json_decode($app->request()->getBody());

Guest
Guest
6 years ago

thanks for all your effort man, I have a problem in the file DbHandler.php exactly in the line 221:

$new_task_id = $this->conn->insert_id;

where is defined insert_id ?

thanks.

766
0
Would love your thoughts, please comment.x
()
x