• PHP表单


    【菜鸟教程】【参考1】【参考2】

    PHP表单

    <?php
    // 定义变量并默认设置为空值
    $nameErr = $emailErr = $genderErr = $websiteErr = "";
    $name = $email = $gender = $comment = $website = "";
    
    if ($_SERVER["REQUEST_METHOD"] == "POST")
    {
        if (empty($_POST["name"]))
        {
            $nameErr = "名字是必需的";
        }
        else
        {
            $name = test_input($_POST["name"]);
            // 检测名字是否只包含字母跟空格
            if (!preg_match("/^[a-zA-Z ]*$/",$name))
            {
                $nameErr = "只允许字母和空格"; 
            }
        }
        
        if (empty($_POST["email"]))
        {
          $emailErr = "邮箱是必需的";
        }
        else
        {
            $email = test_input($_POST["email"]);
            // 检测邮箱是否合法
            if (!preg_match("/([w-]+@[w-]+.[w-]+)/",$email))
            {
                $emailErr = "非法邮箱格式"; 
            }
        }
        
        if (empty($_POST["website"]))
        {
            $website = "";
        }
        else
        {
            $website = test_input($_POST["website"]);
            // 检测 URL 地址是否合法
            if (!preg_match("/(?:(?:https?|ftp)://|www.)[-a-z0-9+&@#/%?=~_|!:,.;]*[-a-z0-9+&@#/%=~_|]/i",$website))
            {
                $websiteErr = "非法的 URL 的地址"; 
            }
        }
        
        if (empty($_POST["comment"]))
        {
            $comment = "";
        }
        else
        {
            $comment = test_input($_POST["comment"]);
        }
        
        if (empty($_POST["gender"]))
        {
            $genderErr = "性别是必需的";
        }
        else
        {
            $gender = test_input($_POST["gender"]);
        }
    }
    
    function test_input($data)
    {
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        return $data;
    }
    ?>
    
    <h2>PHP 表单验证实例</h2>
    <p><span class="error">* 必需字段。</span></p>
    <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> 
       名字: <input type="text" name="name" value="<?php echo $name;?>">
       <span class="error">* <?php echo $nameErr;?></span>
       <br><br>
       E-mail: <input type="text" name="email" value="<?php echo $email;?>">
       <span class="error">* <?php echo $emailErr;?></span>
       <br><br>
       网址: <input type="text" name="website" value="<?php echo $website;?>">
       <span class="error"><?php echo $websiteErr;?></span>
       <br><br>
       备注: <textarea name="comment" rows="5" cols="40"><?php echo $comment;?></textarea>
       <br><br>
       性别:
       <input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?>  value="female"><input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?>  value="male"><span class="error">* <?php echo $genderErr;?></span>
       <br><br>
       <input type="submit" name="submit" value="Submit"> 
    </form>
    
    <?php
    echo "<h2>您输入的内容是:</h2>";
    echo $name;
    echo "<br>";
    echo $email;
    echo "<br>";
    echo $website;
    echo "<br>";
    echo $comment;
    echo "<br>";
    echo $gender;
    ?>

    效果如下图:

    PHP_SELF,SCRIPT_NAME,REQUEST_URI区别

    PHP_SELF

    http://www.yoursite.com/example/ — – — /example/index.php
    http://www.yoursite.com/example/index.php — – — /example/index.php
    http://www.yoursite.com/example/index.php?a=test — – — /example/index.php
    http://www.yoursite.com/example/index.php/dir/test — – — /dir/test

    当我们使用$_SERVER['PHP_SELF']的时候,无论访问的URL地址是否有index.php,它都会自动的返回 index.php.但是如果在文件名后面再加斜线的话,就会把后面所有的内容都返回在$_SERVER['PHP_SELF']。

    SCRIPT_NAME

    http://www.yoursite.com/example/ — – — /
    http://www.yoursite.com/example/index.php — – — /example/index.php
    http://www.yoursite.com/example/index.php?a=test — – — /example/index.php?a=test
    http://www.yoursite.com/example/index.php/dir/test — – — /example/index.php/dir/test

    $_SERVER['REQUEST_URI']返回的是我们在URL里写的精确的地址,如果URL只写到”/”,就返回 “/”

    REQUEST_URI

    http://www.yoursite.com/example/ — – — /example/index.php
    http://www.yoursite.com/example/index.php — – — /example/index.php
    http://www.yoursite.com/example/index.php — – — /example/index.php
    http://www.yoursite.com/example/index.php/dir/test — – — /example/index.php

    在所有的返回中都是当前的文件名/example/index.php

    REQUEST_URI 返回的是包括后面数据串的地址,如 index.php?str=1234 PHP_SELF 是 index.php

    $_SERVER[’PHP_SELF’]在开发的时候常会用到,一般用来引用当前网页地址,并且它是系统自动生成的全局变量,也会有什么问题么?让我们先看看下面的代码吧: 

    <form action=”<?php echo $_SERVER[’PHP_SELF’]; ?>”> <input type=”submit” name=”submit” value=”submit” /> </form> 


      这段代码非常简单,我们想用$_SERVER[’PHP_SELF’]来让网页提交时提交到它自己,假设代码文件名为test.php,在执行的时候就一定会得到我们期望的地址么?首先试试地址http://…/test.php,结果当然是没有问题的啦,别着急,你再访问一下http://…/test.php/a=1,将会得到如下客户端代码: 

    <form action=”/fwolf/temp/test.php/a=1″> <input type=”submit” name=”submit” value=”submit” /> </form> 


    显然,这已经超出了我们的期望,web服务器居然没有产生诸如404之类的错误,页面正常执行了,并且在生成的html代码中居然有用户可以输入的部分,恐怖的地方就在这里。别小看那个“a=1”,如果把它换成一段js代码,就显得更危险了,比如这么调用: 

    http://…/test.php/%22%3E%3Cscript%3Ealert(’xss’)%3C/script%3E%3Cfoo 

    那么,再来看看这个漏洞产生的原理,首先test.php/….这种调用是web服务器允许的,很多cms系统,比如我以前用过的plog,好像也是采用这种方式,在服务器不支持rewrite的情况下实现诸如http://… /index.php/archive/999这样的固定网址的(我以前还以为是对404错误页下的手),所以带“/”的地址无法从web服务器上禁止。然后再看看php中对$_SERVER[’PHP_SELF’]的识别,他就是一个包含当前网址值的全局变量,天知道用户会输入什么样的网站,在上面的例子中是恶意的,可是在wikipedia这样的网站上,却又是可以正常使用这种方式的地址的。所以,最终的结论要落在开发人员身上了,没有很好的处理与用户交互的数据。 

      从安全角度来讲,在开发应用尤其是web应用的时候,所有用户提交的数据都是不安全的,这是基本原则,所以我们才不厌其烦的又是客户端验证又是服务端验证。从上面说的这个安全漏洞来讲,不安全的内容中又要增加“网址”一条了。要解决$_SERVER[’PHP_SELF’]的安全隐患,主要有以下2种方式: 

      1、htmlentities 

      用htmlentities($_SERVER[’PHP_SELF’])来替代简单的$_SERVER[’PHP_SELF’],这样即使网址中包含恶意代码,也会被“转换”为用于显示的html代码,而不是被直接嵌入html代码中执行,简单一点说,就是“<”会变成“<”,变成无害的了。 

      2、REQUEST_URI 

      用$_SERVER[’REQUEST_URI’]来替代$_SERVER[’PHP_SELF’],在phpinfo()中可以看到这两个变量的区别: 

    _SERVER[”REQUEST_URI”] /fwolf/temp/test.php/%22%3E%3Cscript%3Ealert(’xss’)%3C/script%3E%3Cfoo _SERVER[”PHP_SELF”] /fwolf/temp/test.php/”> 

      $_SERVER[’REQUEST_URI’]会原封不动的反映网址本身,网址中如果有%3C,那么你得到的也将会是%3C,而$ _SERVER[’PHP_SELF’]会对网址进行一次urldecode操作,网址中的%3C将会变成字符“<”,所以就产生了漏洞。需要注意的是,在很多情况下,浏览器会对用户输入要提交给web服务器的内容进行encode,然后服务器端程序会自动进行decode,得到相应的原指,在我们进行post或者get操作的时候都是这样。 

      另外还有两点需要指出,第一是这种写法虽然没有直接用到$_SERVER[’PHP_SELF’],但实际效果却是一样的,只是发生的时间错后到了用户提交之后的下一个页面,所以,form的action还是不要留空的好。第二点,除了PHP_SELF之外,其他的$_SERVER变量也许也会有类似的漏洞,比如SCRIPT_URI, SCRIPT_URL, QUERY_STRING, PATH_INFO, PATH_TRANSLATED等等,在使用他们之前一定要先作htmlentities之类的

  • 相关阅读:
    (转载)C#如何在任务管理器中不显示指定的窗体
    Windows上配置Mask R-CNN及运行示例demo.ipynb
    如何选择普通索引和唯一索引?
    relay(跳板机)搭建
    javascript 9x9乘法口诀表
    canvas画布爆炸
    Chrome Network Timing 解释
    JavaScript中对数组的定义
    jquery each 和 map 区别
    css 兼容性转换网站
  • 原文地址:https://www.cnblogs.com/kuboy/p/7828765.html
Copyright © 2020-2023  润新知