Thinkphp框架感悟(二)

        这次主要分析一下I方法

/**
 * 获取输入参数 支持过滤和默认值
 * 使用方法:
 * <code>
 * I('id',0); 获取id参数 自动判断get或者post
 * I('post.name','','htmlspecialchars'); 获取$_POST['name']
 * I('get.'); 获取$_GET
 * </code>
 * @param string $name 变量的名称 支持指定类型
 * @param mixed $default 不存在的时候默认值
 * @param mixed $filter 参数过滤方法
 * @param mixed $datas 要获取的额外数据源
 * @return mixed
 *
 */
function I($name,$default='',$filter=null,$datas=null) {
   static $_PUT   =  null;

    /**
     * 这个if存在的意义是:I方法有一种写法为I('变量类型.变量名/修饰符');,这种写法可以通过修饰符的不同,将得到的变量强制转换为各个不同的类型
     * 于是就需要一个if来判断是否为带“/”的写法。
     * strpos()可以查出参数里第一个/的位置,
     *
     * 如果查到了“/”,则用explode$name字符串拆成两个字符串.
     * explode()的作用是将$name转换为一维数组,以"/"为标记拆分,
     * 如:$demo = "abcd/12345"; var_dump(explode('/',$demo,2));
     * 得到的结果为   array (size=2)
     *                0 => string 'abcd' (length=4)
     *                1 => string '12345' (length=5)
     *
     * 再通过list函数,将“/”前的字符串赋值给$name,"/"后面的字符串赋值给$type
     *
     * 结果:$name变量类型.变量名     *      $type修饰符     *
     * 如果参数传入时的格式不是I('变量类型.变量名/修饰符')这种,
     * 则查看是否设置配置参数'VAR_AUTO_STRING'”,该参数的作用是默认强制转换为字符串 $type = 's';
     */
   if(strpos($name,'/')){
      list($name,$type)  =  explode('/',$name,2);
   }elseif(C('VAR_AUTO_STRING')){
        $type   =   's';
    }

    /**
     *这个if的运行过程与上一个if一样,判断传入的参数$name(也可以是经过上面步骤处理过的$name)     * 最后变量类型(paramgetpost等)被赋值给了$method。变量名被赋值给了$name
     *
     * 如果写的格式为I('变量名'),即没写“.”和变量类型,
     * 则默认变量类型为param
     */
    if(strpos($name,'.')) {
        list($method,$name) =   explode('.',$name,2);
    }else{
        $method =   'param';
    }

    /**
     * strtolower()函数的作用是将字符全部转化为小写
     * 通过$method1的不同,对$input赋不同的传输类型(注:此处的&不是很明白, &的用法是让两个变量指向同一个内容,不知去掉&会怎么样)
     */
    switch(strtolower($method)) {
        case 'get'     :   
           $input =& $_GET;
           break;
        case 'post'    :   
           $input =& $_POST;
           break;
        case 'put'     :   
           if(is_null($_PUT)){
               parse_str(file_get_contents('php://input'), $_PUT);
           }
           $input     =  $_PUT;        
           break;

        /**
         * 此处的$_SERVER是获取系统变量的方法,
         * $_SERVER['REQUEST_METHOD'] 是查看访问页面时的请求方法。例如:“GET”“HEAD”“POST”“PUT”         * 从而达到自动判断请求类型的目的
         * (所以,无论html页面传过来数据用的传输方法是get还是post,都能用param来接收)
         */
        case 'param'   :
            switch($_SERVER['REQUEST_METHOD']) {
                case 'POST':
                    $input  =  $_POST;
                    break;
                case 'PUT':
                   if(is_null($_PUT)){
                       parse_str(file_get_contents('php://input'), $_PUT);
                   }
                   $input     =  $_PUT;
                    break;
                default:
                    $input  =  $_GET;
            }
            break;

        /**
         * 下面依旧是通过$method1的不同,对$input赋不同的关键变量名,用以获取各种系统变量。
         */
        case 'path'    :   
            $input  =   array();
            if(!empty($_SERVER['PATH_INFO'])){
                $depr   =   C('URL_PATHINFO_DEPR');
                $input  =   explode($depr,trim($_SERVER['PATH_INFO'],$depr));            
            }
            break;
        case 'request' :   
           $input =& $_REQUEST;   
           break;
        case 'session' :   
           $input =& $_SESSION;   
           break;
        case 'cookie'  :   
           $input =& $_COOKIE;    
           break;
        case 'server'  :   
           $input =& $_SERVER;    
           break;
        case 'globals' :   
           $input =& $GLOBALS;    
           break;
        case 'data'    :   
           $input =& $datas;      
           break;
        default:
            return null;
    }

    /**
     * 此时$name的内容为变量名,而$input$_post之类的接收类型变量
     *
     * 如果变量名$name为空,则意味着无变量名传入,传入的只是一个接收类型变量
     * 那么这个接收类型变量里其实是所有的用该类型传输过来的内容(如只有$_POST则是一个数组,里面是各种来自method="post" 的表单中的值)
     * 所以不写变量名代表不是接收特定的键值名传过来的内容,而是接收所有通过该方法传过来的内容,并存进传输类型变量这个数组里
     * 所以,如果变量名$name为空,我们将整个接收到的数组赋值给$data     * 其中isset函数的作用是检测变量是否存在:若变量不存在返回false,若其存在但值为null也返回false,只有存在且值不为null时才返回true
     * 这个$filterI方法的第二个传入参数,为参数过滤方法(一般我都没传过这个参数),所以当我们传入参数过滤方法时,会按我们传入的方法过滤
     *
     * 如果传入的$name不为空
     * 则通过isset函数判断传过来的所有数据(是个二维数组,存放在$input$_POST之类)里面)里是否有键值名为$name的键值对
     * 如果有,则将数据复制给$data,之后依然判断下是否传入了参数过滤方法,如果传入则过滤。
     */
    if(''==$name) { // 获取全部变量
        $data       =   $input;
        $filters    =   isset($filter)?$filter:C('DEFAULT_FILTER');
        if($filters) {
            if(is_string($filters)){
                $filters    =   explode(',',$filters);
            }
            foreach($filters as $filter){
                $data   =   array_map_recursive($filter,$data); // 参数过滤
            }
        }
    }elseif(isset($input[$name])) { // 取值操作
        $data       =   $input[$name];
        $filters    =   isset($filter)?$filter:C('DEFAULT_FILTER');
        if($filters) {
            if(is_string($filters)){
                if(0 === strpos($filters,'/')){
                    if(1 !== preg_match($filters,(string)$data)){
                        // 支持正则验证
                        return   isset($default) ? $default : null;
                    }
                }else{
                    $filters    =   explode(',',$filters);                    
                }
            }elseif(is_int($filters)){
                $filters    =   array($filters);
            }
            
            if(is_array($filters)){
                foreach($filters as $filter){
                    if(function_exists($filter)) {
                        $data   =   is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤
                    }else{
                        $data   =   filter_var($data,is_int($filter) ? $filter : filter_id($filter));
                        if(false === $data) {
                            return   isset($default) ? $default : null;
                        }
                    }
                }
            }
        }
        /**
         * 所以现在$data里面其实装的是传输过来的具体内容。
         * 之后再判断下是否有$type(修饰符,在前面有过详解),如果$type不为空,则依据$type,将$data转化成不同的类型
         * 如果$type为空,则判定是否传入参数$default(当传输内容不存在时的默认值),如果有$default,则将其赋值给$data
         */
        if(!empty($type)){
           switch(strtolower($type)){
              case 'a':  // 数组
                 $data  =  (array)$data;
                 break;
              case 'd':  // 数字
                 $data  =  (int)$data;
                 break;
              case 'f':  // 浮点
                 $data  =  (float)$data;
                 break;
              case 'b':  // 布尔
                 $data  =  (boolean)$data;
                 break;
                case 's':   // 字符串
                default:
                    $data   =   (string)$data;
           }
        }
    }else{ // 变量默认值
        $data       =    isset($default)?$default:null;
    }

    /**
     * &&这个运算符的意思是:如果前面为假,那么后面的语句就不执行了。
     * array_walk_recursive()函数的意思是:对数组中的每个元素应用用户自定义的函数(即:将数组$data放入函数think_filter中运算)(关于这个函数目前的用法我还不是很明确)。
     * 最后先判断$data是否为数组,
     * 如果是数组,则运行array_walk_recursive函数(因为array_walk_recursive函数的第一个参数必须得是数组)
     */
    is_array($data) && array_walk_recursive($data,'think_filter');

    /**
     * 最后将$data输出
     */
    return $data;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值