Create a Rest API yourself

WBOY
Release: 2016-07-29 08:59:26
Original
1601 people have browsed it

2015.10 Web-oriented computing course for junior year

In the course for junior year, teacher Haitao asked to use REST for data collection in the project. I was confused, what is rest? Then I went online to find study materials. Then I started writing a rest api myself. Why write it yourself? Because I didn’t use a frameworkCreate a Rest API yourself. It was my first time to use PHP to build a website. I wanted to lay the foundation first and then consider high-level things, so I didn’t use a framework. PHP frameworks such as laravel used by others will have rest mechanisms themselves. For me, a child who has no use of frameworks, I can only write silently by myself.

Of course, there is a reference example http://www.gen-x-design.com/archives/create-a-rest-api-with-php/, but this example is not comprehensive at all. I have added a lot myself. .

<?php


class RestUtils
{
 public static function processRequest()
    {
        // get our verb
        $request_method = strtolower($_SERVER[&#39;REQUEST_METHOD&#39;]);
        $return_obj     = new RestRequest();
        // we&#39;ll store our data here
        $data           = array();
    
        switch ($request_method)
        {
            // gets are easy...
            case &#39;get&#39;:
                $data = $_GET;
                break;
                // so are posts
            case &#39;post&#39;:
                $data = $_POST;
                break;
                // here&#39;s the tricky bit...
            case &#39;put&#39;:
            case &#39;delete&#39;:
                // basically, we read a string from PHP&#39;s special input location,
                // and then parse it out into an array via parse_str... per the PHP docs:
                // Parses str  as if it were the query string passed via a URL and sets
                // variables in the current scope.
                $string=file_get_contents(&#39;php://input&#39;);
                preg_match_all("|\".*\"|",$string,$out1, PREG_PATTERN_ORDER);
                preg_match_all("|\"\s+.*\s+------|",$string,$out2, PREG_PATTERN_ORDER);
                for($i=0;$i<count($out2[0]);$i++){
                    $out1[0][$i]=explode("\"", $out1[0][$i])[1];
                    $out2[0][$i]=explode("\n", $out2[0][$i])[2];
                    $out2[0][$i]=trim($out2[0][$i]);
                }
                $data=array();
                for($i=0;$i<count($out2[0]);$i++){
                     $data[$out1[0][$i]] = $out2[0][$i];
                }     
                break;
            
           
        }
    
        // store the method
        $return_obj->setMethod($request_method);
    
        // set the raw data, so we can access it if needed (there may be
        // other pieces to your requests)
        $return_obj->setRequestVars($data);
    
        if(isset($data['data']))
        {
            // translate the JSON to an Object for use however you want
            $return_obj->setData(json_decode($data['data']));
        }
        return $return_obj;
    }

public static function sendResponse($status = 200, $body = '', $content_type = 'text/html')  
    {  
        $status_header = 'HTTP/1.1 ' . $status . ' ' . RestUtils::getStatusCodeMessage($status);  
        // set the status  
        header($status_header);  
        // set the content type  
        header('Content-type: ' . $content_type);  
  
        // pages with body are easy  
        if($body != '')  
        {  
            // send the body  
            echo $body;  
            exit;  
        }  
        // we need to create the body if none is passed  
        else  
        {  
            // create some body messages  
            $message = '';  
  
            // this is purely optional, but makes the pages a little nicer to read  
            // for your users.  Since you won't likely send a lot of different status codes,  
            // this also shouldn't be too ponderous to maintain  
            switch($status)  
            {  
                case 401:  
                    $message = 'You must be authorized to view this page.';  
                    break;  
                case 404:  
                    $message = 'The requested URL ' . $_SERVER['REQUEST_URI'] . ' was not found.';  
                    break;  
                case 500:  
                    $message = 'The server encountered an error processing your request.';  
                    break;  
                case 501:  
                    $message = 'The requested method is not implemented.';  
                    break;  
            }  
  
            // servers don't always have a signature turned on (this is an apache directive "ServerSignature On")  
            $signature = ($_SERVER['SERVER_SIGNATURE'] == '') ? $_SERVER['SERVER_SOFTWARE'] . ' Server at ' . $_SERVER['SERVER_NAME'] . ' Port ' . $_SERVER['SERVER_PORT'] : $_SERVER['SERVER_SIGNATURE'];  
  
            // this should be templatized in a real-world solution  
            $body = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
                        <html>  
                            <head>  
                                <meta http-equiv="Content-Type" c/html; charset=iso-8859-1">  
                                <title>' . $status . ' ' . RestUtils::getStatusCodeMessage($status) . '</title>  
                            </head>  
                            <body>  
                                <h1>' . RestUtils::getStatusCodeMessage($status) . '</h1>  
                                <p>' . $message . '</p>  
                                <hr />  
                                <address>' . $signature . '</address>  
                            </body>  
                        </html>';  
  
            echo $body;  
            exit;  
        }  
    }  

    public static function getStatusCodeMessage($status)
    {
        // these could be stored in a .ini file and loaded
        // via parse_ini_file()... however, this will suffice
        // for an example
        $codes = Array(
            100 => 'Continue',
            101 => 'Switching Protocols',
            200 => 'OK',
            201 => 'Created',
            202 => 'Accepted',
            203 => 'Non-Authoritative Information',
            204 => 'No Content',
            205 => 'Reset Content',
            206 => 'Partial Content',
            300 => 'Multiple Choices',
            301 => 'Moved Permanently',
            302 => 'Found',
            303 => 'See Other',
            304 => 'Not Modified',
            305 => 'Use Proxy',
            306 => '(Unused)',
            307 => 'Temporary Redirect',
            400 => 'Bad Request',
            401 => 'Unauthorized',
            402 => 'Payment Required',
            403 => 'Forbidden',
            404 => 'Not Found',
            405 => 'Method Not Allowed',
            406 => 'Not Acceptable',
            407 => 'Proxy Authentication Required',
            408 => 'Request Timeout',
            409 => 'Conflict',
            410 => 'Gone',
            411 => 'Length Required',
            412 => 'Precondition Failed',
            413 => 'Request Entity Too Large',
            414 => 'Request-URI Too Long',
            415 => 'Unsupported Media Type',
            416 => 'Requested Range Not Satisfiable',
            417 => 'Expectation Failed',
            500 => 'Internal Server Error',
            501 => 'Not Implemented',
            502 => 'Bad Gateway',
            503 => 'Service Unavailable',
            504 => 'Gateway Timeout',
            505 => 'HTTP Version Not Supported'
        );

        return (isset($codes[$status])) ? $codes[$status] : '';
    }
}

class RestRequest
{
    private $request_vars;
    private $data;
    private $http_accept;
    private $method;

    public function __construct()
    {
        $this->request_vars      = array();
        $this->data              = '';
        $this->http_accept       = (strpos($_SERVER['HTTP_ACCEPT'], 'json')) ? 'json' : 'xml';
        $this->method            = 'get';
    }

    public function setData($data)
    {
        $this->data = $data;
    }

    public function setMethod($method)
    {
        $this->method = $method;
    }

    public function setRequestVars($request_vars)
    {
        $this->request_vars = $request_vars;
    }

    public function getData()
    {
        return $this->data;
    }

    public function getMethod()
    {
        return $this->method;
    }

    public function getHttpAccept()
    {
        return $this->http_accept;
    }

    public function getRequestVars()
    {
        return $this->request_vars;
    }
    
   
    
    
    
}


$data = RestUtils::processRequest();

switch($data->getMethod())
{
    case 'get':
      //  print_r($data->getRequestVars());
        $infoType=$data->getRequestVars()['infoType'];
        if (array_key_exists("username",$data->getRequestVars())) {
            $username=$data->getRequestVars()['username'];
            if($data->getHttpAccept() == 'json'){
                if($infoType=="health"){
                     $healthService=new HealthService();
                     $result=$healthService->getUserHealth($username);
                     if($result==""){
                         RestUtils::sendResponse(404, "Not Found");
                     }
                     else{
                         RestUtils::sendResponse(200, json_encode($result), 'application/json');
                     }
                }
           
            }
            else if ($data->getHttpAccept() == 'xml'){
                if($infoType=="health"){
                    $healthService=new HealthService();
                    $result=$healthService->getUserHealth($username);
                    if($result==""){
                        RestUtils::sendResponse(404, "NOT FOUND");
                    }
                    else{
                        $health=new HealthXML();
                        RestUtils::sendResponse(200, $health->create_xml($result),'application/xml');
                    }
                }
              
            }
        }

        break;
        
    case 'post':
        $infoType=$data->getRequestVars()['infoType'];
        if($infoType=="health"){
           $username=$data->getRequestVars()['username'];
           $height=$data->getRequestVars()['height'];
           $weight=$data->getRequestVars()['weight'];
           $date=$data->getRequestVars()['date'];
           $healthService=new HealthService();
           $ID=$healthService->addHealthWithDate($username, $height, $weight, $date); 
           $health=new HealthXML();
           $data_array = array(
            array(
                    'ID' => $ID,                 
                )
            );   
           RestUtils::sendResponse(201, $health->create_IDxml($data_array));
        }
         
        break;
     
    case 'put':
       // print_r($data->getRequestVars());
        $infoType=$data->getRequestVars()['infoType'];
      //  echo $infoType;
      //  echo $infoType=="health"?"true":"false";
        if($infoType=="health"){
            $ID=$data->getRequestVars()['ID'];
            $username=$data->getRequestVars()['username'];
            $height=$data->getRequestVars()['height'];
            $weight=$data->getRequestVars()['weight'];
            $date=$data->getRequestVars()['date'];
            $healthService=new HealthService();
            $result=$healthService->modifyHealthWithDate($ID, $username, $height, $weight, $date);
            if($result=="false"){
                RestUtils::sendResponse(400, "Bad Request");
            }
            else{
                $health=new HealthXML();
                RestUtils::sendResponse(200, $health->create_xml($result),'application/xml');
            }
        } 
       
        break;
     
    case 'delete':
            $infoType=$data->getRequestVars()['infoType'];
           if($infoType=="health"){
               $ID=$data->getRequestVars()['ID'];          
               $healthService=new HealthService();
               $result=$healthService->deleteHealth($ID);
               if($result==false){
                    RestUtils::sendResponse(404, "Not Found");
               }
               else{
                    RestUtils::sendResponse(204, "No Content");
               }
            } 
           
        break;        
}

class HealthXML{
   
    //  创建XML单项
    function create_item($ID_data,$username_data, $height_data , $weight_data, $dateTime_data)
    {
        $item = "<item>\n";
        $item .= "<ID>" . $ID_data . "</ID>\n";
        $item .= "<username>" . $username_data . "</username>\n";
        $item .= "<height>" . $height_data . "</height>\n";
        $item .= "<weight>" . $weight_data . "</weight>\n";
        $item .= " <dateTime>" . $dateTime_data . "</dateTime>\n";
        $item .= "</item>\n";
        return $item;
    }
    
    function create_xml($data_array){
        $title_size = 1;
        $xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
        $xml .= "<article>\n";
        foreach ($data_array as $data) {
            $xml .= $this->create_item($data['ID'],$data['username'], $data['height'], $data['weight'],$data['dateTime']);
        }
        $xml .= "</article>\n";
        return $xml;
    }
    
  
    
    //  创建XML单项
    function create_IDitem($ID_data)
    {
        $item = "<item>\n";
        $item .= "<ID>" . $ID_data . "</ID>\n";     
        $item .= "</item>\n";
        return $item;
    }
    
    function create_IDxml($data_array){
        $title_size = 1;
        $xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
        $xml .= "<article>\n";
        foreach ($data_array as $data) {
            $xml .= $this->create_IDitem($data['ID']);
        }
        $xml .= "</article>\n";
        return $xml;
    }
 
}


?>
Copy after login
The difficulty is that parsing the http request header really makes me vomit blood. At that time, I didn’t know that chrome could read the request content. My approach was to simply output it. After that, I added a lot of regular expressions during parsing, and finally parsed it smoothly using regular expressions.

I cannot use the API directly. There are examples of analyzing health data on my website. You can also see that "health" appears in large numbers in the second half, which is an example of obtaining health data on my website.

Due to time constraints, the API written in only half a day is probably crude and has many shortcomings. However, I am very happy when I think that so many students did not implement REST during the final inspection of this project, and I did not use the framework to learn REST myself and implemented an API of my own.

The above introduces how to create a Rest API by yourself, including the content. I hope it will be helpful to friends who are interested in PHP tutorials.

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!