详解thinkphp的I函数源码及运转流程和用法
来源:互联网 发布:js缺省参数 编辑:程序博客网 时间:2024/06/18 11:48
上次写了U函数,今天就把I函数的源码解读和流程图记录下来,作为分享,顺便会对使用稍微做一些解释。
一 、函数使用方法:
参数1:$name
这个传递的是要过滤的变量名,里面可以包含数据来源方式method和数据类型type 格式为 method.name/type 例如 post.pram/s
method的方式非常多,具体最好参看源码,这里不具体说了。
要注意这里规定过滤数据的type后,会使用对应的强制转换,例如type为int,则用(int)方式进行转换。如果规定的type在I函数内不存在,则默认强制转换成字符串
type对应 a为数组 b为布尔 d为整形数 f为浮点数
参数2:$default
这个传递的是默认值,如果过滤后的变量不存在,则返回该默认值
参数3:$filter 默认为null
这个传递的是过滤的多个函数或者filter_id以及正则表达式
一个或多个函数:字符串格式多个函数用,隔开,还可以用数组方式,多个函数会循环进行过滤,且过滤的数据可以是多维数组,因为可以递归过滤,另外因为多个函数是循环进行过滤,所以过滤的顺序也是按照循环的顺序进行,所以要注意多个过滤函数的顺序放置。
正则表达式: /表达式/ 正则表达式的过滤方式不能进行递归,所以过滤的数据不能是数组
filter_id形式:整型的int类型或者数组类型都可以,最后用filter_var根据filter_id对应的过滤方式进行过滤,该种方式也是不进行递归的,所以过滤的数据不能是数组
参数4:$datas 默认为null
这个传递参数用来补充method中的data方式,是传递获取额外数据源的数据给过滤变量的
二、I函数运行流程图
三、I函数源码解读:
/** * 获取输入参数 支持过滤和默认值 * 使用方法: * <code> * I('id',0); 获取id参数 自动判断get或者post * I('post.name','','htmlspecialchars'); 获取$_POST['name'] * I('get.'); 获取$_GET * </code> * @param string $name 变量的名称 支持指定类型和method * 格式 get.cc/d get为method cc为变量名称 d为指定数据类型 * @param mixed $default 不存在的时候默认值 * @param mixed $filter 参数过滤方法 可以是函数名,也可以是int类型指定filter_var里的过滤id * @param mixed $datas 要获取的额外数据源 * @return mixed */function I($name,$default='',$filter=null,$datas=null) { /*建立静态变量$_PUT赋值为null*/static $_PUT=null; /*检查变量名称$name里面是否存在/*/if(strpos($name,'/')){ // 指定修饰符 /*如果存在且/不是首字符,则根据其/分割为两个单元的数组,并用list分别赋值给$name以及$type $name是变量名称,$type是变量模式,有强制转化为字符串模式s*/list($name,$type) =explode('/',$name,2); /*检测配置VAR_AUTO_STRING(强制将变量转化为字符串,如果需要变量本身,则必须加变量修饰符$)是否开启*/}elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 /*如果开启了,则将$type赋值为s,也就是字符串模式 ???*/ $type = 's'; } /*检测$name变量名中是否含有.*/ if(strpos($name,'.')) { // 指定参数来源 /*如果有且不在首字符,则根据.分割成两个单元的数组,并用list分别将其赋值给$method以及$name $method为 $name为*/ list($method,$name) = explode('.',$name,2); /*如果不存在.*/ }else{ // 默认为自动判断 /*则将param赋值给$method*/ $method = 'param'; } /*将$method转变为小写,并进行相应的判断*/ switch(strtolower($method)) { /*如果是get*/ case 'get' : /*则引用$_GET并赋值给$input*/ $input =& $_GET; break; /*如果是post*/ case 'post' : /*引用$_POST并赋值给$input*/ $input =& $_POST; break; /*如果是put*/ case 'put' : /*检查$_PUT是否为null*/ if(is_null($_PUT)){ /*如果是则获取php://input的内容并赋值给$_PUT php://input无法读取enctype=multipart/form-data的数据,会为空*/ parse_str(file_get_contents('php://input'), $_PUT); } /*将$_PUT的值赋值给$input*/ $input =$_PUT; break; /*如果是param则自动判断是哪种类型*/ case 'param' : /*检查$_SERVER的请求方式*/ switch($_SERVER['REQUEST_METHOD']) { /*如果是POST类型*/ case 'POST': $input = $_POST; break; /*如果是PUT类型*/ case 'PUT': if(is_null($_PUT)){ parse_str(file_get_contents('php://input'), $_PUT); } $input =$_PUT; break; /*不是以上两种则为GET类型*/ default: $input = $_GET; } break; /*如果是path类型*/ case 'path' : /*设定$input为空数组*/ $input = array(); /*检查$_SERVER的path_info值是否为空*/ if(!empty($_SERVER['PATH_INFO'])){ /*不为空,则将url分隔符的配置赋值给$depr*/ $depr = C('URL_PATHINFO_DEPR'); /*去除$_SERVER['PATH_INFO']两端的url分隔符$depr,然后再根据$depr分割成数组赋值给$ipnut*/ $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); } break; /*如果是request类型*/ case 'request' : /*引用$_REQUEST的值赋值给$input*/ $input =& $_REQUEST; break; /*如果是session类型*/ case 'session' : /*引用$_SESSION的值赋值给$input*/ $input =& $_SESSION; break; /*如果是cookie类型*/ case 'cookie' : /*引用$_COOKIE类型赋值给$input*/ $input =& $_COOKIE; break; /*如果是server类型*/ case 'server' : /*引用$_SERVER赋值给$input*/ $input =& $_SERVER; break; /*如果是globals类型*/ case 'globals' : /*引用$_GLOBALS赋值给$input*/ $input =& $GLOBALS; break; /*如果是data类型,则直接调用用户传入的数据源$datas*/ case 'data' : /*引用$datas赋值给$input*/ $input =& $datas; break; /*如果不属于以上任何类型*/ default: /*则返回null*/ return null; } /*检测$name是否为空,$name是要读取的变量名*/ if(''==$name) { // 获取全部变量 /*如果为空将上面的$input赋值给$data*/ $data = $input; /*检测用户是否设置$filter参数过滤方法,有则返回给$filters, 没有则将默认的过滤配置DEFAULT_FILTER的值返回给$filters*/ $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); /*检测$filters是否存在*/ if($filters) { /*如果存在,检查$filters是否为字符串格式*/ if(is_string($filters)){ /*如果是字符串,则用,分割$filters成数组重新赋值给$filters*/ $filters = explode(',',$filters); } /*循环$filters,将循环的值赋值给$filter*/ foreach($filters as $filter){ /*循环的每个$filter作为函数处理$data后返回给$data*/ $data = array_map_recursive($filter,$data); // 参数过滤 } } /*检查$input[$name]是否设置了*/ }elseif(isset($input[$name])) { // 取值操作 /*如果设置了,则将$input[$name]赋值给$data*/ $data = $input[$name]; /*检查用户是否设置$filter,设置了则赋值给$filters,否则用默认的过滤配置赋值给$fitlers*/ $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); /*检查$filters是否存在*/ if($filters) { /*检查$filters是否为字符串*/ if(is_string($filters)){ /*如果是字符串,则检查$filters首字符是否为/*/ if(0 === strpos($filters,'/')){ /*如果首字符为/则认定为过滤方法是正则匹配的方式,所以将$data强制转换成字符串, 然后将$filters作为正则匹配的表达式,用preg_match进行匹配,并检测匹配结果*/ if(1 !== preg_match($filters,(string)$data)){ // 支持正则验证 /*如果不匹配,则返回用户提交的$default值,如果用户没有设定$default,则返回null*/ return isset($default) ? $default : null; } /*如果$filters首字符不是/*/ }else{ /*则根据,分割$filters并重新赋值给自身*/ $filters = explode(',',$filters); } /*如果$filters不为字符串,则检测是否为int类型*/ }elseif(is_int($filters)){ /*如果是int类型,则将$filters强制转变为数组并赋值给$filters*/ $filters = array($filters); } /*检查$filters是否为数组*/ if(is_array($filters)){ /*将$filters循环,每次循环的值赋值给$filter*/ foreach($filters as $filter){ /*检查循环出来的$filter函数是否存在*/ if(function_exists($filter)) { /*如果存在,则检测$data是否是数组,如果是则用array_map_recursivve递归执行$filter函数处理$data 如果不是数组,则直接用$filter作为函数处理$data,最后将执行结果赋值给$data*/ $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 /*如果$filter函数不存在*/ }else{ /*检查$filter是否是int类型,如果是,则返回$filter,如果不是,则用filter_id获取其对应的id返回 将返回值,作为filter_var的第二次参数过滤选型对$data进行过滤,处理完后返回赋值给$data*/ $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); /*检查$data是否为false*/ if(false === $data) { /*检查用户提交的$default是否设置,如果设置则返回$default,如果没有设置则返回null*/ return isset($default) ? $default : null; } } } } } /*如果$type不为空*/ if(!empty($type)){ /*根据转为小写后的$type类型来强制转换$data的类型*/ 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强制转换成字符串类型*/ $data = (string)$data; } } /*如果$name不为空值,同时不存在$input[$name]*/ }else{ // 变量默认值 /*则检查用户提交的$default默认值是否设置,如果设置了返回其作为$data,如果没有设置,则返回null作为$data*/ $data = isset($default)?$default:null; } /*检查$data为数组的话,则使用array_walk_recursive处理$data递归使用执行think_filter函数, think_filter猜测是对数据查询进行特别过滤,匹配查询语句的都在后方添加了一个空格,这里我自己 也没太懂*/ is_array($data) && array_walk_recursive($data,'think_filter'); /*返回$data*/ return $data;}
- 详解thinkphp的I函数源码及运转流程和用法
- 详解thinkphp的C函数源码以及运行流程和使用注意
- SpringMVC的运转流程及代码解析
- ThinkPHP I()函数详解
- ThinkPHP函数详解:I方法
- ThinkPHP函数详解:I方法
- 利用xdebug和netbeans调试thinkphp源码及流程分析
- Struts的工作流程和配置文件的运转
- 详解thinkphp的U函数及其源码分析
- 【ThinkPHP】U()函数和I()函数
- ThreadPoolExecutor运转机制及BlockingQueue详解
- ThreadPoolExecutor运转机制及BlockingQueue详解
- thinkPhp set_error_handler()函数的用法
- ThinkPHP的I方法使用详解
- LruCache的用法和源码的详解
- ThinkPHP函数 I方法
- 【matlab】函数meshgrid的用法详解(生成网格矩阵)和ndgrid的区别及用法
- ThinkPHP中,display和assign用法详解
- MongoDB -- CentOS7搭建单点服务步骤
- Android Studio 开发Android依赖方式整理
- python刷题笔记3--Palindrome Number
- RecyclerView分组之BaseRecyclerViewAdapterHelper(实现分组功能)
- java基础-IO流1
- 详解thinkphp的I函数源码及运转流程和用法
- 视频比特率与分辨率
- Android 源码中的设计模式
- C语言单链表实现19个功能完全详解
- pycharm连接mysql数据库
- nginx三 之动静分离
- VC1
- PHP学习笔记10(日期时间函数)
- IT人必须掌握的面试技巧