restful+ci框架 实践

restful架构:

是就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。具体理论请看我上一篇写的restful理论。本篇主要记录下关于restful的实践。

restful实践:

工具:

这次在ci框架+restful

主要文件:

在控制器中添加控制器类:Restful.php。

在头部包含REST_Controller.php文件并继承

require APPPATH.'/libraries/REST_Controller.php';

class Widgets extends REST_Controller

在routes.php文件添加路由:

$route['Admin/([A-Za-z0-9]+)/(\d+)'] = "Admin/$1/index/$2";//路由可以根据个人的需求更改

在config/文件夹下添加rest.php文件。用于rest的配置(我这边都是返回地xml格式,如果需要返回其它格式,可以修改rest.php配置文件)

/*
|--------------------------------------------------------------------------
| REST Format
|--------------------------------------------------------------------------
|
| What format should the data be returned in by default?
|
|	Default: xml
|
*/
$config['rest_default_format'] = 'xml';

在application/libraries/文件下添加REST_Controller.php文件

具体代码解释:

restful   get的请求:

    function index_get($id = '')
    {
    	// Example data for testing.
    	$widgets = array(
    			1 => array('id' => 1, 'name' => 'sprocket'),
    			2 => array('id' => 2, 'name' => 'gear')
    	);
    	 
    	if (!$id) { $id = $this->get('id'); }//get方法调用的是REST_Controller类 中的http get方式带的参数
    	if (!$id)
    	{    		    		
    		if($widgets)
    			$this->response($widgets, 200); // 200 being the HTTP response code//REST_Controller类中的指定格式的输出。默认xml
    		else
    			$this->response(array('error' => 'Couldn\'t find any widgets!'), 404);
    	}

        //$widget = $this->widgets_model->getWidget($id);
    	$widget = @$widgets[$id]; // test code

        if($widget)
            $this->response($widget, 200); // 200 being the HTTP response code
        else
            $this->response(array('error' => 'Widget could not be found'), 404);//responce方式是调用的ci框架的output类输出的
    }
用Chrome浏览器的postman插件模拟http请求:

get_1
解释:

(1)Admin是ci控制器下的新建目录。 rest.com/Admin/restful/2  根据自己上面定义的路由规则。路由到/Admin/restful/index/2

(2)在继承REST_Controller类中走的_remap()方法。会走到/Admin/restful/index_get  因为是get方式请求。所以是index_get

    function _remap($object_called)
    {
        $controller_method = $object_called.'_'.$this->method;

        if(method_exists($this, $controller_method))
        {
            $this->$controller_method();
        }

        else
        {
            show_404();
        }
    }
(3)2作为参数放在REST_Controller类的成员属性中

    function __construct()
    {
        parent::__construct();

        // How is this request being made? POST, DELETE, GET, PUT?
        $this->method = $this->_detect_method();//get

        // Lets grab the config and get ready to party
        $this->load->config('rest');

        if($this->config->item('rest_auth') == 'basic')
        {
            $this->_prepareBasicAuth();
        }

        elseif($this->config->item('rest_auth') == 'digest')
        {
            $this->_prepareDigestAuth();
        }

        // Set up our GET variables
        $this->get_args = $this->uri->uri_to_assoc();//获取参数
		$this->get_args = array_keys($this->get_args);
		$this->get_args = array('id'=>$this->get_args[0]);
		
		//var_dump($this->put_args);

        // Set up out PUT variables
        parse_str(file_get_contents('php://input'), $this->put_args);// put 是以表单的形式发送
        // Merge both for one mega-args variable
        $this->args = array_merge($this->get_args, $this->put_args);
        // Which format should the data be returned in?
        $this->format = $this->_detect_format();//设置参数方式  json 、 xml
    }

restful  post请求:

    function index_post()
    {
		//var_dump($this->post('name'));
		$data = $this->post('name');
        //$data = $this->_post_args;
        try {
            //$id = $this->widgets_model->createWidget($data);
            $id = 3; // test code
            //throw new Exception('Invalid request data', 400); // test code
            //throw new Exception('Widget already exists', 409); // test code
        } catch (Exception $e) {
            // Here the model can throw exceptions like the following:
            // * For invalid input data: new Exception('Invalid request data', 400)
            // * For a conflict when attempting to create, like a resubmit: new Exception('Widget already exists', 409)
            $this->responce(array('error' => $e->getMessage()), $e->getCode());
        }
        if ($id) {
            $widget = array('id' => $id, 'name' => $data); // test code
            //$widget = $this->widgets_model->getWidget($id);
            $this->responce($widget, 201); // 201 being the HTTP responce code
        } else
            $this->responce(array('error' => 'Widget could not be created'), 404);
    }

postman模拟请求:

post_1

restful  put请求:

源代码获取put参数:

parse_str(file_get_contents('php://input'), $this->put_args);// put 是以表单的形式发送
restful.php控制器文件  put代码:

    public function index_put()
    {
		$data = $this->put('');
        //$data = $this->_put_args;
        try {
            //$id = $this->widgets_model->updateWidget($data);
            $id = $data['id']; // test code
            //throw new Exception('Invalid request data', 400); // test code
        } catch (Exception $e) {
            // Here the model can throw exceptions like the following:
            // * For invalid input data: new Exception('Invalid request data', 400)
            // * For a conflict when attempting to create, like a resubmit: new Exception('Widget already exists', 409)
            $this->responce(array('error' => $e->getMessage()), $e->getCode());
        }
        if ($id) {
            $widget = array('id' => $data['id'], 'name' => $data['name']); // test code
            //$widget = $this->widgets_model->getWidget($id);
            $this->responce($widget, 200); // 200 being the HTTP responce code
        } else
            $this->responce(array('error' => 'Widget could not be found'), 404);
    }

postman模拟http put请求:(注意put是x-www-form-urlencoded方式,也就是表单)

put_1


restful delete请求:

    function index_delete($id = '')
    {

        // Example data for testing.
        $widgets = array(
            1 => array('id' => 1, 'name' => 'sprocket'),
            2 => array('id' => 2, 'name' => 'gear'),
            3 => array('id' => 3, 'name' => 'nut')
        );

        if (!$id) {
            $id = $this->get('id');
        }
        if (!$id) {
            $this->responce(array('error' => 'An ID must be supplied to delete a widget'), 400);
        }

        //$widget = $this->widgets_model->getWidget($id);
        $widget = @$widgets[$id]; // test code

        if ($widget) {
            try {
                //$this->widgets_model->deleteWidget($id);
                //throw new Exception('Forbidden', 403); // test code
            } catch (Exception $e) {
                // Here the model can throw exceptions like the following:
                // * Client is not authorized: new Exception('Forbidden', 403)
                $this->responce(array('error' => $e->getMessage()), $e->getCode());
            }
            $this->responce($widget, 200); // 200 being the HTTP responce code
        } else
            $this->responce(array('error' => 'Widget could not be found'), 404);
    }

postman模拟http delete请求:

delete_1

关于restful实践一些思考&结论:

1.以上restful.php控制器类的 get、post、put、delete是业务逻辑处理,得根据业务场景修改。

2.get是资源的查询,post是资源的新建或者修改,put是资源的修改,delete是资源的删除,由于put和delete可以由get&post代替,所以一般put和delete比较少见,post是资源新建,点击多次请求时,返回的数据不一样,但是get、delete、put请求时不停的请求相同的URI返回的数据是一样的。

3.restful中URI资源定位符一般是:/resource_name/param。param是方法名称还是参数值?

我的思考是:

p1.方法名称是可变的。不指定方法名称的话不知道走哪个方法的逻辑

a1:方法名称可以是resource_get、resource_post、resource_put、resource_delete。也就是后面添加请求方式

p1:但是这样控制器只有这几个方法了。类似于数据库的CURD操作。不仅有select一个还有select所有等。

a1:restful规范是:param就是id值,因为一个id值一定可以找到一条资源

p1:首先资源不一定知道id而是知道这资源的其它特性,还有id可以和上文put请求一样放在header的请求头中。

我公司用到的restful架构中 param就是指定方法的。但是在网上看都是id值。有没有知道param到底是id值还是方法名,还是说根据业务场景而定?


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值