PHP用户注册登录功能完整实例
验证码制作
一、实验简介
本次实验将会带领大家使用面向对象的思想封装一个验证码类。并在注册和登陆界面展示使用。通过本次实验的学习,你将会领悟到 PHP 的 OOP 思想,以及 GD 库的使用,验证码生成。
1.1 涉及到的知识点
PHP
GD库
OOP编程
1.2 开发工具
sublime,一个方便快速的文本编辑器。点击桌面左下角: 应用程序菜单/开发/sublime
1.3 效果图
二、封装验证码类
2.1 建立目录以及准备字体
在 web 目录下建立一个 admin 目录作为我们的后台目录,存放后台代码文件。在 admin 下建立一个 fonts 目录,用于存放制作验证码所需字体。
在 admin 下新建一个 Captcha.php 文件,这就是我们需要编辑的验证码类文件。
当前目录层次结构:
编辑 Captcha.php 文件:
<?php
/**
* Captcha class
*/
class Captcha
{
function __construct()
{
# code...
}
}
添加该类的私有属性和构造方法:
<?php
/**
* Captcha class
*/
class Captcha
{
private $codeNum; //验证码位数
private $width; //验证码图片宽度
private $height; //验证码图片高度
private $img; //图像资源句柄
private $lineFlag; //是否生成干扰线条
private $piexFlag; //是否生成干扰点
private $fontSize; //字体大小
private $code; //验证码字符
private $string; //生成验证码的字符集
private $font; //字体
function __construct($codeNum = 4,$height = 50,$width = 150,$fontSize = 20,$lineFlag = true,$piexFlag = true)
{
$this->string = 'qwertyupmkjnhbgvfcdsxa123456789'; //去除一些相近的字符
$this->codeNum = $codeNum;
$this->height = $height;
$this->width = $width;
$this->lineFlag = $lineFlag;
$this->piexFlag = $piexFlag;
$this->font = dirname(__FILE__).'/fonts/consola.ttf';
$this->fontSize = $fontSize;
}
}
字体文件可通过以下命令下载到 fonts 目录:
$ wget http://labfile.oss.aliyuncs.com/courses/587/consola.ttf
接下来开始编写具体的方法:
创建图像资源句柄
//创建图像资源
public function createImage(){
$this->img = imagecreate($this->width, $this->height); //创建图像资源
imagecolorallocate($this->img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100)); //填充图像背景(使用浅色)
}
用到的相关函数
imagecreate:新建一个基于调色板的图像
imagecolorallocate:为一幅图像分配颜色
mt_rand:生成更好的随机数
创建验证码字符串并输出到图像
//创建验证码
public function createCode(){
$strlen = strlen($this->string)-1;
for ($i=0; $i < $this->codeNum; $i++) {
$this->code .= $this->string[mt_rand(0,$strlen)]; //从字符集中随机取出四个字符拼接
}
$_SESSION['code'] = $this->code; //加入 session 中
//计算每个字符间距
$diff = $this->width/$this->codeNum;
for ($i=0; $i < $this->codeNum; $i++) {
//为每个字符生成颜色(使用深色)
$txtColor = imagecolorallocate($this->img,mt_rand(100,255),mt_rand(100,255),mt_rand(100,255));
//写入图像
imagettftext($this->img, $this->fontSize, mt_rand(-30,30), $diff*$i+mt_rand(3,8), mt_rand(20,$this->height-10), $txtColor, $this->font, $this->code[$i]);
}
}
用到的相关函数:
imagettftext:用 TrueType 字体向图像写入文本
创建干扰线条
//创建干扰线条(默认四条)
public function createLines(){
for ($i=0; $i < 4; $i++) {
$color = imagecolorallocate($this->img,mt_rand(0,155),mt_rand(0,155),mt_rand(0,155)); //使用浅色
imageline($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
}
}
用到的相关函数:
imageline:画一条线段
创建干扰点
//创建干扰点 (默认一百个点)
public function createPiex(){
for ($i=0; $i < 100; $i++) {
$color = imagecolorallocate($this->img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
imagesetpixel($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
}
}
使用的相关函数:
imagesetpixel:画一个单一像素
对外输出图像:
public function show()
{
$this->createImage();
$this->createCode();
if ($this->lineFlag) { //是否创建干扰线条
$this->createLines();
}
if ($this->piexFlag) { //是否创建干扰点
$this->createPiex();
}
header('Content-type:image/png'); //请求页面的内容是png格式的图像
imagepng($this->img); //以png格式输出图像
imagedestroy($this->img); //清除图像资源,释放内存
}
用到的相关函数:
imagepng:以 PNG 格式将图像输出到浏览器或文件
imagedestroy:销毁一图像
对外提供验证码:
public function getCode(){
return $this->code;
}
完整代码如下:
<?php
/**
* Captcha class
*/
class Captcha
{
private $codeNum;
private $width;
private $height;
private $img;
private $lineFlag;
private $piexFlag;
private $fontSize;
private $code;
private $string;
private $font;
function __construct($codeNum = 4,$height = 50,$width = 150,$fontSize = 20,$lineFlag = true,$piexFlag = true)
{
$this->string = 'qwertyupmkjnhbgvfcdsxa123456789';
$this->codeNum = $codeNum;
$this->height = $height;
$this->width = $width;
$this->lineFlag = $lineFlag;
$this->piexFlag = $piexFlag;
$this->font = dirname(__FILE__).'/fonts/consola.ttf';
$this->fontSize = $fontSize;
}
public function createImage(){
$this->img = imagecreate($this->width, $this->height);
imagecolorallocate($this->img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100));
}
public function createCode(){
$strlen = strlen($this->string)-1;
for ($i=0; $i < $this->codeNum; $i++) {
$this->code .= $this->string[mt_rand(0,$strlen)];
}
$_SESSION['code'] = $this->code;
$diff = $this->width/$this->codeNum;
for ($i=0; $i < $this->codeNum; $i++) {
$txtColor = imagecolorallocate($this->img,mt_rand(100,255),mt_rand(100,255),mt_rand(100,255));
imagettftext($this->img, $this->fontSize, mt_rand(-30,30), $diff*$i+mt_rand(3,8), mt_rand(20,$this->height-10), $txtColor, $this->font, $this->code[$i]);
}
}
public function createLines(){
for ($i=0; $i < 4; $i++) {
$color = imagecolorallocate($this->img,mt_rand(0,155),mt_rand(0,155),mt_rand(0,155));
imageline($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
}
}
public function createPiexs(){
for ($i=0; $i < 100; $i++) {
$color = imagecolorallocate($this->img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
imagesetpixel($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
}
}
public function show()
{
$this->createImage();
$this->createCode();
if ($this->lineFlag) {
$this->createLines();
}
if ($this->piexFlag) {
$this->createPiexs();
}
header('Content-type:image/png');
imagepng($this->img);
imagedestroy($this->img);
}
public function getCode(){
return $this->code;
}
}
以上就是验证码类的全部代码。看起来确实挺简单的,不过用的图像处理函数比较多,上面相关的函数我也做了必要的链接和用途说明。这些函数也不用死记硬背,遇到不清楚的,随时查阅 PHP 官方文档,最重要的是还有中文文档。
2.2 使用验证码
既然已经封装完毕,那就可以开始使用了。这里为了方便,直接在 Captcha 类的下方调用该类:
session_start(); //开启session
$captcha = new Captcha(); //实例化验证码类(可自定义参数)
$captcha->show(); //调用输出
三、前端展示
后端已经准备好了验证码,前端界面就可以展示了,修改 index.php 中的注册与登陆表单的验证码部分:
<div class="form-group">
<div class="col-sm-12">
<img src="admin/Captcha.php" alt="" id="codeimg" onclick="javascript:this.src = 'admin/Captcha.php?'+Math.random();">
<span>Click to Switch</span>
</div>
</div>
img 标签添加了点击事件的 js 代码,这样就可以实现点击更换验证码的功能!
效果图:
四、完善
缓冲(buffer)是为了协调吞吐速度相差很大的设备之间数据传送而采用的技术,用来存放缓冲数据的区域叫缓冲区,在计算机科学领域,当数据从一个地方传送到另一个地方时,缓冲区被用来临时存储数据。与缓冲相似的一个技术是缓存(cache),它们都是为了解决数据存储和传输速度不同而带来的问题,不同的是,缓冲主要在写时使用,而缓存主要用来在读时使用。
如上图,是一个简易的缓冲区模拟图,左端入口的数据具有单个输入体积小,速度快,数量多,但右端输出数据具有体积大,速度慢的特点。如果没有缓冲区,很容易造成数据堵塞,有了缓冲区之后,当数据填满缓冲区,再统一输出,则可以大大减少系统负担。
php在执行的过程中,嵌入的HTML代码,’echo’,’print_r’等指令都是一次数据输出,正是因为有缓冲区的存在,系统可以在php执行完之后再一次把数据发送给浏览器,运行如下代码:
<?php
echo "这里是第一行数据";
echo "这里是第二行数据,下面睡眠5秒";
sleep(5);
echo "这里是第三行数据,下面是HTML代码";
?>
<h1>标题</h1>
发现浏览器是同时显示所有内容,而不是先显示第一行和第二行数据,等待5秒后再显示后面的数据。不仅这样,PHP的缓冲区还提供给我们更加强大的功能,我们可以在数据发送之前对其作出捕获,更改等。PHP提供给我们”ob_”系列函数,例如如下代码,可以对某些字符进行替换:
<?php
ob_start();
echo "Hello world, this is http://www.111cn.net/";
$content = ob_get_contents();
ob_end_clean();
echo str_replace("http://","https://",$content);
?>
上面中的ob_start,ob_get_contents,ob_end_clean分别用来开启用户缓冲区,获取缓存内容和关闭缓存区,PHP中所有的输出控制函数有1:
flush — 刷新输出系统缓冲
ob_clean — 清空(擦掉)输出缓冲区
ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲
ob_flush — 冲刷出(送出)输出缓冲区中的内容
ob_get_clean — 得到当前缓冲区的内容并删除当前输出缓。
ob_get_contents — 返回输出缓冲区的内容
ob_get_flush — 刷出(送出)缓冲区内容,以字符串形式返回内容,并关闭输出缓冲区。
ob_get_length — 返回输出缓冲区内容的长度
ob_get_level — 返回输出缓冲机制的嵌套级别
ob_get_status — 得到所有输出缓冲区的状态
ob_gzhandler — 在ob_start中使用的用来压缩输出缓冲区中内容的回调函数。ob_start callback function to gzip output buffer
ob_implicit_flush — 打开/关闭绝对刷送
ob_list_handlers — 列出所有使用中的输出处理程序。
ob_start — 打开输出控制缓冲
output_add_rewrite_var — 添加URL重写器的值(Add URL rewriter values)
output_reset_rewrite_vars — 重设URL重写器的值(Reset URL rewriter values)
php中,可以通过php.ini的output_buffering来设置缓存,On表示无穷大,Off表示关闭,数字则表示缓冲区的大小(以字节为单位),默认大小是4KB,如果设置成off,则示例一的代码是不是就可以分段在浏览器显示了呢?答案是否定的,有两点需要注意,第一点即使把PHP的缓存关闭,php输出在系统层面也有缓存(可以理解为Linux系统stdout的缓存),必须通过flush函数输出;第二点是一些有些浏览器对一次接收的文字长度有限制,如果太少,则不予显示。所以这样的代码可以分段显示:
<?php
echo "这里是第一行数据";
echo str_repeat(" ",1024);
echo "这里是第二行数据,下面睡眠5秒";
flush();
sleep(5);
echo "这里是第三行数据,下面是HTML代码";
?>
<h1>标题</h1>
<h1>标题</h1>
当然在实际生产环境,直接把output_buffering关闭的情况比较少见,我们可以通过ob_系列函数来进行操作,下面的例子是利用缓冲进行服务器推送(comet)的示例。如下代码可以给客户端进行信息推送:
<?php
ob_start();
$i=0;
while($i<100){
echo $i.str_repeat(" ",2024);
$i++;
ob_flush();
flush();
sleep(5);
}
?>
PHP函数:empty() 和 isset() 都是判断变量是否已配置的函数,不过使用的时候还是存在一定的区别。
empty() 函数用来测试变量是否已经配置。若变量已存在、非空字符串或者非零,则返回 false 值;反之返回 true。
isset() 函数用来测试变量是否已经配置。若变量已存在则返回 true 值。其它情形返回 false 值。
从上面两个函数的定义可以看出 empty() 和 isset() 的共同点是:都可以判定一个变量是否为空,都返回boolean类型,即true或false。而它们最明显区别的地方就是:返回的布尔值刚好是相反。
另外,他们之间最大的区别就是对于0的判断,若用empty判断会认为是空,用isset则认为不为空,举个例子:
<?php
var $a=0;
//empty($a)返回true
if(empty($a)){
echo "判断结果是空"
}
//isset($a)返回true
if(isset($a)){
echo "判断结果不是空"
}
?>
empty() 判断一个变量是否为“空”,同时还会检测变量是否为空、为零。当一个变量值为0,empty() 认为这个变量同等于空,即相当于没有设置。而isset() 判断一个变量是否已经设置,就算变量值为空,为零也算已设置。
一、举例说明
A.如何判断一个变量是否定义?
<?php
// 假设不存在$test 变量
$isset = isset($test) ? "test is define!" : "test is undefine!";
echo "isset:$isset", '<br />';
$empty = !empty($test) ? "test is define!" : "test is undefine!";
echo "empty:$empty", '<br />';
$is_null = is_null($test) ? "test is define!" : "test is undefine!";
echo "is_null:$is_null";
测试结果是:
isset:test is undefine!
empty:test is undefine!
is_null:test is define!
结果表明: empty,isset首先都会检查变量是否存在,然后对变量值进行检测。而is_null 只是直接检查变量值,是否为null,因此如果变量未定义就会出现错误!
B、看下各自接收的参数是什么?
isset函数参数:
<?php
$test=100;
echo isset($test),isset(100),$isset($b=100);
输出:
<br />
<b>Parse error</b>: parse error, unexpected T_LNUMBER, expecting T_STRING or T_VARIABLE or '$' in <b>PHPDocument3</b> on line <b>3</b><br />
empty函数参数:
<?php
$test=100;
echo empty($test),empty(100),empty($b=100);
输出:
<br />
<b>Parse error</b>: parse error, unexpected T_LNUMBER, expecting T_STRING or T_VARIABLE or '$' in <b>PHPDocument3</b> on line <b>3</b><br />
is_null函数参数:
<?php
$test=100;
echo is_null($test),is_null(100),is_null($b=100);
运行结果:没有任何错误。
结果表明: empty,isset输入参数必须是一个变量(PHP变量是以$字符开头的),而is_null输入参数只要是能够有返回值就可以(常量,变量,表达式等)。在PHP手册里面,对于他们解析是:empty,isset 是一个语言结构而非函数,因此它无法被变量函数调用。
二、概括总结isset,empty,is_null区别:
empty()
如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义,以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
isset()
如果 变量 存在且值非NULL,则返回 TRUE,否则返回 FALSE(包括未定义)。变量值设置为:null,返回也是false;unset一个变量后,变量被取消了。注意,isset对于NULL值变量,特殊处理。
is_null()
检测传入值【值,变量,表达式】是否是null,只有一个变量定义了,且它的值是 null ,它才返回TRUE . 其它都返回 FALSE 【未定义变量传入后会出错!】。
1、isset()对PHP参数判断
您可以使用 PHP isset() 来判断一个参数是否被定义,注意如果该参数为空,或者"\n"(NULL字节)使用 PHP isset() 判断之后,都会为TRUE。
<?php
$var = ''; // 这里初始参数$var='';
$var0 = FALSE // 这里初始参数为布尔FALSE
$var2 = NULL; // 这里定义$var2=NULL,用isset()判断返回FALSE
$var3 = "\0"; // 这里是NULL字节,用isset()判断,返回TRUE,不同于NULL常数
$var4 = "www.qianyunlai.com"; // 这里定义会在下面给unset掉
if (isset($var)) {
echo '参数$var已经设定,且值不为NULL';
}
// 参数$var已经赋值,而且值为$var='',所以会输出“参数$var已经设定”
if (isset($var0)) {
echo '参数$var0已经设定,且值不为NULL';
}
// 参数$var0已经赋值,而且值为$var=FALSE,所以会输出“参数$var已经设定”
if (isset($vget)) {
echo '参数$vget已经设定,且值不为NULL';
}
// 参数$vget根本就没有被提及过,isset($vget)返回FALSE,不会输出
if (isset($var2)) {
echo '参数$var2已经设定,且值不为NULL';
}
// 这里是$var2虽然被设定了,但是$var2=NULL,所以isset($var2)返回FALSE,不会输出
if (isset($var3)) {
echo '参数$var3已经设定,且值不为NULL';
}
// 参数$var3 虽然\0 就是代表NULL字节,但是这个不是常数NULL,所以$isset("\0")返回TRUE,会输出
unset($var4); // 这里给$var4 释放掉了
if (isset($var4)) {
echo '参数$var4已经设定,且值不为NULL';
}
// 虽然开始已经定义$var4,而且还不为NULL,但是后来又给 unset() 掉了,所以不会输出。
?>
2、PHP isset() 对数组的判断
在使用PHP数组的时候,需要判断数组的某个值是否存在也可以使用 PHP isset() 函数。
<?php
$V => array(
'aa' => 'www.qianyunlai.com',
'bb' => array(
'file' => 'file.qianyunlai.com',
'img' => 'img.qianyunlai.com',
'hosts' => array(
'blog' => 'blog.qianyunlai.com',
'res' => 'res.qianyunlai.com'
)
)
);
// var_dump用于输出TRUE 或 FALSE
var_dump(isset($V['aa']));
// 数组$V 的$V['aa'] ='www.qianyunlai.com'已经存在,所以输出TRUE
var_dump(isset($V['bb']['file']));
//$V['bb']['file'] = 'file.qianyunlai.com' 所以输出 TRUE
var_dump(isset($V['bb']['hosts']['blog']));
// $V['bb']['hosts']['blog']='blog.qianyunlai.com'所以输出TRUE
var_dump(isset($V['bb']['hosts']['sh']));
//根据数组,根本就没有设定该项,所以输出FALSE
?>
3、PHP isset()对参数判断
很多时候我们需要对多个参数进行判断,可以使用isset($A)&&isset($B)……来判断这些参数是不是都已经设定了,而且都不为NULL,对此您可以使用isset()多参数来判断是不是都设定了。
<?php
isset($v1)&&isset($v2)&&isset($v3)……
// 等价于
isset($v1,$v2,$v3……)
?>
使用isset()判断多个参数,需要所有参数都被设定,且不为NULL,只要其中有一个参数没有被设定过,或者为NULL,那么整个isset()就为FALSE。
4、PHP isset()判断$_POST、$_GET、$_REQUEST等值
用isset() 或者empty() 判断通过表单传递来的参数是isset() 最常见的用法。
if (isset($_POST['from']) && 'qianyunlai.com' == $_POST['from']) {
echo '网站通过POST传递的来源是qianyunlai.com';
}
根据上面我们可以用isset判断多参数,在对表单传递来的值进行判断就最方便了。
<?php
// 表单传递来user用户名和 pass必须同时存在才能执行
if (isset($_POST['user'], $_POST['pass'])) {
$user=$_POST['user'];
$pass=$_POST['pass'];
echo '您填写的用户名是:',$user,';密码是:',$pass;
}
?>
5、PHP isset($var{字符串长度}) 判断字符串长度
用PHP判断字符串是否存在或者判断字符串长度是否超过某一数字或者判断字符串长度是否为空一般使用strlen(),但是其实使用isset()性能更优越。
<?php
// 三元,等同于 if (isset($_POST['from'])) { $var = $_POST['from'];} else {$weiget = '';}
$var = isset($_POST['from']) ? $_POST['from'] : '';
// 判断$var存在,且字符串长度大于0
/* 菜鸟写法
if (strlen($var) > 0) {
echo '$var子符长度大于0';
}
*/
// 性能更优越的写法,判断$var第1个字符是否设定了
if (isset($var{1})) {
echo '$var字符长度大于0';
}
?>
6、PHP isset() 与 PHP empty() 的区别
很多人都拿 PHP isset() 和 PHP empty()进行比较,不过得出的结论一般都是 PHP isset() 判断这个参数是否存在,且不为NULL,即使用 PHP isset() 判断空值、0、布尔值(TRUE/FALSE)都是TRUE,而且 PHP isset() 还可以对数组进行判断。
而 PHP empty(),若变量不存在,或者变量存在且其值为""、0、"0"、NULL、FALSE、array()、var $var; 以及没有任何属性的对象,则返回 TURE。
那么!empty(),就是变量存在,且值不为""、0、"0"、NULL、FALSE、array()以及var $var;
<?php
// $_POST['from'] 传递来的是一个网址,据此我们可以知道,这个值一定不为0和布尔,只能是字符串,或者空字符串,或者不存在
/* 下面写法比较常见,但是需要判断两次
if (isset($_POST['from']) && isset($_POST['from']{1})) {
echo '$weigeti子符长度大于0';
}
*/
// 下面用!empty() 只需要判断一次,更加高效
if (!empty($_POST['from'])) {
echo '传递的from存在且不为空、0等';
}
?>
虽然有时候用!empty()判断传递来的$_GET、$_POST 性能更优越,但是并不是能完全代替isset()使用,如果传递的值允许包含0、'0'或者空的时候,就不能使用!empty()判断了,否则即使传递过来了0、'0'都会被当作没有传递任何值过来。
而对于可以确定传递过来的值一定不为0、'0'、空的时候,如用户名、密码等,使用!empty() 性能更优越。
补充:PHP 判断常量,变量和函数是否存在
if (defined('CONST_NAME')) {
//do something
}
变量检测则是使用isset,注意变量未声明或声明时赋值为NULL,isset均返回FALSE,如:
if (isset($var_name)) {
//do something
}
函数检测用function_exists,注意待检测的函数名也需要使用引号,如:
if (function_exists('fun_name')) {
fun_name();
}
<?php
/* 判断常量是否存在*/
if (defined('MYCONSTANT')) {
echo MYCONSTANT;
}
//判断变量是否存在
if (isset($myvar)) {
echo "存在变量$myvar.";
}
//判断函数是否存在
if (function_exists('imap_open')) {
echo "存在函数imag_openn";
} else {
echo "函数imag_open不存在n";
}
?>
function_exists判断函数是否存在
<?php
if (function_exists('test_func')) {
echo "函数test_func存在";
} else {
echo "函数test_func不存在";
}
?>
filter_has_var函数
filter_has_var() 函数检查是否存在指定输入类型的变量。
若成功,则返回 true,否则返回 false。
<?php
if(!filter_has_var(INPUT_GET, "name"))
{
echo("Input type does not exist");
}
else
{
echo("Input type exists");
}
?>
输出为. Input type exists
其他变量处理函数:
gettype:取得变量的类型。
intval:变量转成整数类型。
doubleval:变量转成倍浮点数类型。
empty:判断变量是否已配置。
is_array:判断变量类型是否为数组类型。
is_double:判断变量类型是否为倍浮点数类型。
is_float:判断变量类型是否为浮点数类型。
is_int:判断变量类型是否为整数类型。
is_integer:判断变量类型是否为长整数类型。
is_long:判断变量类型是否为长整数类型。
is_object:判断变量类型是否为类类型。
is_real:判断变量类型是否为实数类型。
is_string:判断变量类型是否为字符串类型。
isset:判断变量是否已配置。
settype:配置变量类型。
strval:将变量转成字符串类型。
unset:删除变量。
一:四舍五入
1.round — 对浮点数进行四舍五入
float round ( float $val [, int $precision ] )
2:floor — 舍去法取整(向下取整)
float floor ( float $value )
3.ceil — 进一法取整(向上取整)
float ceil ( float $value )
坑点: 当数值为整数的时候 例如 11 那么floor(11) = 10 , ceil (11) = 12; 问题显而易见,所以计算的时候要格外注意这一点,解决方法 floor(11 + 0.01);
二:整数和小数相乘除
坑点:3.5 * 100 = 300 ,就算你数学再好也没用,在php世界里这就是真理。
解决方法就是将整型变成浮点型 3.5 * (float)100 = 350
三:浮点数的怪异
坑点:8.50 – 8 = 0.500000001 其实原因和2差不多, 解决方法:将结果进行round(),提高精度即可
相关文章
- php 获取用户IP与IE信息程序 function onlineip() { global $_SERVER; if(getenv('HTTP_CLIENT_IP')) { $onlineip = getenv('HTTP_CLIENT_IP');...2016-11-25
- 在很多网站用户先访问一个要登录的页面,但当时没有登录后来登录了,等待用户登录成功之后肯定希望返回到上次访问的页面,下面我就来给大家介绍登录后跳转回原来要访问的页...2016-11-25
- 本文章完美的利用了php的curl功能实现模拟登录discuz以及模拟发帖,本教程供参考学习哦。 代码如下 复制代码 <?php $discuz_url = ‘ht...2016-11-25
- php简单用户登陆程序代码 这些教程很对初学者来讲是很有用的哦,这款就下面这一点点代码了哦。 <center> <p> </p> <p> </p> <form name="form1...2016-11-25
Ruby on Rails实现最基本的用户注册和登录功能的教程
这里我们主要以has_secure_password的用户密码验证功能为中心,来讲解Ruby on Rails实现最基本的用户注册和登录功能的教程,需要的朋友可以参考下...2020-06-30- 当来访者浏览器语言是中文就进入中文版面,国外的用户默认浏览器不是中文的就跳转英文页面。 <?php $lan = substr( $HTTP_ACCEPT_LANGUAGE,0,5); if ($lan == "zh-cn") print("<meta http-equiv='refresh' c...2015-11-08
- 一个用Javascript检测用户输入密码强度的效果代码,以下代码主要是从以下四个方面检测用户输入的密码的强度的,有兴趣的朋友可以自己添加或修改成自己想要的形式! 1. 如果输入的密码位数少于5位,那么就判定为弱。 2. 如果...2015-10-23
- 什么是SSO?单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护...2015-11-08
- 【问题描述】:同一用户在同一时间多次登录如果不能检测出来,是危险的。因为,你无法知道是否有其他用户在登录你的账户。如何禁止同一用户多次登录呢? 【解决方案】 (1) 每次登录,身份认证成功后,重新产生一个session_id。 s...2015-11-24
- 什么是SSO?单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护...2015-11-08
- 这篇文章主要为大家详细介绍了vue实现用户登录切换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-04-22
- 这是注册程序是一款当用户输入完用户名是,就会自动去数据库中查询用户要注册的用户名是否己经被注册了,如果是返回提示否则提示可以注册。 conn.php文件 代...2016-11-25
- 出现phpmyadmin不能登录是我在修改我mysql服务器密码之后导致的,后来百度了相关的原因,原来是修改了mysql密码之后我们还需要在phpmyadmin目录中去修改config.inc.php中...2016-11-25
Vue-Element-Admin集成自己的接口实现登录跳转
关于这个Vue-element-admin中的流程可能对于新的同学不是很友好,所以本文将结合实例代码,介绍Vue-Element-Admin集成自己的接口实现登录跳转,感兴趣的小伙伴们可以参考一下...2021-06-23- 这篇文章主要介绍了C#实现图片放大功能的按照像素放大图像方法,功能非常实用,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了浅谈js二维码扫码登录是什么原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-13
- 在本篇文章中小编给各位整理了一篇关于python中翻译功能translate模块实现方法,有需要的朋友们可以参考下。...2020-12-18
- 这篇文章主要给大家介绍了关于微信小程序用户授权最佳实践的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-08
- 昨天有一朋友说自己的phpmyadmin不能登录并且无任何提示了,问我怎么解决,下面我来分享一下关于phpmyadmin不能登录问题总结. phpmyadmin不能登录没有提示 解决方法:...2016-11-25
- EMUI11值得升级吗?好不好用?下面小编带来EMUI11上手体验,一起来看看手机鸿蒙OS的提前预演...2020-12-08