4-1 cookie 简介
Cookie 是存储在客户端浏览器中的数据,我们通过Cookie来跟踪与存储用户数据。一般情况下,Cookie通过HTTP headers 从服务端返回到客户端。多数 web 程序都支持 Cookie 的操作,因为 Cookie 是存在于 HTTP 的标头之中,所以必须在其它信息输出以前进行设置,类似于 header 函数的使用限制。
PHP 通过 setcookie 函数进行 Cookie 的设置,任何从浏览器发回的 Cookie, PHP 都会自动的将他存储在 $_COOKIE 的全局变量之中,因此我们可以通过 $_COOKIE[‘key’] 的形式来读取某个 Cookie 的值。
PHP 中的 Cookie 具有非常广泛的使用,经常用来存储用户的登录信息,购物车等,且在使用会话 Session 时通常使用 Cookie 来存储会话 id 来识别用户, Cookie 具备有效期,当有效期结束之后, Cookie 会自动从客户端删除。同时为了进行安全控制, Cookie 还可以设置域跟路径。
setcookie('test',time());
ob_start();
print_r($_COOKIE);
$content = ob_get_contents();
$content = str_replace(" ", ' ', $content);
ob_clean();
header("content-type:text/html; charset=utf-8");
echo "当前的 Cookie 为:<br>";
echo nl2br($content);
4-2 设置 cookie
PHP 设置 cookie 最常用的是 setcookie 函数,它有 7 个可选参数,常用的是前 5 个。
expire(过期时间) 为 0 表示浏览器关闭就失效。
path(有效路径) 如果路径设置了 ‘/‘ ,则整个网站有效
domain(有效域) 默认整个域名有效,如果设置了’www.imooc.com’,则只在www子域中有效
$value = 'test';
setcookie('TestCookie',$value);
setcookie('TestCookie',$value, time()+3600); // 设置 cookie 一小时后过期
setcookie('TestCooike',$value, time()+3600, '/path/', 'imooc.com' ); // 设置路径和域
PHP 还有一个设置 cookie 的函数—- setrawcookie , setrawcookie 和 setcookie 基本一样,唯一不同的是,value 值不会自动进行 urlencode ,因此在需要的时候要手动进行 urlencode
setrawcookie('CookieName', rawurlencode($value), time()+60*60*24*365);
因为 Cookie 是通过 HTTP 标头进行设置的,所以也可以直接通过 header 方法进行设置
header("Set-Cookie:cookieName=value");
4-3 cookie 的删除与过期时间
在 PHP 中删除 cookie 也是使用 setcookie 实现的
setcookie('TestCookie', '', time()-1);
cookie 的过期时间设置为当前时间之前 ,那么cookie 就自动失效。之所以这样设计,是因为 cookie 是通过 http 标头来传递的。客户端根据服务端返回的 Set-Cookie 段来进行 cookie 的设置,如果删除 cookie 需要使用新的 Del-Cookie 来实现,那么 HTTP 头就会变得更复杂,实际上通过 Set-Cookie 就可以简单明了地实现 cookie 的设置、更新和删除。
我们也可以直接使用 header 函数来删除 cookie
header("Set-Cookie:test=18635664139;expires=".gmdate('D, d M Y H:i:s \G\M\T', time()-1) );
这里用了 gmdate 用来生成格林威治标准时间,以便排除时差的影响。
4-4 cookie 的有效路径
cookie 中的路径用来控制设置的 cookie 在哪个路径下有效,默认为 ‘/‘,为在所有路径下都有效,在设定路径之后,就只在设定的路径及子路径下有效。例如
setcookie("test", time(), 0, '/path' );
一般情况下,大多是使用 ‘/‘ 的,少部分情况下会指定路径,这种情况下,只有在指定路径中才传递 cookie 值,可以节省数据的传输,增强安全性以及提高性能。
4-5 session 和 cookie 的异同
cookie 将数据存储在客户端,建立起用户和服务器的联系,通常可以解决很多问题。但是 cookie 仍然具有一些局限:
cookie 不是太安全,容易被盗用导致 cookie 欺骗。
单个 cookie 只能存储 4k
每次请求都要进行网络传输,占用带宽。
session 是将用户的会话数据存在服务端,没有大小限制,通过一个 session_id 进行用户识别, PHP 默认情况下, session_id 是通过 cookie 来保存的,因此从某种程度上来说, session 依赖于 cookie 。但这不是绝对的, session id 也可以通过参数来实现,只要能将 session id 传递到服务器进行识别的机制都可以使用 session。
4-6 使用 session
在 PHP 中使用 session 很简单, 先执行 session_start 方法开启 session ,然后通过全局变量 $_SESSION 进行 session 的读写。
session_start();
$_SESSION['test'] = time();
var_dump($_SESSION);
session 会自动地对设置的值进行 encode 和 decode, 因此 session 支持任意数据类型, 包括数组和对象
session_start();
$_SESSION['ary'] = array('name' => 'cheche');
$_SESSION['obj'] = new stdClass();
默认情况下, session 是以文件形式存储在服务器上的,因此,当一个页面开启了 session 之后,会独占这个 session 文件, 这样会导致当前用户的其它并发访问无法执行而等待,可以采用缓存或者数据库的形式来解决这个问题。。。。。
4-7 删除与销毁 session
删除某个 session 值,可以使用 unset() 函数。
session_start();
$_SESSION['name'] = 'jobs';
unset($_SESSION['name']);
如果要删除所有 session , 可以使用 session_destroy() , session_destroy() 会删除所有 sesssion, 但是 session_id 仍然存在。
session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
session_destroy();
值得注意的是 session_destroy() 并不会立即销毁全局变量 $_SESSION 中的值,只有当下次再访问的时候, $_SESSION 才会为空。因此,如果想要立即销毁 session , 可以使用 unset( ) 函数。
session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
unset($_SESSION);
session_destroy();
var_dump($_SESSION); // 此时已经为空
如果需要销毁 cookie 中的 session_id, 通常在用户退出的时候可能会用到, 则还需要显示地调用 setcookie 方法 删除 session_id 的 cookie 值。
4-8 使用 session 来存储用户的登录信息
session_start();
$userinfo = array(
'uid' => 1,
'name' => 'CheXuejian',
'email' => 'CheXuejian@imooc.com',
'gendar' => 'man',
'age' => 24
);
header(“content-type:text/html;charset=utf-8");
// 将用户保存到 session 中
$_SESSION['uid'] = $userinfo['uid'];
$_SESSION['name'] = $userinfo['name'];
$_SESSSION['userinfo'] = $userinfo;
// 将用户数据保存到 cookie 中
$secureKey = "immoc";
$str = serialize($userinfo); // 将用户信息序列化
// 将用户信息加密
$str = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), $str, MCRYPT_MODE_ECB));
setcookie('userinfo', $str);
// 当需要时进行解密
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), base64_decode($str),MCRYPT_MODE_ECB);
$uinfo = unserialize($str);
echo '揭秘后的用户信息:<br>';
print($uinfo);