0

0

自己创建一个Rest API

php中文网

php中文网

发布时间:2016-07-29 08:59:26

|

1777人浏览过

|

来源于php中文网

原创

2015.10 大三上 面向web的计算课程

在大三上的课程中,海涛老师要求项目中运用rest进行数据采集。我两眼懵逼,啥是rest呀?然后就去网上找了学习资料。然后之后就着手开始自己写一个rest api。为什么要自己写呢?因为我没用框架自己创建一个Rest API,第一次使用php做网站,我想先打好基础再考虑高层次的东西,就没有用框架。其他人用的诸如laravel之类的PHP框架自己本身会带rest机制。对于我一个没用框架的孩子,只能自己默默写了。

当然,有参考例子哦http://www.gen-x-design.com/archives/create-a-rest-api-with-php/,不过这个例子一点都不全面,我自己补充了很多。

<?php


class RestUtils
{
 public static function processRequest()
    {
        // get our verb
        $request_method = strtolower($_SERVER['REQUEST_METHOD']);
        $return_obj     = new RestRequest();
        // we'll store our data here
        $data           = array();
    
        switch ($request_method)
        {
            // gets are easy...
            case 'get':
                $data = $_GET;
                break;
                // so are posts
            case 'post':
                $data = $_POST;
                break;
                // here's the tricky bit...
            case 'put':
            case 'delete':
                // basically, we read a string from PHP'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('php://input');
                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><div class="aritcle_card flexRow">
                                                        <div class="artcardd flexRow">
                                                                <a class="aritcle_card_img" href="/ai/1268" title="Imagine Me"><img
                                                                                src="https://img.php.cn/upload/ai_manual/001/431/639/68b6db4754952805.png" alt="Imagine Me"  onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
                                                                <div class="aritcle_card_info flexColumn">
                                                                        <a href="/ai/1268" title="Imagine Me">Imagine Me</a>
                                                                        <p>利用AI技术创建自己的个人模型</p>
                                                                </div>
                                                                <a href="/ai/1268" title="Imagine Me" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
                                                        </div>
                                                </div>  
                                <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;
    }
 
}


?>

难点是对于http请求头的解析真是让我吐血啊,那个时候我还不知道chrome可以看请求内容,我的做法是简陋地输出来看。之后解析时狂补了一通正则表达式,最后用正则顺利解析了。

我这不能API直接用啊,里面有我网站里分析健康数据的例子,你们也可以看到,后半段大量地出现“health",就是我的网站中的获取健康数据的例子啊。

因为时间紧急,所以只用半天写出来的API,大概是又简陋又有很多不足的吧。不过想到这个项目最终检查时有那么多同学没有实现rest,而我没有用框架自己学习rest,实现了一个自己的api,也是挺开心的。

以上就介绍了自己创建一个Rest API,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1142

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

371

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

245

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

37

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

114

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

77

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

17

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

863

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

123

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 18.7万人学习

Pandas 教程
Pandas 教程

共15课时 | 1.1万人学习

C# 教程
C# 教程

共94课时 | 10.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号