这次主要分析一下I方法

  1. /**
  2. * 获取输入参数 支持过滤和默认值
  3. * 使用方法:
  4. * <code>
  5. * I('id',0); 获取id参数 自动判断get或者post
  6. * I('post.name','','htmlspecialchars'); 获取$_POST['name']
  7. * I('get.'); 获取$_GET
  8. * </code>
  9. * @param string $name 变量的名称 支持指定类型
  10. * @param mixed $default 不存在的时候默认值
  11. * @param mixed $filter 参数过滤方法
  12. * @param mixed $datas 要获取的额外数据源
  13. * @return mixed
  14. *
  15. */
  16. function I($name,$default='',$filter=null,$datas=null) {
  17. static $_PUT = null;
  18. /**
  19. * 这个if存在的意义是:I方法有一种写法为I('变量类型.变量名/修饰符');,这种写法可以通过修饰符的不同,将得到的变量强制转换为各个不同的类型
  20. * 于是就需要一个if来判断是否为带“/”的写法。
  21. * strpos()可以查出参数里第一个/的位置,
  22. *
  23. * 如果查到了“/”,则用explode将$name字符串拆成两个字符串.
  24. * explode()的作用是将$name转换为一维数组,以"/"为标记拆分,
  25. * 如:$demo = "abcd/12345"; var_dump(explode('/',$demo,2));
  26. * 得到的结果为 array (size=2)
  27. * 0 => string 'abcd' (length=4)
  28. * 1 => string '12345' (length=5)
  29. *
  30. * 再通过list函数,将“/”前的字符串赋值给$name,将"/"后面的字符串赋值给$type
  31. *
  32. * 结果:$name为“变量类型.变量名”
  33. * $type为“修饰符”
  34. *
  35. * 如果参数传入时的格式不是I('变量类型.变量名/修饰符')这种,
  36. * 则查看是否设置“配置参数'VAR_AUTO_STRING'”,该参数的作用是默认强制转换为字符串 $type = 's';
  37. */
  38. if(strpos($name,'/')){
  39. list($name,$type) = explode('/',$name,2);
  40. }elseif(C('VAR_AUTO_STRING')){
  41. $type = 's';
  42. }
  43. /**
  44. *这个if的运行过程与上一个if一样,判断传入的参数$name(也可以是经过上面步骤处理过的$name)。
  45. * 最后变量类型(param、get、post等)被赋值给了$method。变量名被赋值给了$name
  46. *
  47. * 如果写的格式为I('变量名'),即没写“.”和变量类型,
  48. * 则默认变量类型为param
  49. */
  50. if(strpos($name,'.')) {
  51. list($method,$name) = explode('.',$name,2);
  52. }else{
  53. $method = 'param';
  54. }
  55. /**
  56. * strtolower()函数的作用是将字符全部转化为小写
  57. * 通过$method1的不同,对$input赋不同的传输类型(注:此处的&不是很明白, &的用法是让两个变量指向同一个内容,不知去掉&会怎么样)
  58. */
  59. switch(strtolower($method)) {
  60. case 'get' :
  61. $input =& $_GET;
  62. break;
  63. case 'post' :
  64. $input =& $_POST;
  65. break;
  66. case 'put' :
  67. if(is_null($_PUT)){
  68. parse_str(file_get_contents('php://input'), $_PUT);
  69. }
  70. $input = $_PUT;
  71. break;
  72. /**
  73. * 此处的$_SERVER是获取系统变量的方法,
  74. * $_SERVER['REQUEST_METHOD'] 是查看访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。
  75. * 从而达到“自动判断请求类型”的目的
  76. * (所以,无论html页面传过来数据用的传输方法是get还是post,都能用param来接收)
  77. */
  78. case 'param' :
  79. switch($_SERVER['REQUEST_METHOD']) {
  80. case 'POST':
  81. $input = $_POST;
  82. break;
  83. case 'PUT':
  84. if(is_null($_PUT)){
  85. parse_str(file_get_contents('php://input'), $_PUT);
  86. }
  87. $input = $_PUT;
  88. break;
  89. default:
  90. $input = $_GET;
  91. }
  92. break;
  93. /**
  94. * 下面依旧是通过$method1的不同,对$input赋不同的“关键变量名”,用以获取各种系统变量。
  95. */
  96. case 'path' :
  97. $input = array();
  98. if(!empty($_SERVER['PATH_INFO'])){
  99. $depr = C('URL_PATHINFO_DEPR');
  100. $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr));
  101. }
  102. break;
  103. case 'request' :
  104. $input =& $_REQUEST;
  105. break;
  106. case 'session' :
  107. $input =& $_SESSION;
  108. break;
  109. case 'cookie' :
  110. $input =& $_COOKIE;
  111. break;
  112. case 'server' :
  113. $input =& $_SERVER;
  114. break;
  115. case 'globals' :
  116. $input =& $GLOBALS;
  117. break;
  118. case 'data' :
  119. $input =& $datas;
  120. break;
  121. default:
  122. return null;
  123. }
  124. /**
  125. * 此时$name的内容为变量名,而$input为$_post之类的接收类型变量
  126. *
  127. * 如果变量名$name为空,则意味着无变量名传入,传入的只是一个接收类型变量
  128. * 那么这个接收类型变量里其实是所有的用该类型传输过来的内容(如只有$_POST则是一个数组,里面是各种来自method="post" 的表单中的值)
  129. * 所以不写变量名代表不是接收特定的键值名传过来的内容,而是接收所有通过“该方法”传过来的内容,并存进“传输类型变量”这个数组里
  130. * 所以,如果变量名$name为空,我们将整个接收到的数组赋值给$data,
  131. * 其中isset函数的作用是检测变量是否存在:若变量不存在返回false,若其存在但值为null也返回false,只有存在且值不为null时才返回true
  132. * 这个$filter是I方法的第二个传入参数,为“参数过滤方法”(一般我都没传过这个参数),所以当我们传入“参数过滤方法”时,会按我们传入的方法过滤
  133. *
  134. * 如果传入的$name不为空
  135. * 则通过isset函数判断传过来的所有数据(是个二维数组,存放在$input($_POST之类)里面)里是否有键值名为$name的键值对
  136. * 如果有,则将数据复制给$data,之后依然判断下是否传入了“参数过滤方法”,如果传入则过滤。
  137. */
  138. if(''==$name) { // 获取全部变量
  139. $data = $input;
  140. $filters = isset($filter)?$filter:C('DEFAULT_FILTER');
  141. if($filters) {
  142. if(is_string($filters)){
  143. $filters = explode(',',$filters);
  144. }
  145. foreach($filters as $filter){
  146. $data = array_map_recursive($filter,$data); // 参数过滤
  147. }
  148. }
  149. }elseif(isset($input[$name])) { // 取值操作
  150. $data = $input[$name];
  151. $filters = isset($filter)?$filter:C('DEFAULT_FILTER');
  152. if($filters) {
  153. if(is_string($filters)){
  154. if(0 === strpos($filters,'/')){
  155. if(1 !== preg_match($filters,(string)$data)){
  156. // 支持正则验证
  157. return isset($default) ? $default : null;
  158. }
  159. }else{
  160. $filters = explode(',',$filters);
  161. }
  162. }elseif(is_int($filters)){
  163. $filters = array($filters);
  164. }
  165. if(is_array($filters)){
  166. foreach($filters as $filter){
  167. if(function_exists($filter)) {
  168. $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤
  169. }else{
  170. $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter));
  171. if(false === $data) {
  172. return isset($default) ? $default : null;
  173. }
  174. }
  175. }
  176. }
  177. }
  178. /**
  179. * 所以现在$data里面其实装的是传输过来的具体内容。
  180. * 之后再判断下是否有$type(修饰符,在前面有过详解),如果$type不为空,则依据$type,将$data转化成不同的类型
  181. * 如果$type为空,则判定是否传入参数$default(当传输内容不存在时的默认值),如果有$default,则将其赋值给$data
  182. */
  183. if(!empty($type)){
  184. switch(strtolower($type)){
  185. case 'a': // 数组
  186. $data = (array)$data;
  187. break;
  188. case 'd': // 数字
  189. $data = (int)$data;
  190. break;
  191. case 'f': // 浮点
  192. $data = (float)$data;
  193. break;
  194. case 'b': // 布尔
  195. $data = (boolean)$data;
  196. break;
  197. case 's': // 字符串
  198. default:
  199. $data = (string)$data;
  200. }
  201. }
  202. }else{ // 变量默认值
  203. $data = isset($default)?$default:null;
  204. }
  205. /**
  206. * &&这个运算符的意思是:如果前面为假,那么后面的语句就不执行了。
  207. * array_walk_recursive()函数的意思是:对数组中的每个元素应用用户自定义的函数(即:将数组$data放入函数think_filter中运算)(关于这个函数目前的用法我还不是很明确)。
  208. * 最后先判断$data是否为数组,
  209. * 如果是数组,则运行array_walk_recursive函数(因为array_walk_recursive函数的第一个参数必须得是数组)
  210. */
  211. is_array($data) && array_walk_recursive($data,'think_filter');
  212. /**
  213. * 最后将$data输出
  214. */
  215. return $data;
  216. }

Thinkphp框架感悟(二)的更多相关文章

  1. Thinkphp框架感悟(一)

    一.assign() /** * 分析: * 此处是Controller类里面的assign方法,我们一般写的控制器所调用的assign方法就是调的这个. * 而这个方法就干了三件事:1.获取传过来的 ...

  2. 制作类似ThinkPHP框架中的PATHINFO模式功能(二)

    距离上一次发布的<制作类似ThinkPHP框架中的PATHINFO模式功能>(文章地址:http://www.cnblogs.com/phpstudy2015-6/p/6242700.ht ...

  3. ThinkPHP框架整合phpqrcode生成二维码DEMO

    ThinkPHP框架发展到今天功能已经变得是非常强大了,但是ThinkPHP框架中没有二维码相关的库,因此我们可以通过整合phpqrcode来完成生成二维码的功能.想使用phpqrcode首先就要把p ...

  4. ThinkPHP框架学习(二)

    在上一节中,我主要讲到了如何获取ThinkPHP框架,以及虚拟目录和虚拟主机的配置.准备工作完成之后,就可以利用ThinkPHP去部署项目了. 先在工作目录(D:/zend/workspace)下新建 ...

  5. 攻城记:Thinkphp框架的项目规划总结和踩坑经验

    一.项目模块规划 1.项目分为PC端.移动端.和PC管理端,分为对应目录为 /Application/Home,/Application/Mobile,/Application/Admin: 对应入口 ...

  6. 关于在BAE上部署ThinkPHP框架的问题

    现在有点小兴奋,因为在在BAE上部署ThinkPHP框架的问题快折腾一天了,午觉都没睡,不过没白整总算有点结果.不扯淡了,直入正题吧. 之前熟悉ThinkPHP框架,想在BAE上用ThinkPHP做点 ...

  7. 使用Thinkphp框架开发移动端接口

     本文给大家分享的是使用thinkphp框架开发移动端接口的2种方法,一种是开发API,另外一种是实现移动端访问自动切换移动主题模板,从而实现伪app访问,下面我们就来详细看下如何实现吧. 方案一:给 ...

  8. 浅析Thinkphp框架中运用phprpc扩展模式

    浅析Thinkphp框架中应用phprpc扩展模式 这次的项目舍弃了原来使用Axis2做web服务端的 方案,改用phprpc实现,其一是服务端的thinkphp已集成有该模式接口,其二是phprpc ...

  9. ThinkPHP框架视图详细介绍 View 视图--模板(九)

    原文:ThinkPHP框架视图详细介绍 View 视图--模板(九) 视图也是ThinkPHP使用的核心部分: 一.模板的使用 a.规则 模板文件夹下[TPL]/[分组文件夹/][模板主题文件夹/]和 ...

随机推荐

  1. hdu 4281(MTSP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4281 题意:给出N个点,第一个点是裁判,其他N-1个点需要裁判过去回答问题,每个点需要的时间不一样,而 ...

  2. scrollTo , scrollBy区别

    View视图中scrollTo 与scrollBy这两个函数的区别 . 首先 ,我们必须明白在Android View视图是没有边界的,Canvas是没有边界的,只不过我们通过绘制特定的View时对 ...

  3. POJ 2750 Potted Flower (线段树区间合并)

    开始懵逼找不到解法,看了网上大牛们的题解才发现是区间合并...  给你n个数形成一个数列环,然后每次进行一个点的修改,并输出这个数列的最大区间和(注意是环,并且区间最大只有n-1个数) 其实只需要维护 ...

  4. x264源代码 概述 框架分析 架构分析

    函数背景色 函数在图中以方框的形式表现出来.不同的背景色标志了该函数不同的作用: 白色背景的函数:不加区分的普通内部函数. 浅红背景的函数:libx264类库的接口函数(API). 粉红色背景函数:滤 ...

  5. 从客户端(CourseIssueContent="<P>财务审计师岗位认证招生简章<BR>...")中检测到有潜在危险的 Request.Form 值。

    说明: 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止.该值可能指示危及应用程序安全的尝试,如跨站点的脚本攻击.通过在 Page 指令或 配置节中设置 validateRequest ...

  6. JavaScript设计模式——单体模式

    一:单体模式简介: 是什么:将代码组织为一个逻辑单元,这个单元中的代码通过单一的变量进行访问.只要单体对象存在一份实例,就可以确信自己的所有代码使用的是同样的全局资源. 用途:1.用来划分命名空间,减 ...

  7. 工具:使用jekyll生成静态网站

    在使用前端框架构建网页而不使用后端平台与数据库,即没有服务器的条件下读取文件夹其他文件,浏览器可能会阻止访问.对于这种静态构建可以使用简单的生成工具jekyll.它主要适用于将静态文件生成静态网站,在 ...

  8. linux(centos6)搭建ftp服务器

    前提 ssh服务已经开启,关闭防火墙,主机和虚拟机能ping通 查看ssh和防火墙的状态 service sshd status service iptables status 开启ssh服务 ser ...

  9. iOS Debug日志 viewhierarchy调试笔记

    Debut - View Debugging - Capture View Hierarchy 当视图没有正常显示时,用view hierarchy进行调试,查看左边的分支里有没有加载对应的视图. 如 ...

  10. C#Excel的导入与导出

    1.整个Excel表格叫做工作表:WorkBook(工作薄),包含的叫页(工作表):Sheet:行:Row:单元格Cell. 2.NPOI是POI的C#版本,NPOI的行和列的index都是从0开始 ...