对比CodeIgniter的REST_Controller和CI_Controller接收参数,输出的异同

REST_Controller可以方便的在get/post/put/delete里处理相关信息,CI_Controller在访问的时候是控制器/method的方式,两种各有优缺点。所以必要的时候,尽管以restfull思想为大前提,但是CI_Controller也是有必要用的。虽然REST_Controller继承自CI_Controller,但是在获得输入和输出的时候进行了大量的封装,如果用Rest_Controller时间长了,会忘了CI_Controller的本来面目。废话不说了,下面对最常用的get和post进行对比:

一,GET请求

CI_Controller的get

在controller文件夹下新建文件Test_ci.php,内容如下:

<?php

class Test_ci extends CI_Controller {
    public function print_user($name, $age = 24, $id = ‘3060411151‘, $website) {
//        //方式1
//        echo "name = " . $name . " age = " . $age;
//        echo ‘<br/>‘;
//
//        //方式2
        $data = array(‘name‘=>$name, ‘age‘=>$age, ‘id‘=>$id, ‘website‘=>$website);
        echo json_encode($data);
//
//        //方式3
//        $data = array(‘name‘=>$name, ‘age‘=>$age);
//        $this->output->set_output(json_encode($data));

        //方式4,标准url
//        parse_str($_SERVER[‘QUERY_STRING‘], $_GET);
//        $data = array(‘name‘=>$_GET[‘name‘], ‘age‘=>$_GET[‘age‘], ‘id‘=>$_GET[‘id‘], ‘website‘=>$_GET[‘website‘]);
//        echo json_encode($data);
    }
}

然后浏览器输入http://app.sod90.com/city52/test_ci/print_user/yanzi/0/4567进行测试,可以看到正常的json输出。

我们可以总结如下几点:

1,controllder/method/params1/params2/params3进行传递的,为了安全起见method里各个参数一定要写个默认值。这种传递方式必须按照顺序,依次传入,CI依次匹配,不能漏传。本例中如果传入/yanzi/67,这个67会作为age,而非id。

2,当请求为get时,且通过controllder/method/params1/params2/params3传递参数时,直接通过$_GET[‘name‘]是得不到值的,通过$this->input->get(‘name‘)同样的不到值。函数的输入参数即是get请求的参数。

3,在返回的时候直接echo即可,当然也可以用$this->output->set_output,也可以用exit().共同点是里面必须为string,如果为array要记得json_encode.

4,这种pathinfo的url好处是利于SEO,能让动态的url看起来像静态的一样。如本例的网址是http://app.sod90.com/city52/test_ci/print_user/yanzi/25/4567 我如果想统计‘yanzi‘这个name被访问的次数则直接分析url就可以了。但凡是有利也有弊,试想我想传个参数 website=http://blog.csdn.net/yanzi1225627, 那url地址就要这样:http://app.sod90.com/city52/test_ci/print_user/yanzi/25/4567/http://blog.csdn.net/yanzi1225627用这种pathinfo的url一定会跪。得到的结果如下:

这是因为CI区分参数时以‘/‘去匹配的。为了解决这个问题,我们只能用传统的标准url方式,方法也很简单:

1,在调用_$GET之前调用parse_str($_SERVER[‘QUERY_STRING‘], $_GET);一次, 就ok了。个别文档说还要将配置文件里的uri_protocol改为PATH_INFO 这是没有必要的,直接用默认的REQUEST_URI即可。

2,将原来控制器的方法里输入函数全部去掉。修改后的程序如下:

<?php

class Test_ci extends CI_Controller {
    public function print_user(/*$name, $age = 24, $id = ‘3060411151‘, $website*/) {
//        //方式1
//        echo "name = " . $name . " age = " . $age;
//        echo ‘<br/>‘;
//
//        //方式2
//        $data = array(‘name‘=>$name, ‘age‘=>$age, ‘id‘=>$id, ‘website‘=>$website);
//        echo json_encode($data);
//
//        //方式3
//        $data = array(‘name‘=>$name, ‘age‘=>$age);
//        $this->output->set_output(json_encode($data));

        //方式4,标准url
        parse_str($_SERVER[‘QUERY_STRING‘], $_GET);
        $data = array(‘name‘=>$_GET[‘name‘], ‘age‘=>$_GET[‘age‘], ‘id‘=>$_GET[‘id‘], ‘website‘=>$_GET[‘website‘]);
        echo json_encode($data);
    }
}

运行结果示例:

可以看到,完美解决了问题。但是直接使用$_GET不推荐这么做,如果key不存在会报错。事实上可以不输入parse_str($_SERVER[‘QUERY_STRING‘], $_GET);这句话,直接使用$this->input->get()就可以获得到get参数了。CI_Controller get请求的输入输出就介绍到这里。

REST_Controller的get

<?php
/**
 * Created by PhpStorm.
 * User: yanzi
 * Date: 15/11/20
 * Time: 上午7:54
 */
require_once APPPATH . ‘libraries/REST_Controller.php‘;
class Test_rest extends REST_Controller{
    public function index_get() {
        $data = array(
            ‘name‘=>$this->get(‘name‘),
            ‘age‘=>$this->get(‘age‘),
            ‘id‘=>$this->get(‘id‘)
        );
        $this->response($data);
    }
}

浏览器输入:http://app.sod90.com/city52/test_rest?name=yanzi&age=25&id=4567 可以看到效果如下:

当然代码里的$this->get(‘key‘),也可以换成$this->input->get(‘key‘)的写法。除此外,我们浏览器还可以输入一个分段式的url测试下:

http://app.sod90.com/city52/test_rest/name/yandzi/age/25/id/4567/format/json 结果很失望:

输入http://app.sod90.com/city52/test_rest?name/yandzi/age/25/id/4567/format/json ,结果依旧:

可以看到这进到了正确的方法里,但是未检测到参数。自始至终config里配置

$config[‘uri_protocol‘] = ‘REQUEST_URI‘;

将其改为path_info也是不行。但是rest_controller的官网 里有下面一段描述:

但是经过验证并没有成功。我在apache和nginx上都测试过了,均不行。不知是我环境问题还是咋回事。

二,POST请求

CI_Controller的POST

post请求两者比较简单,CI_Controller使用 $_POST[‘key‘]或$this->input->post()就可以获得到参数,REST_Controller使用$this->post(‘key‘)获得。

前者的测试代码:

    public function print_user2(){
        $data = array(‘name‘=>$_POST[‘name‘], ‘age‘=>$_POST[‘age‘], ‘id‘=>$_POST[‘id‘], ‘website‘=>$_POST[‘website‘]);
        echo json_encode($data);
    }

测试实例:

我们将代码里的$_POST[‘name‘]换成$this->input->post(‘name‘),结果依旧。但是唯一的区别是,在没有传‘name‘这个字段时,直接用$_POST[‘name‘]会报错,而用$this->input->post(‘name‘)得到的是null,因此我们应该尽量都用$this->input->post()来获得参数。

然后代码改为:

    public function print_user2(){
        $data = array(‘name‘=>$this->input->get(‘name‘), ‘age‘=>$_POST[‘age‘], ‘id‘=>$_POST[‘id‘], ‘website‘=>$_POST[‘website‘]);
        echo json_encode($data);
    }

即用来测试post请求里url后面还带参数的情况:

发现也是ok的。再将代码改下,试试直接传递参数:

   public function print_user2($name){
        $data = array(‘name‘=>$name, ‘age‘=>$_POST[‘age‘], ‘id‘=>$_POST[‘id‘], ‘website‘=>$_POST[‘website‘]);
        echo json_encode($data);
    }

结果也是ok的。但是你输入/name/yanziyan,是区分不出来name字段的。

REST_Controller的POST

测试代码:

<?php

/**
 * Created by PhpStorm.
 * User: yanzi
 * Date: 15/11/20
 * Time: 上午7:54
 */
require_once APPPATH . ‘libraries/REST_Controller.php‘;
class Test_rest extends REST_Controller{
    public function index_get() {
        $data = array(
            ‘name‘=>$this->get(‘name‘),
            ‘age‘=>$this->get(‘age‘),
            ‘id‘=>$this->get(‘id‘)
        );
        $this->response($data);
    }

    public function index_post(){
        $data = array(
            ‘name‘=>$this->post(‘name‘),
            ‘age‘=>$this->post(‘age‘),
            ‘id‘=>$this->post(‘id‘)
        );
        $this->response($data);
    }
}

使用POST_MAN进行测试:

再来测试下post请求里获取get参数的例子:

    public function index_post(){
        $data = array(
            ‘name‘=>$this->get(‘name‘),
            ‘age‘=>$this->post(‘age‘),
            ‘id‘=>$this->post(‘id‘)
        );
        $this->response($data);
    }

可以看到并未接收到name这个参数。
但是不用怕,将$this->get()换成$this->input->get()试一下:

    public function index_post(){
        $data = array(
            ‘name‘=>$this->input->get(‘name‘),
            ‘age‘=>$this->post(‘age‘),
            ‘id‘=>$this->post(‘id‘)
        );
        $this->response($data);
    }

测试:

这样就能收到参数了。除此外,使用$this->query()也是可以获得到post里的url参数的。但是query是获得不到post参数的。

再来测试下/key/params的方式,发现还是不行:

最终的结论如下:

1,需明确$this->input->get()和$this->input->post()是CI_Controller提供的方法,Rest_Controller继承自CI_Controller除了这两个方法外,作者为我们提供了更简便的访问方式:$this->get(), $this->post(), $this->query().

2,不推荐使用_$GET和_$POST来获得参数,原因是字段未传时将会报错。在CI_Controller里如果使用_$GET(仅当使用key=params1&key2=params2这种方式传参数时),还要加上:parse_str($_SERVER[‘QUERY_STRING‘], $_GET);

3,CI_Controller和REST_Controller这两个控制器在访问上区别很大。Rest是按请求类型get/post自动给你路由到xxx_get()和xxx_post()里,url里只需要控制器的名字,不需要method的名字,CI是必须在url里指定函数名***/controller/method/params1/params2/params3

4,CI_Controller是支持***/controller/method/params1/params2/params3这种分段式url,往method这个函数依次传入数据,但是如果参数里本身有/就会有问题。所以必要时候还是得用***/controller/method?key1=params1&key2=params2这种方式

5,Rest_Controller不支持***/controller/method/params1/params2/params3这种段式传参,但是官网上说支持/controller/key1/params1/key2/params2,但是我在Nginx和apache上均没有成功。

6,$this->query能在rest的controller下,用来获取url里的参数(?key=params1&key2=params2),不管是不是get请求。也即post或put请求的url里传的参数。当然在post请求时也可以通过$this->input->get()获得url里的参数,通过$this->get()在post请求里是得不到url里的参数的。

7,$this->output->set_output()是CI_Controller提供的方法的,但在Rest里可以直接用$this->response()进行返回。在CI_Controller里如果嫌$this->output->set_output()太长,且只考虑反回数据的话可以使用echo 或exit直接返回数据。

参考文献:

1,restserver github:https://github.com/chriskacerguis/codeigniter-restserver

2,restserver guide:http://code.tutsplus.com/tutorials/working-with-restful-services-in-codeigniter-2--net-8814

3,CodeIgniter官网:http://codeigniter.org.cn/user_guide/libraries/output.html

------------------欢迎大家加入PHP CodeIgniter社区群:460132647,备注yanzi

时间: 2024-11-10 11:23:34

对比CodeIgniter的REST_Controller和CI_Controller接收参数,输出的异同的相关文章

Request 接收参数乱码原理解析一:服务器端解码原理

“Server.UrlDecode(Server.UrlEncode("北京")) == “北京””,先用UrlEncode编码然后用UrlDecode解码,这条语句永远为true吗?答案是否定的,结果可能与很多人预想的不大一样.本文主要分析这一问题出现的原理,研究下Server.UrlEncode(),Server.UrlDecode(),Request["xxx"]三个函数与编码方式的关系. 1. 问题出现的情景 网站采用了GB2312编码,在Web.confi

Struts2(四)Action一接收参数

一.属性接收参数并输出 导入struts2的包,导入需要的包 和struts.xml配置文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/str

Struts2中Action接收参数的方法主要有以下三种:

Struts2中Action接收参数的方法主要有以下三种: 1.使用Action的属性接收参数(最原始的方式):     a.定义:在Action类中定义属性,创建get和set方法:     b.接收:通过属性接收参数,如:userName:     c.发送:使用属性名传递参数,如:user1!add?userName=jim: 2.使用DomainModel接收参数:     a.定义:定义Model类,在Action中定义Model类的对象(不需要new),创建该对象的get和set方法

Spring MVC 之请求处理方法可接收参数(二)

请求处理方法可接收参数 今天学习了前三个方法. 1.作用域对象2.单个表单提交数据3.表单数据封装的Bean对象 首先创建一个实体对象. 1 package com.cy.springannotation.entity; 2 /** 3 * 定义一个表单实体类 4 * @author acer 5 * 6 */ 7 public class UserBean { 8 //要求属性名必须要和表单的参数名一样的! 9 private String username; 10 private Strin

Request 接收参数乱码原理解析二:浏览器端编码原理

上一篇<Request 接收参数乱码原理解析一:服务器端解码原理>,分析了服务器端解码的过程,那么浏览器是根据什么编码的呢? 1. 浏览器解码 浏览器根据服务器页面响应Header中的“Content-Type: text/html; charset=gb2312”解码.修改web.config中“responseEncoding=utf-8”,发现服务器页面响应Header变成了“Content-Type: text/html; charset=utf8”. <system.web&g

处理request接收参数的中文乱码的问题:

? POST的解决方案: * POST的参数在请求体中,直接到达后台的Servlet.数据封装到Servlet中的request中.request也有一个缓冲区.request的缓冲区也是ISO-8859-1编码. * 设置request的缓冲区的编码: * request.setCharacterEncoding("UTF-8");  --- 一定要在接收参数之前设置编码就OK. ? GET的解决方案: * 1.修改tomcat的字符集的编码.(不推荐) * 2.使用URLEncod

Struts2中Action接收参数的方法

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt112 Struts2中Action接收参数的方法主要有以下三种: 1.使用Action的属性接收参数:     a.定义:在Action类中定义属性,创建get和set方法:     b.接收:通过属性接收参数,如:userName:     c.发送:使用属性名传递参数,如:user1!add?userName=Magci: 2.使用DomainModel接收参数:   

Struts2 DomainModel、ModelDriven接收参数

一.DomainModel(域模型) 1. 应用场景:一般我们在struts2的action中接收参数通常是如下方式 package cn.orlion.user; import com.opensymphony.xwork2.ActionSupport; public class UserAction extends ActionSupport{ private String username; private String password; public String getUsernam

Struts中Action三种接收参数的方式?

前言: 前面已经有一篇随笔介绍了Struts2的大概原理.本文就Struts2中Action与jsp页面进行数据对接时介绍几种常见方法! 值栈ValueStack 3个Action Action1 package com.gdufe.action; import com.opensymphony.xwork2.ActionSupport; /* * Action接收参数之后通过set方法赋给普通变量age,name; */ public class UserAction1 extends Act