首页 > 编程技术 > php

php判断客户端IP来防止重复提交表单的方法

发布时间:2016-11-25 16:46

如果你的网站有表单提交的话,可能会遇到有人恶意提交表单,现在我们来用php通过记录客户端ip地址来防止表单重复提交,代码分享给大家。

本文实例分析了php通过记录IP来防止表单重复提交方法。分享给大家供大家参考。具体分析如下:

这个原理比较的简单就是用户第一次提交时我们记录提交用户的IP地址,这样如果用户在固定时间内再次提交表单就会提示重复提交了,这种做法通常用于在顶一下,支持一下这种应用中了,在防止数据重复提交是一个非常不好的选择.

例子,代码如下:

 代码如下 复制代码
<?php
 session_start();
if(empty($_SESSION['ip']))//第一次写入操作,判断是否记录了IP地址,以此知道是否要写入数据库
{
$_SESSION['ip']=$_SERVER['REMOTE_ADDR'];//第一次写入,为后面刷新或后退的判断做个铺垫
mysql_query("INSERT INTO admin(id, name, age) VALUES(123, '姚明', 25)");//写入数据库操作
}
else//已经有第一次写入后的操作,也就不再写入数据库
{
echo '请不要重复提交表单或刷新页面';//写一些已经写入的提示或其它东西
}
?>

还有办法就是:

1:在页面生成随机码,也就是每次提交随机码都不一样,在提交的时候验证随机码!

2:在提交的时候,验证如果数据存在,就不提交了.

如果你想防止重复提交入库IP不是最好的办法,我们可以在数据库中查询是不是有相同记录并且IP是不是想同再进行处理.

例子,代码如下:

 代码如下 复制代码
$sql ="select * from 表名 where buy_tel='电话' and IP='$ip'   ";// and $time-buy_date<60
$query = $db->query( $sql );
if( $db->rows( $query ) )
{
echo('<script>alert("您己提交过了,请勿重复提交!");</script>');
}
else
{
//进行入库操作
}

希望本文所述对大家的PHP程序设计有所帮助。

网站文件上传安全性不容忽视,我们第一步验证就是限制上传扩展名,只能上传我们规定的文件扩展名,现在我们用php的ereg来验证上传文件。

ereg格式如下:

 代码如下 复制代码
ereg(正规表达式,字符串,[匹配部分数组名]);

 这里利用了ereg来验证用户上传的文件类型与文件名是否是符合文件命名规则,实例代码如下:

 代码如下 复制代码
if( !is_uploaded_file($upfile) )
 {
  echo("你什么都没有上传哦!");
  exit();
 }
 else
 {
  if( !ereg(".(htm|html)$", $upfile_name) )
  {
   echo("dedecms模板只能用 .htm 或 .html扩展名!");
    exit();
  }
  if( ereg("[/]",$upfile_name) )
  {
   echo("模板文件名有非法字符,禁止上传!-1");
    exit();
  }
  move_uploaded_file($upfile, $templetdird.'/'.$upfile_name);
  @unlink($upfile);
  echo("成功上传一个文件!");
  exit();
 }
 exit();

现在我们只是讲了验证上传的文件名是否合法,以后的教程我们会继续讲怎么判断上传的内容是否安全。

本实例讲的是用用PHP将科学计数法转为正常数字的函数,本函数经本人实测可用,现在分享给大家。

PHP实现将科学计数法转换为原始数字字符串的方法实现代码如下:

 代码如下 复制代码
function NumToStr($num){
    if (stripos($num,'e')===false) return $num;
    $num = trim(preg_replace('/[='"]/','',$num,1),'"');//出现科学计数法,还原成字符串
    $result = "";
    while ($num > 0){
        $v = $num - floor($num / 10)*10;
        $num = floor($num / 10);
        $result   =   $v . $result;
    }
    return $result;
}


希望本函数对学习php的同学有所帮助。

之前听到过的一个前辈关于php性能优化的说法——PHP为我们提供了那么多的原声函数,我们尽量用原生函数解决问题。但是有时在想,php原生态的函数就一定快吗?现在看到一个国外的人写的函数,就来测试一下。

今天在阅读kohana源码中的Arr类的时候发现了这样一个函数

 代码如下 复制代码
/**
 * Fill an array with a range of numbers.
 *
 *     // Fill an array with values 5, 10, 15, 20
 *     $values = Arr::range(5, 20);
 *
 * @param   integer $step   stepping
 * @param   integer $max    ending number
 * @return  array
 */
public static function range($step = 10, $max = 100)
{
    if ($step < 1)
        return array();

    $array = array();
    for ($i = $step; $i <= $max; $i += $step)
    {
        $array[$i] = $i;
    }

    return $array;
}


看到这里的时候,我发现php的原声函数也是可以实现这个功能的,忽然想到之前听到过的一个前辈关于php性能优化的说法——PHP为我们提供了那么多的原声函数,我们尽量用原生函数解决问题。于是我就做了个测试,看看php原生函数性能究竟比自己写的快多少。要测试的函数有原生函数range()和上面的函数_range(),这里加下划线开始是因为重写原声函数range()会报错“Fatal error: Cannot redeclare range() in”。

 代码如下 复制代码
function _range($step = 10, $max = 100)
{
    if ($step < 1)
        return array();
    $array = array();
    for ($i = $step; $i <= $max; $i += $step)
    {
        $array[$i] = $i;
    }
    return $array;
}
$time['begin'] = microtime(true);
$tmp = range(0,1000000,3);
//$tmp = _range(0,1000000,3);
$time['end']   = microtime(true);


echo $time['end'] - $time['begin'].'s'."r";
echo (memory_get_peak_usage()/1024/1024)."M";


分别用原生函数和自定义函数进行测试,在产生0~1000000之间所有的3的倍数时,结果出乎我的意料:

首先是使用原生函数的结果:

使用PHP原生函数就一定比自定义函数快吗?

下面是使用自定义函数的结果:

使用PHP原生函数就一定比自定义函数快吗?

为了结果比较准确,我在做个图表统计
统计次数     原生函数range()     自定义函数_range()
(0,1000000,3)     5.155E-3s     27.5530M     1.907E-5s     0.1241M
(0,1000000,2)     7.479E-3s     40.2688M     1.811E-5s     0.1241M
(0,1000,1)     8.16E-5s     0.1620M     2.649E-5s     0.1241M

从表中可以看出产生随机数时自定义函数比原生函数要节省内存和时间,而且原生函数在生成大量随机数时特别耗内存,消耗时间也特别多,而自定义函数在这方面则表现得好,产生的内存和消耗的时间基本稳定,看来前面那位前辈说的不一定完全正确哦,但是这里要注意我们这里的自定义函数只能生成数字,而原生的range还可以产生字母的,但是我想这自定义函数添加个字母应该也不会太难~

看来kohana官方对range这个函数很是了解,对php内核中该函数的复杂度也很了解,所以这个小优化才可以做这么好,太厉害了!!!

我们知道在PHP中没有函数重载这个概念,让很多时候我们无法进行一些处理,甚至有时候不得不在函数后面定义好N个参数只有使用func_get_arg,func_get_args,func_num_args实现伪重载了,下面一起来看看吧。

偶尔在网上看到关于php的伪重载的问题,有点兴趣便研究了一下。下面作者将说说php如何利用func_get_arg,func_get_args,func_num_args实现函数的伪重载问题。

首先说说方法重载的好处:

实现方法重载可以不用为了对不同的参数类型或参数个数,而写多个函数。多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。如果我们使用reflector去查看微软写的.net的基类库的话,我们可以发现他使用很多的方法重载,这样我们在调用的时候,就不需要记那么多的方法名称,而是知道了方法的功能就可以直接的给他传递不同的参数,编译器会明确的知道我们调用了哪一个方法。

但是在PHP中没有函数重载这个概念,让很多时候我们无法进行一些处理,甚至有时候不得不在函数后面定义好N个参数来解决相关问题,而php提供了几个函数,比如:func_get_arg,func_get_args,func_num_args 却可以直接解决相关问题。具体举个示例代码如下:

 代码如下 复制代码
<?php
function  testOne($a) {
echo ('一个参数就这样 ');
}
function testTwo($a, $b) {
 echo ('两个参数的就这样 ');
}
function testThree($a, $b, $c) {
 echo ('呵呵,这是三个参数的 ');
}
function test() {
 $argNum = func_num_args();
 // 这一段其实可以用 $_arg = func_get_args() 来获得所有的参数,只是要用数组而已,不方便我下面的表达,呵呵
 for ($i = 0; $i < $argNum; $i++) {
  $_arg_{$i} = func_get_arg($i);
 }
 switch ($argNum) {
  case 1 :
   testOne($_arg_1);
  break ;
  case 2 :
   testTwo($_arg_1, $_arg_2);
  break ;
  case 3 :
   testThree($_arg_1, $_arg_2, $_arg_3);
  break ;
  default :
   echo (' 这是没有参数的情况 ');
  break ;
 }
}
/**
 * 例子的实现
 */
test();
echo ('<br>');
test(1);
echo ('<br>');
test(1, 2);
echo ('<br>');
test(1, 2, 3);
// 这些只是在函数中的运用,其实最主要的还是在类中的运用
// 如果这些用到类里面我就不需要担心构造函数是否有几个参数了,不是吗?
// 类里面的运用只举一个简单的例子
class test{
 var $a = 0;
 var $b = 0;
 function test() {
  $argNum = func_num_args();
  $_arg = func_get_args();
  switch ($argNum) {
   case 1 :
    $this->test1($_arg[0]);
   break ;
   case 2 :
    $this->test2($_arg[0], $_arg[1]);
   break;
   default :
    $this->a = 0;
    $this->b = 1;
   break;
  }
 }
 function test1($a) {
  $this->a = $a;
 }
 function test2($a, $b) {
  $this->a = $a;
  $this->b = $b ;
 }
}

友情提示

php的的func_num_args、func_get_arg和func_get_args都是返回函数实参相关的函数。

func_num_args:实参个数;

func_get_arg:返回某一个实参,必须事实参数组的索引;

func_get_args:返回实参数组;

标签:[!--infotagslink--]

您可能感兴趣的文章: