找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1544|回复: 0

[分享] 织梦中预定义的超全局数组处理

[复制链接]
发表于 2018-1-27 09:24:48 | 显示全部楼层 |阅读模式 来自 中国–河南–新乡
当我们写好表单后,提交到对应php文件进行处理,在处理前首先要接收数据,然后对数据处理,以申请友情链接为例子。

  友情链接申请界面如下图所示:
1.webp
  当我们提交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,在栈内存中示意图如下所示。
2.webp
  当我们连续声明二个同样的变量即$a=5;$a=7;最后$a的值是7,前面的变量会被后面的变量覆盖掉。

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

  此时,如果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来管理的。

可变变量:

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

  1.   <?php

  2. $a="good";

  3. $a="ok";

  4. echo $good;
  5. ?>
复制代码


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

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

  1. foreach(Array('_GET','_POST','_COOKIE') as $_request)
  2.     {
  3.         foreach($_request as $_k => $_v)
  4.         {
  5.             if($_k == 'nvarname') ${$_k} = $_v;
  6.             else ${$_k} = _RunMagicQuotes($_v);
  7.         }
  8.     }
复制代码


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


局部变量:

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

  例子:

  1. <?php

  2. $a=5;

  3. function sum($a){

  4. $a+=7;

  5. }
  6. echo sum(3);
  7. echo $a;

  8. ?>
复制代码


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

全局变量:

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

  1. <?php
  2. $a=5;

  3. function say(){
  4.   global $a;
  5.   echo $a;
  6. }
  7. say();

  8. ?>
复制代码


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

  1. <?php
  2. global $a;
  3. $a=5;

  4. function say(){
  5.   echo $a;
  6. }
  7. say();

  8. ?>
复制代码


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

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

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

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

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

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

  3. print_r($_GET);

  4. ?>
复制代码


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

你好
Array ( )

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

问题:

  当我们在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原理,制作如下图。
5.webp
  现在又有一个问题,当我们通过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系统已经给我们自动帮我们解码)。

发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;

如何回报帮助你解决问题的坛友,好办法就是点击帖子下方的评分按钮给对方加【金币】不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号

关闭

站长推荐上一条 /1 下一条

QQ|侵权投诉|广告报价|手机版|小黑屋|西部数码代理|飘仙建站论坛 ( 豫ICP备2022021143号-1 )

GMT+8, 2024-11-26 11:24 , Processed in 0.048399 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表