Cookie
As cookies, the online world is full of them. Without cookie
, it is estimated that most website authentication functions will be invalid. This shows the importance of cookie
. What I bring to you today are some little things about php
and cookie
. - The experimental object in this article is pure
php
, without any frameworkphp
. Therefore, all writing methods are native, please know. cookie
Before output, please make sure that no page is output. Even a single whitespace character won't work. Uncle Sunan remembered the classic pitfall forphp
novices: When thephp
file is saved asutf8
, it must benobom
.
Related recommendations: "php cookie (topic)"
Option 1: setcookie
Function
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
The function description is here: https://doc.php.sh/zh/function.setcookie.html.
$name
Needless to say, the cookie project name is usually a string similar to "str", but it can also be in the form of an array, such as "arr[one ]".$value
will be escaped during the transmission process, for example, spaces will become plus signs, etc. The escape function, according to Uncle Sunan's inference, should be urlencode.$expire
Timestamp, seconds instead of milliseconds, cookie expiration time, is a specific time point, not a time period, PHP will further convert it to GMT Format. . Generally, this time is controlled to a past time to delete cookies. If left blank or filled with 0, it will take effect during the browser session and will become invalid when the browser is closed. When indicating the expiration time, there are two in the http protocol, expire and max-age. Currently, the expire expiration time is still set in PHP, but from the perspective of the http protocol, expire has begun to be replaced by max-age. Expire refers to the time point of expiration, and max-age is the number of seconds after which it will expire.$path
The effective directory of cookie is generally configured with $domain, and is generally set to/
.$domain
This parameter needs special attention. If not filled in, it will default to the current domain name. If you fill it in, generally speaking, you need to use$_SERVER['SERVER_NAME']
to obtain the domain name yourself. And if you fill it out actively, the final cookie scope will be all the subdomains filled in. If you fill in "newsn.net", then when reflected to the browser, the final value is ".newsn.net". Note that adding a "." in front of it expands the range of expression.$secure
Another very weird parameter indicates whetheris only passed to the client
through a secure HTTPS connection. If set to true, if the current website environment is not https, then the entire cookie will be completely invalid. However, we can find through packet capture that this cookie has been set by PHP, but has been invalidated on the browser side. In php, you can useisset($_SERVER["HTTPS"])
to determine whether https is supported.$httponly
The position of this parameter is also very awkward, it is the last one of all optional parameters. To set it, you must first set$domain
and$secure
, which seem to be unnecessary settings. In the current network environment, $httponly should be a strongly recommended setting value. For details, please refer to Uncle Sunan’s follow-up httponly article: https://newsn.net/tag/httponly/.
So, it is very likely that the php
statement you need is like this:
setcookie("cookie_name", "cookie_value", time() + 3600, "/", $_SERVER['SERVER_NAME'], isset($_SERVER["HTTPS"]), true);
Option 2: setrawcookie
Function
bool setrawcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool$ httponly = false ]]]]]] )
setrawcookie
和setcookie
,基本一致,区别就在于对$value的处理。下面的两条语句是一致的效果:
setcookie($name,$value);setrawcookie($name,urlencode($value));
特别说明:
urlencode
和rawurlencode
是有区别的,两者的区别不在本篇文章中叙述。需要明确的就是,两者是有区别的。- 当
setrawcookie
的$value
,不进行encode
操作的话,如果里面含有空格的话,整条语句都是失效的。并且不会报错!所以,setrawcookie
必须联合urlencode
才能保证其正确性。但是这个时候,就不如使用setcookie
了。
方案三:header
输出cookie
set cookie
函数,如果想要生效,也是通过header
设置浏览器端进而生效的。所以通过header
输出也是可行的。那么关于写出几条等价的header
操作,大家对比学习一下:
header("Set-Cookie:cookie_name1_cp=" . urlencode("浏览器关闭失效"));setcookie("cookie_name1", "浏览器关闭失效");
header("Set-Cookie:cookie_name=" . urlencode("设置有效域名/https/httponly") . "; expires=" . gmstrftime("%a, %d-%b-%Y %H:%M:%S GMT", time() + 3600*24) . "; Max-Age=3600; path=/; domain= ".$_SERVER['SERVER_NAME']."; httponly");setcookie("cookie_name3", "设置有效域名/https/httponly", time() + 3600*24, "/", $_SERVER['SERVER_NAME'], isset($_SERVER["HTTPS"]),true);
需要注意的是:
- 设置内容的时候,会对特殊字符进行转义。
setcookie
的转义是自动的,header
的转义是主动的。 - 使用
header
的时候,过期时间是个gmt
时间字符串,而setcookie
是个时间戳。 - 设置域名的时候,两者都直接写的域名,但是生效的时候,生效的是.域名,就是说生效范围包括二级域名。
header
比setcookie
好的地方在于:它可以跳过哪些过期时间/域名/path等参数,直接设置httponly
。
最后对比
下面来个php
的cookie
相关函数的终极对决:
<?php $val="我是中文 newsn.net";setcookie("cookie_normal",$val);setrawcookie("cookie_raw",urlencode($val));setrawcookie("cookie_raw2",rawurlencode($val));header("Set-Cookie:cookie_header=带 空 + 格 的中文",false);?><script src="js/jquery-3.2.1.min.js"></script><script src="js/jquery.cookie.js"></script><script> var cookie_normal=$.cookie('cookie_normal'); var cookie_raw=$.cookie('cookie_raw'); var cookie_raw2=$.cookie('cookie_raw2'); var cookie_header=$.cookie('cookie_header'); document.write(document.cookie+"<br/><br/>normal:"+cookie_normal+",<br/>raw:"+cookie_raw+",<br/>raw2:"+cookie_raw2+",<br/>header:"+cookie_header);</script>
这些cookie
值使用了不同的方法进行了设置。里面含有空格和加号。从结果中,我们得出如下结论:
-
setcookie
和setrawcookie
中的中文,用document.cookie
不能顺利读出,但是用jquery.cookie
可以顺利读出。 -
jquery
的cookie
插件,均正确读取了php
端的各种cookie
值。但是读取header
中的值时,对加号的处理似乎有些问题。 -
document.cookie
,只能正常读取header
设置的中文。即使中文中带有空格,也能正常读取。这也是最正常,表现最好的组合。
Summary
On the surface, using header
to set cookie
and using the setcookie
function to set cookie
are The same effect can be obtained. Uncle Sunan believes that using header
to set cookie
is better than setcookie
. Related matters will be continued in the next article. Stay tuned.
In actual operation, there are still unexpected things.