织梦中预定义的超全局数组处理

当我们写好表单后,提交到对应php文件进行处理,在处理前首先要接收数据,然后对数据处理,以申请友情链接为例子。 友情链接申请界面如下图所示: 当我们提交flink.php后,正常情况是flink.php会用超全局数组$_POST来接收数据,但是打开flink.php文件,我们
  当我们写好表单后,提交到对应php文件进行处理,在处理前首先要接收数据,然后对数据处理,以申请友情链接为例子。

  友情链接申请界面如下图所示:
织梦友情链接
  当我们提交flink.php后,正常情况是flink.php会用超全局数组$_POST来接收数据,但是打开flink.php文件,我们完全找不到$_POST,难道织梦不用$_POST,织梦也是用php开发的,所以,收集数据必定会用到$_POST,但是如果你仔细分析织梦源码的话,你会发现每个对表单提交过来的数据进行处理的文件,都找不到$_POST或$_GET等超全局数据。

  以前刚学习php时,看织梦系统源码,非常费事,就拿这样刚开始时让我纠结了好久,等看多了织梦系统源码,才知道,原来织梦把这些超全局变数组,都做了处理,这样以后我们无需每次处理表单,都要多写$_POST或$_GET等多余的代码了。

  我们看一下织梦里面的这个flink.php文件,找到下面几行:

    $msg = htmlspecialchars($msg);
    $email = htmlspecialchars($email);
    $webname = htmlspecialchars($webname);
    $url = htmlspecialchars($url);
    $logo = htmlspecialchars($logo);
    $typeid = intval($typeid);

  织梦直接用类似$msg来收集表单来的数据,正常应当是$msg = $_POST['msg'],现在变成了$msg = $msg(htmlspecialchars()这个函数的功能是把一些预定义的字符转换为 HTML 实体,这与超全局变量没有关系),是不省了不少事,也许大家会问,也省不了多少,这只是一个文件,而织梦时面的处理表单的文件,不止数十个,加起来就量就非常大了,这样不仅可以减少代码,而且,还省不少事。

  这个功能是如何实现的?织梦是在入口文件common.inc.php里面定义的,找到这个文件,代码如下:

    foreach(Array('_GET','_POST','_COOKIE') as $_request)
    {
        foreach($$_request as $_k => $_v)
        {
            if($_k == 'nvarname') ${$_k} = $_v;
            else ${$_k} = _RunMagicQuotes($_v);
        }
    }

  首先遍历声明的数组Array('_GET','_POST','_COOKIE'),再通过第二次循环遍历,就可以实现了上面的提到简略形式,其中$$_request正是类似的$_GET,$POST,$_COOKIE。$$_request是可变变量,在下面的教程里讲到。在这二又重循环中用到了一个函数_RunMagicQuotes(),还有一个函数CheckRequest()。

  不仅这个超全局变量了这种简略思想,在上传文件收集上传信息的$FILES也用了这种思想,作为一个技术员,可以好好研究一下织梦一些设计思想,一定会对我们大有用处。


扩展学习:

  要看明白织梦对预定义的超全局数组(预定义的超全局数组也叫预定义的超全局变量)是如何处理优化的,首先得明白这些超全局数组$_GET、$_POST、$_REQUEST、$GLOBAL、$COOKIE、$SESSION等是什么意思,它们是如何运作的?只有把这些基本的概念弄明白了,才能对织梦里面的超全局数组的应用有更好的把握。

  要知道预定义全局数组首先要知道什么是变量、什么是局部变量、什么是全局变量。

变量常识:

  当我们声明了一个变量,php就会给变量分配一个空间,这个空间包括变量名、变量的地址和存储变量值空间,例如,声明变量$age=10,在栈内存中示意图如下所示。

  当我们连续声明二个同样的变量即$a=5;$a=7;最后$a的值是7,前面的变量会被后面的变量覆盖掉。

  当我们使用地址引用即在变量前面加上&符号后,例如$a=5;$b=&$a;这时的变量$b里面的存储的是变量a的地址,如果改变$a的值那么,$b的值同样也改变,因为,$b指向$a,如下图所示。


  此时,如果unset($a)销毁变量$a,是不是变量$b也跟着销毁呢?不是的,变量$b仍然存在,且值不变。

  如果$a=5;$b=&$a;$c=10;$b=&$c,若现在我们把$c赋值为20即$c=20,请问echo $b的结果是多少?打印结果是20,也就是说$b现在的已经“抛弃”$a,转向指向$c了,$b具有“喜新厌旧”的特性。

  我们定义的变量都是由超全局变量$GLOBAL来管理的。

可变变量:

  什么是可变变量?看下面的例子:

  <?php

$a="good";
 
$$a="ok";

echo $good;
?>

  打印结果是:ok,在这里$$a就是$good,本来good是$a的值结果经过二个$$符号,把原来是作为值的good变成了另一个变量,这就是可变变量。还可以把$$a再加上一个$符号变成$$$a现在的$$$a与$ok等价,原来是值的ok现在也变成了变

量。可变变量在php程序开发中也是经常用到的,在织梦里面的入口文件common.inc.php里面下面代码里面,

foreach(Array('_GET','_POST','_COOKIE') as $_request)
    {
        foreach($$_request as $_k => $_v)
        {
            if($_k == 'nvarname') ${$_k} = $_v;
            else ${$_k} = _RunMagicQuotes($_v);
        }
    }

  这段代码就有用到可变变量。$$request其实就是$_GET 或$_POST或$_COOKIE,在织梦系统里面,用这些可变变量的地方还有文件上传功能里面等。


局部变量:

  在php里面的变量有局部变量,有全局变量,他们是相对而言的,举一个简单的例子,如果我们定义一个函数,在函数内部定义一个变量$a,那么,这个$a就是一个局部变量,他只能在这个函数中起作用,超出这个函数,这个变量就不起作用了,言外之意就是函数里面的变量不可以访问函数外的变量,举例子说明,例如有一个sum.php的程序文件,里面有如下代码。
 
  例子:

<?php

$a=5;

function sum($a){

$a+=7;

}
echo sum(3);
echo $a;

?>

  在这个例子中,函数sum()外面的变量$a和函数内部的$a虽然变量名完全一样,但是这他们是完全不同的二个变量,只是名字一样,就像重名的二个人,虽然,姓名一样,但是人完全不一样。这二个变量互不影响,相互独立。执行完这段代码后的结果是:10,5,结果正好说明这一点。

全局变量:

  在函数外部声明的变量,就是全局部量,全局变量可以在函数中使用,但前提是在要函数内部用global 全局变量名,声明后,就可以在函数中使用了。例如。

<?php
$a=5;

function say(){
  global $a;
  echo $a;
}
say();

?>

  如果在函数体外声明global $a,在函数内不能使用,例如:

<?php
global $a;
$a=5;

function say(){
  echo $a;
}
say();

?>

  这样是错误的!打印不出内容来。

  预定义超全局数组,我们知道,我们定义的变量都是有一定的作用域或称为作用范围的,但是在php系统里面系统定义了几个变量,这些变量在我们使用它们时,无需声明就可以使用,不管在什么地方,这些变量就是超全局变量,又称超全局数组,常用的超全局变量有9个,分别是$_GET、$_POST、$_SESSION、$_SERVER、$_COOKIE、$_REQUEST、$_ENV、$_FILES、$GLOBAL。

  这些超全局变量都有不同的作用,其中$_REQUEST包括$_GET,$_POST,$_SESSION这三个,也就是我们完全可以用$_REQUEST来代替这三个,但是请注意,这个会带来安全风险,所以,在一般情况下,当我们不知道传过来的值是用的什么方法时,我们才用$_REQUEST。但请请尽量不要用这个$_REQUEST。

  如果我们不知道传值方法的话,我们可以通过$_SERVER['REQUEST_METHOd']来判断访问页面使用的请求方法。

  我们分析一个超全局变量$_GET它是如何运行的。

  现在我们看一个例子:文件userlogin.php里面的代码是:
<?PHP
echo "你好"."<br>";

print_r($_GET);

?>
 
  当我们在浏览器输入http://www.dedebase.com/userlogin.php时,显示的结果是:

你好
Array ( )

  如果我们地址栏输入http://www.dedebase.com/userlogin.php?aa=bb&cc=nihao后,显示结果如下所示:


问题:

  当我们在userlogin.php后面加上 ?aa=bb&cc=nihao,程序自动帮我们收集问号后面的内容,并分装到数组里面,这是为什么呢?为什么一个$_GET就能得到一个数组,它是如何运行的呢?

  $_GET 运行原理:当我们在浏览器输入http://www.dedebase.com/userlogin.php?aa=bb&cc=nihao后,浏览器通过http协议访问apache(如果你空间装的是iis那么,他会访问iss)服务器,然后,apache服务器调用php模块,把提交的数据(也就是问号后面的aa=bb&cc=nihao)封装成超全局数组$_GET,并发给文件userlogin.php,然后,php模块把userlogin.php调用后的内容,发送给apache服务器,apache服务器,再把内容通过http协议发送给浏览器,浏览器就显示出如上图所示内容了。

  为了方便大家更直观的理解$_GET原理,制作如下图。

  现在又有一个问题,当我们通过get方法,即userlogin.php?aa=你好&cc=nihao传递中文参数时,在ie5,ie6下面会出现问题。如果是偶数个汉字,是正常显示的,如果是奇数位汉字,userlogin.php?aa=你好吗&cc=nihao这样传递参会出现乱码。

  解决方法:

  第一种:直接在userlogin.php?aa=你好吗&cc=nihao里面的“你好吗”后面加全角空格,即userlogin.php?aa=你好吗 &cc=nihao,然后在服务器端用trim()函数把空格去掉,这样就可以解决在ie5,ie6下的乱码,但这样不好。我们可以用第二种方法。

  第二种:用urlencode()进行编码,$str=urlencode("你好吗"),即userlogin.php?aa=".$str."&cc=nihao,后然,在服务器接收时用decode($_GET['aa'])解码(解码可以不用,php系统已经给我们自动帮我们解码)。
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

当我们需要在前端输出图片+对应的图片注释描述时,需要用到图集功能;当我们自定义模型或者商品模型、软件模型需要也要用到图片+注释描述时,也需要用到图集功能。 备份你后台目录以下4个文件 \dede\archives_add.php \dede\archives_edit.php \dede\templet
导出效果 添加教程 1、\dede\templets\diy_main.htm 找到 前台预览/a 在它的下面加入一行 | a href=diy_list.php?action=exceldiyid={dede:field.diyid/} target=_blank导出表单Excel/a 2、\dede\diy_list.php 找到 else{ showmsg(未定义操作, -1);} 在它的
需求:调用一个商城系统里面的产品数据到dedecms文章页,希望对需要类似需求的人有所帮助 功能实现:为了不用垮数据库查询,dedecms安装到商城系统数据库里面 下面是实现的代码(请根据自己的环境进行修改) include/taglib/hongyungoods.lib.php 文件内容如下
刚学习完dedecms的标签语法,我有很多困惑,觉得标签的意义比较抽象,不知道如何用标签来写一些具体的内容。如果有一些数据库的编程经验,就知道一个很常用的编程范例增删改查。比如说,我要建立的是书本的模型,有索书号,书名,类型,之后要写一个网页来完
理解织梦模板引擎有什么意义?一方面可以更好地自定义标签。更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步。理解织梦会使我们写php代码时更顺手,同时能学习一些php代码的组织方式。 这似乎不是那么简单,如果你只想学习自定义标签,可以看
制作网站主页、频道封面的时候,如果只是把某个栏目最新或者按特定排序方式的文档无选择的读出来,是存在很大不足的,还好织梦DedeCMS给用户提供了自定义文档属性功能,使用自定义属性之后,只要给arclist标记加上att='自定义属性的ID'的属性,然后在发布