深入分析PHP 删除cookie教程

 更新时间:2016年11月25日 15:36  点击:1782
cookie是一个存储在用户本地的一个小的文本文件了我们可以通过浏览器来访问它,下面我们来看看关于PHP 删除cookie的一些事项。


要删除 cookie 需要确保它的失效期是在过去,才能触发浏览器的删除机制

在php中,我们可以使用setcookie()函数来设置浏览器的Cookie信息。

常见的设置cookie的示例代码如下:

<?php

$name = 'mycookie'; // cookie名称
$value = 'CodePlayer'; // cookie值
$expire = time() + 3600 * 24 * 7; // 过期时间 7天
$path = '/'; // 设置可以使用该cookie的路径,'/'表示站点根目录,该目录及所有子目录中均可访问该cookie。

// 设置一个cookie
setcookie( $name, $value, $expire, $path );

?>

不过,我们想要删除Cookie信息的话,又该怎么办呢。php并没有提供另外一个专门用来删除Cookie的函数,而是直接使用setcookie()函数来删除Cookie信息,我们只需要将过期时间更改为当前时间之间的时间即可。

<?php
// 设置cookie已过期,浏览器即可删除该cookie。此时可以为任意值。
setcookie( 'mycookie', 'CodePlayer', time() - 3600, '/' );

// 或者

// 将过期时间直接设为0,表示1970-1-1(已经过期了),可以避免time()及数学运算的消耗
setcookie( 'mycookie', 'CodePlayer', 0, '/' );
?>

此外,我们还可以将Cookie的值设为空字符串(“”)或null,也可用来删除Cookie。

<?php
/* 删除cookie */

setcookie('mycookie', '');
// 或者
setcookie('mycookie', null);
?>

这样就完了吗?No!如果你直接如上使用空字符串或null的方式来删除Cookie,可能会导致对应的cookie无法删除。

当然,上述删除Cookie的方式是没有错的,错的是我们没有在删除Cookie时指定路径(第4个参数)。如果没有指定路径参数,则路径默认为当前请求URL所在目录。如果你设置Cookie时的路径与删除Cookie时的路径不一致,将无法删除该Cookie。

<?php
// 当前请求为:"/abc/cookie.php"

// 在路径"/"下设置cookie
setcookie( 'mycookie', 'CodePlayer', time() + 3600 * 24 * 7, '/' );

// 注意:这样删除是无效的,因为默认路径为当前目录,即:"/abc/"
// setcookie( 'mycookie', '');

// 删除路径"/"下设置的名为"mycookie"的cookie,此时时间值可随意,哪怕未过期也行
setcookie( 'mycookie', '', 0, '/');
?>

以下代码可以在php5.20的linux源码包中ext/standard/head.c第99行附近找到.

if (value && value_len == 0) {
/*
    * MSIE doesn't delete a cookie when you set it to a null value
    * so in order to force cookies to be deleted, even on MSIE, we
    * pick an expiry date 1 year and 1 second in the past
    */
time_t t = time(NULL) - 31536001;
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
efree(dt);
} else {
sprintf(cookie, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
if (expires > 0) {
strcat(cookie, "; expires=");
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
strcat(cookie, dt);
efree(dt);
}
}

源码中清清楚楚的显示,if (value && value_len == 0) ,当value_len为0

sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);

会发送删除cookie的http头给浏览器.

最后我们可以得出结论,在php中使用

setcookie($cookiename, '');或者 setcookie($cookiename, NULL);

都会删除cookie,当然这些手册中并没有。

下文来为各位介绍Php处理浮点数的问题了,如果各位在使用过程中碰到这些问题我们可以一起来看看,希望文章对各位有帮助

公司要对产品价格做调整,因为做的外贸商城,所以价格要和国际接轨。比如国外的价格展示方式是:$35标识为$35.00; $56.2标识为:$56.20.

通过sprintf(“%1\$.2f”,$price)解决了上面的需求,但是新的问题出现,有价格为0的会处理为0.00.

通过empty()和判断是否相等,无法识别符点数0.00;通过百度总结了下面处理浮点数的方法。

浮点数0.00的处理

通过intval转换为整形intval(0.00) 变为0,只针对0.00使用intval处理;可以看先的例子你就明白了。

例子1:

$n=”19.99″;

print intval($n*100); //输出的结构是1998,而不是1999;

print intval(strval($n*100));//这个输出的才是1999;

例子二:

echo floor((0.1+0.7)*10);//输出的是7,而不是8;

echo floor(strval((0.1+0.7)*10));//这个才是8;

在php中一些简单的浮点数据在内部不能以精确的二进制来表示的。这和计算机的数据表示相关,即:不可能以有限的二进制来表示某些十进制的分数。永远不要相信浮点数的结果精确到了最后一位, 也永远不要比较两个浮点数是否相等。

上面的2个例子,总结出php处理浮点数的方式是将其转成字符串, 可以通过strval或者使用printf/sprintf将浮点数转成字符串.

浮点数精度

显然简单的十进制分数如同 0.1 或 0.7 不能在不丢失一点点精度的情况下转换为内部二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7.9999999999...。

这和一个事实有关,那就是不可能精确的用有限位数表达某些十进制分数。例如,十进制的 1/3 变成了 0.3333333. . .。

面试题对于我们要去找工作的朋友多少都会要看一下的,这里一聚教程小伙伴为各位整理PHP类型转换的面试题与答案解析,希望本文章能够对各位有帮助。


最近在为公司面试新人,经常会问到的一道题目就是PHP类型转换的值,例如:
 
var_dump((int)true);
var_dump((string)true);
var_dump((string)false);
var_dump((bool)"1");
var_dump((bool)"0");
var_dump((bool)"");
var_dump((bool)"false");

我印象中最早见到这道题目是在英极的PHP高级开发工程师岗位的笔试题里面,看似很基础,但是依然可以难住不少PHPer。先来看一下运行结果:

int(1)
string(1) "1"
string(0) ""
bool(true)
bool(false)
bool(false)
bool(true)

对于大多数人来说,第1、2、4行通常是没有问题的。但是为什么false转换为字符串是空字符串呢?在处理请求值时,通常会传一个字符串类型的false,但是“false”(字符串)并非false(布尔),这有点令人疑惑了。

为什么会这样呢?

关于这个问题,我们从PHP内核入手,看看在类型转换时系统内部到底发生了什么。

首先补充一些关于PHP弱类型实现方式的背景知识。PHP解释器是使用C语言写成的,当然最终对变量的处理,也会使用C语言构造数据结构来实现。在Zend引擎中,一个PHP变量对应的类型是zval。

打开Zend/zend_types.h文件,我们可以看到zval类型的定义,php-5.5.23版本大约在第55行左右:

typedef struct _zval_struct zval;


这样我们发现,zval其实是一个名为_zval_struct的结构体类型,我们在Zend/zend.h文件中找到这个结构体的定义,大约在320行左右开始:


 
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
 
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};

大家可以看到,_zval_struct中包含两个重要的成员,一个是zvalue_value类型的value,一个是zend_uchar类型的type。注意zvalue_value类型是一个联合体,它用来存储一个PHP变量的值的信息。(如果你忘记了什么是联合体,我来解释一下。联合体类似结构体,但是联合体的中的成员,存储时有且只能有一个,而且联合体占用的空间是联合体中长度最长的那个成员,这样做是为了节省内存的使用。)在zvalue_value中,包括了long、double、struct、HashTable、zend_object_value五个类型的成员。他们分别用来存储PHP变量不同类型的值:
C类型  PHP类型
long  bool
int
resource
double  float
struct  string
HashTable  array
zend_object_value  object

看到这个结构体之后,想必也就明白了常问的诸如PHP中int类型的取值范围,以及php中strlen的时间复杂度之类的问题。

由此可见,PHP的变量类型转换,或者说是弱类型实现,本质上是实现zval类型在不同类型之间的转换。除了完成zvalue_value的数值转换,还需要将_zval_struct中的type设置成当前变量的type类型。在Zend引擎中实现了convert_to_*系列函数完成这一转换,我们在Zend/zend_operators.c中可以看到这些转换函数,在大约511行左右,可以找到转换为布尔类型的函数:


 
ZEND_API void convert_to_boolean(zval *op) /* {{{ */
{
int tmp;
 
switch (Z_TYPE_P(op)) {
case IS_BOOL:
break;
case IS_NULL:
Z_LVAL_P(op) = 0;
break;
case IS_RESOURCE: {
TSRMLS_FETCH();
 
zend_list_delete(Z_LVAL_P(op));
}
/* break missing intentionally */
case IS_LONG:
Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0);
break;
case IS_DOUBLE:
Z_LVAL_P(op) = (Z_DVAL_P(op) ? 1 : 0);
break;
case IS_STRING:
{
char *strval = Z_STRVAL_P(op);
 
if (Z_STRLEN_P(op) == 0
|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
Z_LVAL_P(op) = 0;
} else {
Z_LVAL_P(op) = 1;
}
STR_FREE(strval);
}
break;
case IS_ARRAY:
tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
zval_dtor(op);
Z_LVAL_P(op) = tmp;
break;
case IS_OBJECT:
{
zend_bool retval = 1;
TSRMLS_FETCH();
 
convert_object_to_type(op, IS_BOOL, convert_to_boolean);
 
if (Z_TYPE_P(op) == IS_BOOL) {
return;
}
 
zval_dtor(op);
ZVAL_BOOL(op, retval);
break;
}
default:
zval_dtor(op);
Z_LVAL_P(op) = 0;
break;
}
Z_TYPE_P(op) = IS_BOOL;
}
/* }}} */

case IS_STRING这段代码即是将一个字符串类型变量转换为布尔型的操作。可以看到,只有空字符串,或者字符串长度为1,并且此字符为0时,字符串的布尔值才为1,也就是true,其他为0,也就是false。

同样的,我们也就明白了布尔值如何转换为字符串的,可以从_convert_to_string函数的实现中了解。

看似简单并且基础的PHP问题,究其根源是对PHP实现机制的把握。个人觉得,这道题也不失为鉴别PHPer知识边界的一道好题目。

本文我们来分享一段可以同时ping多个ip然后对比找出网络最快的ip的php程序,这段程序用来找代理ip可是神器。


为了翻墙方便 ,买了个vpn,转到osx下面官方没有提供合适的客户端,无法选择最快的线路。于是就自己写了个脚本,手动ping出最快的IP.

 代码如下 复制代码
$servers = array(
    array('VIP荷兰线路01','nl01.yyuu.me','81.4.105.195','4122或3108'),
    array('VIP法国线路01','fr01.yyuu.me','176.31.206.242','4122或3108'),
    array('VIP意大利线路01','it01.yyuu.me','37.247.48.226','4122或3108'),
    array('VIP新加坡线路01','sg01.yyuu.me','128.199.69.209','4122或3108')
);


//配合pcntl_signal使用
declare(ticks=1);
//最大的子进程数量
$max = count($servers);
//当前的子进程数量
$child = 0;

//当子进程退出时,会触发该函数
function sig_handler($sig) {
    switch($sig) {
        case SIGCHLD:
            //do something
    }
}

//注册子进程退出时调用的函数
pcntl_signal(SIGCHLD, "sig_handler");
foreach($servers as $server){
    $pid = pcntl_fork();
    if($pid){
        //echo 'main thread start',PHP_EOL;
    }else{
        exec('ping -c 1 '.$server[2],$result);
        echo $server[1].' '.$server[2].' '.$result[1],PHP_EOL;
        exit();
    }
}
如果要做到安全密码与用户名都随机我有一个朋友做服务器的登录密码与用户名就是使用了phpmyadmin随机生成密码功能来做的,与其用phpmyadmin不如自己做了,下文整理了一些关于php随机密码生成的自定义函数供大家参考。

可以指定生成的字符串长度

function rand_str($length, $max=FALSE)
{
  if (is_int($max) && $max > $length)
  {
    $length = mt_rand($length, $max);
  }
  $output = '';
  
  for ($i=0; $i<$length; $i++)
  {
    $which = mt_rand(0,2);
    
    if ($which === 0)
    {
      $output .= mt_rand(0,9);
    }
    elseif ($which === 1)
    {
      $output .= chr(mt_rand(65,90));
    }
    else
    {
      $output .= chr(mt_rand(97,122));
    }
  }
  return $output;
}
调用实例:
$randstr = rand_str(16);

生成随机字符串的函数

<?php
/**
* 产生随机字符串
*
* 产生一个指定长度的随机字符串,并返回给用户
*
* @access public
* @param int $len 产生字符串的位数
* @return string
*/
function randStr($len=6) {
$chars='ABDEFGHJKLMNPQRSTVWXYabdefghijkmnpqrstvwxy23456789#%*'; // characters to build the password from
mt_srand((double)microtime()*1000000*getmypid()); // seed the random number generater (must be done)
$password='';
while(strlen($password)<$len)
$password.=substr($chars,(mt_rand()%strlen($chars)),1);
return $password;
}
?>


创建字符池。


function randomkeys($length)
   {
       $pattern = '1234567890abcdefghijklmnopqrstuvwxyz
                   ABCDEFGHIJKLOMNOPQRSTUVWXYZ,./&amp;l
                  t;&gt;?;#:@~[]{}-_=+)(*&amp;^%$?!';    //字符池
      for($i=0; $i<$length; $i++)
       {
           $key .= $pattern{mt_rand(0,35)};    //生成php随机数
       }
       return $key;
   }
   echo randomkeys(8);


无需创建字符池
 
function randomkeys($length)
   {
        $output='';
        for ($a = 0; $a < $length; $a++) {
            $output .= chr(mt_rand(35, 126));    //生成php随机数
        }
        return $output;
    }
    echo randomkeys(8);


随机用户名和随机密码例子

//随机生成用户名(长度6-13)
 

function create_password($pw_length = 4){
    $randpwd = '';
    for ($i = 0; $i < $pw_length; $i++){
        $randpwd .= chr(mt_rand(33, 126));
    }
    return $randpwd;
}
 

function generate_username( $length = 6 ) {
    // 密码字符集,可任意添加你需要的字符
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|';
    $password = '';
    for ( $i = 0; $i < $length; $i++ )
    {
        // 这里提供两种字符获取方式
        // 第一种是使用substr 截取$chars中的任意一位字符;
        // 第二种是取字符数组$chars 的任意元素
        // $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        $password .= $chars[ mt_rand(0, strlen($chars) - 1) ];
    }
    return $password;
}

//调用
$userId = 'user'.generate_username(6);
$pwd = create_password(9);

mt_srand生成随机种子,密码的长度可以随意定义,最长32位。

<?php
mt_srand((double) microtime() * 1000000);
 
function gen_random_password($password_length = 32, $generated_password = ""){
 $valid_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 $chars_length = strlen($valid_characters) - 1;
 for($i = $password_length; $i--; ) {
  //$generated_password .= $valid_characters[mt_rand(0, $chars_length)];
 
  $generated_password .= substr($valid_characters, (mt_rand()%(strlen($valid_characters))), 1);
 }
 return $generated_password;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>php密码生成器</title>
<style type="text/css">
body {
 font-family: Arial;
 font-size: 10pt;
}
</style>
</head>
<body>
<span style="font-weight: bold; font-size: 15pt;">密码生成器</span><br /><br />
<?php
 
if (isset($_GET['password_length'])){
 if(preg_match("/([0-9]{1,8})/", $_GET['password_length'])){
  print("密码生成成功:<br />
<span style="font-weight: bold">" . gen_random_password($_GET['password_length']) . "</span><br /><br />n");
 } else {
  print("密码长度不正确!<br /><br />n");
 }
}
 
print <<< end
请为密码生成其指定生成密码的长度:<br /><br />
<form action="{$_SERVER['PHP_SELF']}" method="get">
 <input type="text" name="password_length">
 <input type="submit" value="生成">
</form>
end;
?>
</body>
</html>

[!--infotagslink--]

相关文章

  • phpems SQL注入(cookies)分析研究

    PHPEMS(PHP Exam Management System)在线模拟考试系统基于PHP+Mysql开发,主要用于搭建模拟考试平台,支持多种题型和展现方式,是国内首款支持题冒题和自动评分与教师评分相...2016-11-25
  • php读取zip文件(删除文件,提取文件,增加文件)实例

    下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
  • 删除条目时弹出的确认对话框

    复制代码 代码如下: <td> <a href="/member/life/edit_ppt/<?php echo $v->id;?>" class="btn">编辑</a> <a href="javascript:;" onclick="if(confirm('您确定删除这条记录?')){location.href='/member/life/d...2014-06-07
  • JS使用cookie实现DIV提示框只显示一次的方法

    本文实例讲述了JS使用cookie实现DIV提示框只显示一次的方法。分享给大家供大家参考,具体如下:这里运用JavaScript的cookie技术,控制网页上的提示DIV只显示一次,也就是当用户是第一次打开网页的时候才显示,第二次自动隐藏起...2015-11-08
  • php跨网站请求伪造与防止伪造方法

    伪造跨站请求介绍伪造跨站请求比较难以防范,而且危害巨大,攻击者可以通过这种方式恶作剧,发spam信息,删除数据等等。...2013-10-01
  • PHP中SSO Cookie登录分析和实现

    什么是SSO?单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护...2015-11-08
  • Centos中彻底删除Mysql(rpm、yum安装的情况)

    我用的centos6,mysql让我整出了各种问题,我想重装一个全新的mysql,yum remove mysql-server mysql之后再install并不能得到一个干净的mysql,原来的/etc/my.cnf依然没变,datadir里面的数据已没有任何变化,手动删除/etc/my.cn...2015-03-15
  • MyBatis-Plus的物理删除和逻辑删除(使用场景)

    数据库中的数据删除会分为两种:物理删除 和 逻辑删除,接下来通过本文给大家介绍MyBatis-Plus的物理删除和逻辑删除使用场景分析,感兴趣的朋友一起看看吧...2021-09-25
  • PHP中SSO Cookie登录分析和实现

    什么是SSO?单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护...2015-11-08
  • vue项目中js-cookie的使用存储token操作

    这篇文章主要介绍了vue项目中js-cookie的使用存储token操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-14
  • mybatis-plus getOne和逻辑删除问题详解

    这篇文章主要介绍了mybatis-plus getOne和逻辑删除,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-26
  • C# 复制与删除文件的实现方法

    这篇文章主要介绍了C# 复制与删除文件的实现方法的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下...2020-06-25
  • C#删除UL LI中指定标签里文字的方法

    这篇文章主要介绍了C#删除UL LI中指定标签里文字的方法,涉及C#针对页面HTML元素进行正则匹配与替换的相关操作技巧,需要的朋友可以参考下...2020-06-25
  • 什么是cookie?js手动创建和存储cookie

    什么是cookie? cookie 是存储于访问者的计算机中的变量。每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。你可以使用 JavaScript 来创建和取回 cookie 的值。 有关cookie的例子: 名字 cookie 当访...2014-05-31
  • MybatisPlus实现逻辑删除功能

    这篇文章主要介绍了MybatisPlus实现逻辑删除功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-25
  • js实现上传文件添加和删除文件选择框

    这篇文章主要为大家详细介绍了js实现上传文件添加和删除文件选择框 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-10-25
  • C++递归删除一个目录实例

    这篇文章主要介绍了C++递归删除一个目录的实现方法,涉及到目录的操作及递归算法的应用,需要的朋友可以参考下...2020-04-25
  • jQuery中DOM节点的删除方法总结(超全面)

    这篇文章主要介绍了jQuery中DOM节点的删除方法,文中介绍的很相信,内容包括empty()的基本用法、remove()的有参用法和无参用法、empty和remove区别、保留数据的删除操作detach()以及detach()和remove()区别,需要的朋友可以参考借鉴。...2017-01-26
  • python爬虫用request库处理cookie的实例讲解

    在本篇内容里小编给大家整理的是一篇关于python爬虫用request库处理cookie的实例讲解内容,有需要的朋友们可以学习参考下。...2021-02-21
  • MySQL查看、创建和删除索引的方法

    本文实例讲述了MySQL查看、创建和删除索引的方法。分享给大家供大家参考。具体如下:1.索引作用在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定位技术,能够大大提高查询效率。特别是当数据量非常大,查询...2015-10-21