php利用验证码防止恶意注册学习笔记
今天我们来研究下PHP验证码,我们通过简单的数字验证码来实现,首先来写一个生成验证码的代码:
代码如下 | 复制代码 |
<?php //随机生成一个4位数的数字验证码 $num=”"; for($i=0;$i<4;$i++){ $num .= rand(0,9); } //4位验证码也可以用rand(1000,9999)直接生成 //将生成的验证码写入session,备验证页面使用 Session_start(); $_SESSION["Checknum"] = $num; //创建图片,定义颜色值 Header(“Content-type: image/PNG”); srand((double)microtime()*1000000); $im = imagecreate(60,20); $black = ImageColorAllocate($im, 0,0,0); $gray = ImageColorAllocate($im, 200,200,200); imagefill($im,0,0,$gray); //随机绘制两条虚线,起干扰作用 $style = array($black, $black, $black, $black, $black, $gray, $gray, $gray, $gray, $gray); imagesetstyle($im, $style); $y1=rand(0,20); $y2=rand(0,20); $y3=rand(0,20); $y4=rand(0,20); imageline($im, 0, $y1, 60, $y3, IMG_COLOR_STYLED); imageline($im, 0, $y2, 60, $y4, IMG_COLOR_STYLED) //在画布上随机生成大量黑点,起干扰作用; for($i=0;$i<80;$i++) { imagesetpixel($im, rand(0,60), rand(0,20), $black); } //将四个数字随机显示在画布上,字符的水平间距和位置都按一定波动范围随机生成 $strx=rand(3,8); for($i=0;$i<4;$i++){ $strpos=rand(1,6); imagestring($im,5,$strx,$strpos, substr($num,$i,1), $black); $strx+=rand(8,12); } ImagePNG($im); ImageDestroy($im); ?> |
在reg.php页面我们写一个表单:(此处省去了其他的HTML代码)
代码如下 | 复制代码 |
<tr> <td>验证码 :</td> <td><input type=”text” name=”yzm”style=”width:60px;height:20px;” /><img src=”code.php” onclick=”javascript:this.src=’code.php?’+Math.random();”></img></td> </tr> <tr> <td colspan=’2′><input type=”submit” value=”注册”/></td> <td>验证码 :</td> </tr> |
因为我们是用post提交的,所以我们用$_POST来获取(在接受页面做验证码的验证:post.php页面)
代码如下 | 复制代码 |
Session_start(); //back_alert()验证码输入错误的时候,弹出错误信息 function back_alert($yzm){ echo “<script type=’text/javascript’>alert(‘$yzm’);history.back();</script>”; } //禁止恶意调用(禁止直接在浏览器打开post.php页面) if($_POST["yzm"]==null){ back_alert(‘你都木有输入验证码,有木有???’); } // 禁止恶意注册 if(!($_POST["yzm"]==$_SESSION["Checknum"])){ back_alert(‘验证码不正确’); } echo $_POST["yzm"]; |
API(Application Programming Interface,应用程序编程接口)在WEB应用中是非常常见的,比如开发微薄应用有微薄API,做淘宝的有淘宝API,不同的API有不同的接口方式,一般API都有一个URL的访问地址,通过这个访问地址可以获取到用户的自定义数据,但这并不是公开的,比如经过了认证后才能正确的访问到数据。
使用新浪微博API发布一条微薄就需要提供用户名和密码认证后才能正确的发布微薄,总结了一下主要有以下几种API接口认证思路:
1. 使用HTTP Basic Authentication
在你访问一个需要HTTP Basic Authentication的URL的时候,如果你没有提供用户名和密码,服务器就会返回401,如果你直接在浏览器中打开,浏览器会提示你输入用户名和密码(google浏览器不会,bug?)。你可以尝试点击这个url看看效果:http://api.minicloud.com.cn/statuses/friends_timeline.xml
要在发送请求的时候添加HTTP Basic Authentication认证信息到请求中,有两种方法:
一是在请求头中添加Authorization:
代码如下 | 复制代码 |
Authorization: “Basic 用户名和密码的base64加密字符串” |
二是在url中添加用户名和密码:
http://userName:password@api.minicloud.com.cn/statuses/friends_timeline.xml
代码如下 | 复制代码 |
$fp = fsockopen("www.mydomain.com",80); fputs($fp,"GET /downloads HTTP/1.0"); fputs($fp,"Host: www.mydomain.com"); fputs($fp,"Authorization: Basic " . base64_encode("user:pass") . ""); fpassthru($fp); |
2.使用Oauth认证
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。
下载地址:http://code.google.com/p/oauth2-php/downloads/list
3. 使用SOAP
对于应用程序开发来说,使程序之间进行因特网通信是很重要的。
目前的应用程序通过使用远程过程调用(RPC)在诸如 DCOM 与 CORBA 等对象之间进行通信,但是 HTTP 不是为此设计的。RPC 会产生兼容性以及安全问题;防火墙和代理服务器通常会阻止此类流量。
通过 HTTP 在应用程序间通信是更好的方法,因为 HTTP 得到了所有的因特网浏览器及服务器的支持。SOAP 就是被创造出来完成这个任务的。
SOAP 提供了一种标准的方法,使得运行在不同的操作系统并使用不同的技术和编程语言的应用程序可以互相进行通信。
运算符优先级是一个程序员必须了解并且撑握的一个重要的知识点了,下面我们一起来看看PHP运算符优先级文章吧。今天在老王的技术手册看到一个问题:
代码如下 | 复制代码 |
<?phpif ($a = 100 && $b = 200) { var_dump($a, $b);} |
输出是什么?
这个问题, 咋一看或许觉得简单, 但其实仔细推敲并不简单,
如果说布尔与之前的部分, 是由于优先级的问题, 但是如果仅仅是优先级的问题的话, 那么结果应该是:
代码如下 | 复制代码 |
$a = (100 && $b) = 200 |
而实际上的结果, 确实高优先级的&&让步给次优先级的=, 让 $b = 200 先结合了.
究其原因, 是因为PHP并不完全遵守优先级的定义, 这个在PHP的手册中也有说明:
Note: Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.
这样的设计, 个人不发表看法, 反正在C语言中, 这样类似的语句是判定为语法错的. PHP采用这样的设计, 很可能是历史原因,
有好奇的同学, 会想知道到底为什么, 之前jayeeliu网友也问过:
laruence你好:
问一个php运算符优先级的问题
代码如下 | 复制代码 |
$t == 1 && $tt = 2 |
按照php运算符优先级应该是
代码如下 | 复制代码 |
(($t == 1) && $tt) = 2 |
这个顺序执行,但实际上应该是
代码如下 | 复制代码 |
($t == 1) && ($tt = 2) |
我有些不太理解。
其实也简单, 运算符优先级是在存在二义性文法的时候的一种规约规则选择的手段, 而PHP的语法分析文件定义中, 却让等号和T_BOOLEAN_AND(&&)之前不存在了规约冲突:
代码如下 | 复制代码 |
expr_without_variable: |
最后, 顺便说一下, PHP对应于T_BOOLEAN_AND 还定义了 T_LOGICAL_AND(and) 和 T_LOGICAL_OR(or) , 这俩个的优先级都低于等号, 于是就会有了, 很多PHP入门教材示例代码中经典的:
代码如下 | 复制代码 |
$result = mysql_query(*) or die(mysql_error()); |
类似的还可以用or来实现三元操作符(?:)的功能:
代码如下 | 复制代码 |
$person = $who or $person = "laruence"; |
//等同于:
代码如下 | 复制代码 |
$person = empty($who)? "laruence" : $who; |
结合方向 |
运算符 |
---|---|
左 | , |
左 | or |
左 | xor |
左 | and |
右 | |
右 | = += -= *= /= .= %= &= |= ^= ~= <<= >>= |
左 | ? : |
左 | || |
左 | && |
左 | | |
左 | ^ |
左 | & |
无 | == != === !== |
无 | < <= > >= |
左 | << >> |
左 | + - . |
左 | * / % |
右 | ! ~ ++ -- (int) (float) (string) (array) (object) @ |
右 | [ |
无 | new |
例
代码如下 | 复制代码 |
<?php $a=12;
echo '$a='.$a//输出结果 ?> 输出的结果:$a=24 |
总结:在函数体内定义的global变量,函数体外可以使用,在函数体外定义的global变量不能在函数体内使用,
代码如下 | 复制代码 |
$glpbal $a; function f() //再看看下面一例 function f() f(); |
上面的实例只是基本的global全局变量知识,下面我们看看复杂点的:
代码如下 | 复制代码 |
//A.php 文件 <?php $a = 0 ; //B.php 文件 <?php |
为什么输出的却是0?!!
在用户自定义函数中,一个局部函数范围将被引入。任何用于函数内部的变量按缺省情况将被限制在局部函数范围内(包括include 和 require 导入的文件内的变量)!
解释:A.php文件的内Test_Global是定义好的第三方函数,该函数用include导入了B.php文件内的$a的global全局变量,所以$a被限制在Test_Global局部函数范围内,所以B.php文件内的$a的作用范围都在Test_Global内,而不是作用了整个A.php内….
解决方案:
1. 冲出局部函数
代码如下 | 复制代码 |
//A.php 文件 <?php //B.php 文件 <?php |
global问题解析:
question:我在config.inc.php中定义了一些变量($a),在别的文件中函数外部 include("config.inc.php"),函数内部需要使用这些变量$a,如果没有声明的话,echo $a是打印不出来任何东西的。因此声明global $a,但是有很多函数和很多变量,总不能不断重复的这样声明吧?有什么好的解决办法,请指点。
answer1:先在config.inc.php里定义常量:define(常量名,常量值)
再在其他需要用到的地方require 'config.inc.php',
然后就能在这个文件里直接使用这个常量了。
answer2:我也有个办法,就是定义数组,如$x[a],$x,那样就只要声明global $x一个了。
answer3:我试了你的这个方法,不行啊。
answer4:改你的php.ini文件。
① 创建数组第一种方法
$arr[0]=123;
$arr[1]=90;
….
概念:
[0] -> 这个我们称为下标,或者称为 关键字
$arr[0] -> 这个称为数组的一个元素.
$arr[0]=123; 123 表示该$arr[0]元素对应的值
$arr –》这个是该数组的名称.
☞在php数组中,元素存放的值可以是任意数据数据类型
② 创建数组的第二种方法
基本语法
$数组名=array(值1,值2,.......);
举例说明:
$arr=array(1,90,"helllo",89.5);
③ 第三种方式创建数组(在默认情况下,我们的元素的下标,是从0开始给你编号,但是实际上,也可以自己指定)
基本语法$arr[‘logo’]=”北京”;
$arr[’hsp’]=123;
....
或者
$arr=array(”logo”=>”北京”,”hsp”=>123,4=>678);
数组的遍历方法:
注: 如果使用 for while do..while 要确定该数组的下标是从 0开始顺序排放
数组共有多少个元素,可以使用系统函数count
//
代码如下 | 复制代码 |
for循环遍历方法 //while循环遍历方法 //do..while //foreach 遍历方法 |
php的数组相关的函数
① count 函数
基本用法是
count($数组名); 可以统计该数组共有多少元素.
② is_array
③ print_r 和 var_dump
④ explode 对字符串进行分割
案例:
$str="浙江&台州&杭州";
//在实际开发中,涉及到字符串的拆分,可以考虑
$arr=explode("&",$str);
print_r($arr);
数组查找
例子:
代码如下 | 复制代码 |
<?php |
例子输出结果如下:
键名为:0
array_key_exists()函数
如果在一个数组中找到一个指定的键,函数array_key_exists()返回true,否则返回false。其形式如下:
boolean array_key_exists(mixed key,array array);
下面的例子将在数组键中搜索apple,如果找到,将输出这个水果的颜色:
代码如下 | 复制代码 |
$fruit["apple"] = "red"; |
执行这段代码得到的结果:
apple's color is red
合并数组
array_merge()函数将数组合并到一起,返回一个联合的数组。所得到的数组以第一个输入数组参数开始,按后面数组参数出现的顺序依次迫加。其形式为:
Php代码
array array_merge (array array1 array2…,arrayN)
这个函数将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。
如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。
如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。
代码如下 | 复制代码 |
<?php // output |
2. 追加数组
array_merge_recursive()函数与array_merge()相同,可以将两个或多个数组合并在一起,形成一个联合的数组.两者之间的区别在于,当某个输入数组中的某个键己经存在于结果数组中时该函数会采取不同的处理方式.array_merge()会覆盖前面存在的键/值对,替换为当前输入数组中的键/值对,而array_merge_recursive()将把两个值合并在一起,形成一个新的数组,并以原有的键作为数组名。还有一个数组合并的形式,就是递归追加数组。其形式为:
Php代码
array array_merge_recursive(array array1,array array2[…,array arrayN])
程序实例如下:
代码如下 | 复制代码 |
<?php // output |
现在键 apple 指向一个数组,这个数组由两个颜色值组成的索引数组。
3. 连接数组
array_combine()函数会得到一个新数组,它由一组提交的键和对应的值组成。其形式为:
array array_combine(array keys,array values)
注意,两个输入数组必须大小相同,不能为空。示例如下
代码如下 | 复制代码 |
// output
|
4. 拆分数组 array_slice()
array_slice()函数将返回数组中的一部分,从键offset开始,到offset+length位置结束。其形式:
Php代码
array array_slice (array array, int offset[,int length])
offset 为正值时,拆分将从距数组开头的offset 位置开始;如果offset 为负值,则拆分从距数组末尾的offset 位置开始。如果省略了可选参数length,则拆分将从offset 开始,一直到数组的最后一个元素。如果给出了length 且为正数,则会在距数组开头的offset+length 位置结束。相反,如果给出了length且为负数,则在距数组开头的count(input_array)-|length|位置结束。考虑一个例子:
代码如下 | 复制代码 |
<?php $fruits = array("Apple", "Banana", "Orange", "Pear", "Grape", "Lemon", "Watermelon"); // output |
数组排序(下面方法用于一维数组)
•sort() 函数用于对数组单元从低到高进行排序。
•rsort() 函数用于对数组单元从高到低进行排序。
•asort() 函数用于对数组单元从低到高进行排序并保持索引关系。
•arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。
•ksort() 函数用于对数组单元按照键名从低到高进行排序。
•krsort() 函数用于对数组单元按照键名从高到低进行排序。
多维数组排序
比如有个多为数组:
代码如下 | 复制代码 |
$arr = array( |
需要对二维数组中的 age 项排序。
需要用到PHP的内置函数 array_multisort(),可以看手册。
自定义函数:
代码如下 | 复制代码 |
function multi_array_sort($multi_array,$sort_key,$sort=SORT_ASC){ //处理 echo “<pre/>”; //输出 Array [b] => Array [a] => Array [d] => Array ) |
written by 大宇
相关文章
- 最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
Django def clean()函数对表单中的数据进行验证操作
这篇文章主要介绍了Django def clean()函数对表单中的数据进行验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-09jQuery Real Person验证码插件防止表单自动提交
本文介绍的jQuery插件有点特殊,防自动提交表单的验证工具,就是我们经常用到的验证码工具,先给大家看看效果。效果图如下: 使用说明 需要使用jQuery库文件和Real Person库文件 同时需要自定义验证码显示的CSS样式 使用实例...2015-11-08- 这篇文章主要为大家详细介绍了JS实现随机生成验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-06
- 这篇文章主要为大家详细介绍了JavaScript实现密码框输入验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-01
- 这篇文章主要介绍了Nest.js 授权验证的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-22
- 通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能效果图:先到官网(http://plugins.jquery.com/cookie/)下载cookie插件,放到相应文件夹,代码如下:复制代码 代码如下: <!DOCTYPE ht...2015-03-15
- 验证码类文件 CreateImg.class.php <?php class ValidationCode { private $width,$height,$codenum; public $checkcode; //产生的验证码 private $checkimage; //验证码图片 private $disturbColor = ''; /...2015-11-08
- 这篇文章主要介绍了el-table树形表格表单验证(列表生成序号),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-01
- 我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
- 1、简介Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目...2014-05-31
- 这篇文章主要介绍了基于JavaScript实现验证码功能的相关资料...2017-04-03
- 这篇文章主要介绍了selenium 反爬虫之跳过淘宝滑块验证功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-27
vue element table中自定义一些input的验证操作
这篇文章主要介绍了vue element table中自定义一些input的验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18- 这篇文章主要为大家详细介绍了js canvas实现滑块验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-03-14
- 这篇文章主要为大家详细介绍了vue实现表单验证小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-29
- 下面小编就为大家带来一篇单击按钮发送验证码,出现倒计时的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 代码...2017-07-06
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
这篇文章主要介绍了Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2016-06-24- 验证码是一个现在WEB2.0中常见的一个功能了,像注册、登录又或者是留言页面,都需要注册码来验证当前操作者的合法性,我们会看到有些网站没有验证码,但那是更高级的验证了,...2016-11-25
- 这篇文章主要介绍了基于Pytorch版yolov5的滑块验证码破解思路详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-25