1

I'm trying to implement a RESTful API for my web app.
I have learned from some tutorials how to write the classes for REST API service.

However, in one of the tutorials, they use AngularJS to send HTTP.delete requests to the server on button clicks.
If I don't want to use AngularJS, how can I set the request method in the HTML form to delete a specified user?

For example, if I go to localhost/app/api/user/3
I will get the information of User of id 3 in JSON representation because the default request method is GET.

How can I send delete request to localhost/app/api/user/3 and to delete this user?

In HTML forms, there are only POST and GET methods.

I also don't know how the PUT works...

The following are the classes:

<?php
class REST {
  public $_request_args = array();
  private $_method = "";
  public $_content_type = "application/json";
  private $_code = 200;

  public function __construct() {
      $this->inputs();
  }

  private function inputs() {
    $this->_method = $this->get_request_method();
    switch($this->_method){
        case "POST":
            $this->_request_args = $this->cleanInputs($_POST);
            break;
        case "GET":
            $this->_request_args = $this->cleanInputs($_GET);
            break;
        case "DELETE":
        case "PUT":
            parse_str(file_get_contents("php://input"),$this->_request_args);
            $this->_request_args = $this->cleanInputs($this->_request_args);
            break;
        default:
            $this->response('Method Not Allowed',405);
            break;
      }
  }

  private function get_status_message(){
      $status = array(
        200 => 'OK', 
        204 => 'No Content',  
        404 => 'Not Found',  
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        500 => 'Internal Server Error');
      return ($status[$this->_code]) ? $status[$this->_code] : $status[500];
  }

  public function get_request_method(){
      $request_method = $_SERVER['REQUEST_METHOD'];
      if ($request_method == 'POST' && array_key_exists('HTTP_X_HTTP_METHOD', $_SERVER)) {
          if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'DELETE') {
            $request_method = 'DELETE';
          } else if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'PUT') {
            $request_method = 'PUT';
          } else {
            throw new Exception("Unexpected Header");
          }
      }
      return $request_method;
  }

  private function cleanInputs($data){
      $clean_input = array();
      if (is_array($data)) {
         foreach ($data as $k => $v) {
            $clean_input[$k] = $this->cleanInputs($v);
         }
      } else {
         if(get_magic_quotes_gpc()) {
            $data = trim(stripslashes($data));
         }
         $data = strip_tags($data);
         $clean_input = trim($data);
      }
      return $clean_input;
   }        

   private function set_headers() {
      header("HTTP/1.1 ".$this->_code." ".$this->get_status_message());
      header("Content-Type:".$this->_content_type);
   }

   public function response($data, $status = 200) {
       $this->_code = ($status)? $status : 200;
       $this->set_headers();
       if (is_array($data))
          echo json_encode($data, JSON_PRETTY_PRINT);
       else
          echo $data;
       exit;
    }
}   
?>

//EDIT::

<?php
class API extends REST {
public $data = "";
public function processApi() {
    $request_args = explode('/', rtrim($_SERVER["PATH_INFO"], '/'));
    $func = array_shift($request_args);
    if(method_exists($this, $func))
        $this->$func();
    else {
        $this->response('',404); // If the method not exist with in this class "Page not found".
     }
  }

  private function users() {
    if($this->get_request_method() != "GET"){
        $this->response('',405);
    }
    $conn = DBManager::getConnection();
    $stmt = $conn->prepare("SELECT * FROM USER");
    $stmt->execute();
    $result = $stmt->fetchAll();
    $this->response($result);
  }

  private function courses() {
    if($this->get_request_method() != "GET"){
        $this->response('',405);
    }
    $conn = DBManager::getConnection();
      $stmt = $conn->prepare("SELECT * FROM COURSE");
      $stmt->execute();
      $result = $stmt->fetchAll();
      $this->response($result);
   }

   private function subjects() {
       if($this->get_request_method() != "GET"){
          $this->response('',405);
       }
       $conn = DBManager::getConnection();
       $stmt = $conn->prepare("SELECT * FROM SUBJECT");
       $stmt->execute();
       $result = $stmt->fetchAll();
       $this->response($result);
   }
}

$api = new API;
$api->processApi();
?>

So my question is if I have a form like the following:

<form action='api/users/3' method='POST'>
    <input type='submit' value='Delete User' />
</form>

How can I actually delete this user with that request even though the method is POST not DELETE?

I have checked other posts and there's no answer to this question!

  • Possible duplicate of [HTTP protocol's PUT and DELETE and their usage in PHP](http://stackoverflow.com/questions/27941207/http-protocols-put-and-delete-and-their-usage-in-php) – Julio Soares Oct 03 '15 at 13:01
  • There is a good explanation here http://stackoverflow.com/questions/27941207/http-protocols-put-and-delete-and-their-usage-in-php – Julio Soares Oct 03 '15 at 13:01

2 Answers2

2

Browsers do not support HTTP DELETE and PUT methods in HTML Forms. To get support for the DELETE method, you can insert a pseudo "method" (a hidden text element) in your FORM, this is how the Slim and Breeze router / "micro-framework" handles PUT and DELETE methods.

<form action='api/users/3' method='POST'>
    <input type="hidden" name="_method" value="PUT | DELETE" />
    <input type='submit' value='Delete User' />
</form>

In Breeze, using the DELETE method will look like this in your PHP script:

delete('/', function(){
    echo 'you made a DELETE request';
});

You may be able to do something similar. Alternatively, you may consider switching to a REST router or micro-framework that comes with support for DELETE and PUT.

Kristoffer Bohmann
  • 3,986
  • 3
  • 28
  • 35
1

for Google Chrome, you can install a very helpful extension that helps you to develop and test your REST API: Advanced REST Client

Also, you need to specify the HTTP.delete case as the following:

case "DELETE":
    parse_str(file_get_contents("php://input"),$this->_request_args);
    $this->_request_args = $this->cleanInputs($this->_request_args);
    break;

There seems to be something wrong with the processApi() function because that's not how you get the arguments.

Fix your HTACCESS file to redirect URLs properly.

Follow this tutorial for more info: http://coreymaynard.com/blog/creating-a-restful-api-with-php/