ThinkPHP源码学习之I方法
2015-09-05 09:53
543 查看
PHP新人一个,最近在做一个项目,用的是ThinkPHP,想往深处学习,特意学习ThinkPHP的源码并作笔记,以记录这些容易忘记的东西,废话不多说,开始。
官网说明:
I方法是ThinkPHP众多单字母函数中的新成员,其命名来自于英文Input(输入),主要用于更加方便和安全的获取系统输入变量,可以用于任何地方,用法格式如下:
I('变量类型.变量名',['默认值'],['过滤方法'])
变量类型是指请求方式或者输入类型,包括:
注意:变量类型不区分大小写。
变量名则严格区分大小写。
默认值和过滤方法均属于可选参数。
官方的代码如下:
function I($name,$default='',$filter=null,$datas=null) {
static $_PUT
= null;//使用static定义了一个静态,声明类成员或方法为static,就可以不实例化类而直接访问。不能通过一个对象来访问其中的静态成员(静态方法除外)
if(strpos($name,'/')){ //
指定修饰符 strpos()函数为查找字符串在另一个字符串中第一次出现的位置,查找‘/'在参数nam中第一次出现的位置
list($name,$type)
= explode('/',$name,2);//explode(separator,string,limit)函数意义为根据特定字符将字符串打撒为数组,limit为返回的数组的个数
}elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 //调用了ThinkPHP的C方法
$type = 's';
}
//小结 此if含义为判断参数是否带有/
if(strpos($name,'.')) { // 指定参数来源 //查看是否带.!
list($method,$name) = explode('.',$name,2);
}else{ // 默认为自动判断
$method = 'param';
}
switch(strtolower($method)) { //strtolower()把所有字符转换为小写 利用switch来定位方法的类型
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;
case 'param' :
switch($_SERVER['REQUEST_METHOD']) { //$_SERVER['REQUEST_METHOD' 获取请求的方法 利用获取到的方法名,使用swith()来定位方法的类型,此处思想为递归
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;
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;
}
if(''==$name) { // 获取全部变量
$data = $input;
$filters = isset($filter)?$filter:C('DEFAULT_FILTER');//使用了三目运算符 isset()函数 一般用来检测变量是否设置,empty()用来判断是否为空
if($filters) {
if(is_string($filters)){
$filters = explode(',',$filters);
}
foreach($filters as $filter){
$data = array_map_recursive($filter,$data); // ThinkPHP的参数过滤方法array_map_recursive foreach()为循环函数
}
}
}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)){ //preg_match()用来匹配正则表达式
// 支持正则验证
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;
}
}
}
}
}
if(!empty($type)){//使用switch判断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;
}
is_array($data) && array_walk_recursive($data,'think_filter');
return $data;
}
I方法主要是用来获取前台传给后台的值,方法定义了四个参数,只有一个是必须的,此参数为所要获取的名称,其他都是可以变的。
以上标红的便是自己看代码过程中的记得一些知识点。
功能:安全的获取input传过来的参数
实现思路:
如果提交的时候跟上了类型,则按指定的类型处理,如果没有跟上指定类型,则根据服务器变量来确定类型。
通过过滤来确保提交的数据的安全性。
官网说明:
I方法是ThinkPHP众多单字母函数中的新成员,其命名来自于英文Input(输入),主要用于更加方便和安全的获取系统输入变量,可以用于任何地方,用法格式如下:
I('变量类型.变量名',['默认值'],['过滤方法'])
变量类型是指请求方式或者输入类型,包括:
变量类型 | 含义 |
---|---|
get | 获取GET参数 |
post | 获取POST参数 |
param | 自动判断请求类型获取GET、POST或者PUT参数 |
request | 获取REQUEST 参数 |
put | 获取PUT 参数 |
session | 获取 $_SESSION 参数 |
cookie | 获取 $_COOKIE 参数 |
server | 获取 $_SERVER 参数 |
globals | 获取 $GLOBALS参数 |
变量名则严格区分大小写。
默认值和过滤方法均属于可选参数。
官方的代码如下:
function I($name,$default='',$filter=null,$datas=null) {
static $_PUT
= null;//使用static定义了一个静态,声明类成员或方法为static,就可以不实例化类而直接访问。不能通过一个对象来访问其中的静态成员(静态方法除外)
if(strpos($name,'/')){ //
指定修饰符 strpos()函数为查找字符串在另一个字符串中第一次出现的位置,查找‘/'在参数nam中第一次出现的位置
list($name,$type)
= explode('/',$name,2);//explode(separator,string,limit)函数意义为根据特定字符将字符串打撒为数组,limit为返回的数组的个数
}elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 //调用了ThinkPHP的C方法
$type = 's';
}
//小结 此if含义为判断参数是否带有/
if(strpos($name,'.')) { // 指定参数来源 //查看是否带.!
list($method,$name) = explode('.',$name,2);
}else{ // 默认为自动判断
$method = 'param';
}
switch(strtolower($method)) { //strtolower()把所有字符转换为小写 利用switch来定位方法的类型
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;
case 'param' :
switch($_SERVER['REQUEST_METHOD']) { //$_SERVER['REQUEST_METHOD' 获取请求的方法 利用获取到的方法名,使用swith()来定位方法的类型,此处思想为递归
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;
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;
}
if(''==$name) { // 获取全部变量
$data = $input;
$filters = isset($filter)?$filter:C('DEFAULT_FILTER');//使用了三目运算符 isset()函数 一般用来检测变量是否设置,empty()用来判断是否为空
if($filters) {
if(is_string($filters)){
$filters = explode(',',$filters);
}
foreach($filters as $filter){
$data = array_map_recursive($filter,$data); // ThinkPHP的参数过滤方法array_map_recursive foreach()为循环函数
}
}
}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)){ //preg_match()用来匹配正则表达式
// 支持正则验证
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;
}
}
}
}
}
if(!empty($type)){//使用switch判断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;
}
is_array($data) && array_walk_recursive($data,'think_filter');
return $data;
}
I方法主要是用来获取前台传给后台的值,方法定义了四个参数,只有一个是必须的,此参数为所要获取的名称,其他都是可以变的。
以上标红的便是自己看代码过程中的记得一些知识点。
功能:安全的获取input传过来的参数
实现思路:
如果提交的时候跟上了类型,则按指定的类型处理,如果没有跟上指定类型,则根据服务器变量来确定类型。
通过过滤来确保提交的数据的安全性。
相关文章推荐
- 一个关于if else容易迷惑的问题
- 从源码安装Mysql/Percona 5.5
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- JSP/PHP基于Ajax的分页功能实现
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- kindeditor 批量上传 上传失败 thinkphp swfupload session
- Php Installing An Expansion
- PHP+Apache在Windows 9x下的安装和配置
- IIS 6 的 PHP 最佳配置方法
- 安装Apache和PHP的一些补充
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- 浅析Ruby的源代码布局及其编程风格
- PHP 5.3.0 安装分析心得
- apache 环境下 php 的配置注意事项
- ASP.NET、ASP、PHP、JSP之间有什么区别?