近来php技术群里有些关于setcookie的讨论。
直接进入主题先看看两段PHP实现COOKIE赋值代码:
1)setcookie实现:
setcookie("A", “A_1”, time() + 3600 * 24, '/');
?>
2)header方法实现
header("Set-Cookie: A=A_1;expires=Thu, 27-Feb-2014 09:38:34 GMT; Max-Age=86400; path=/");
?>
我们来看看setcookie
看源代码
打开 /php-5.5.8/ext/standard/head.c
找到 PHP_FUNCTION(setcookie) 跳到
PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC)
/*
cookie 名称不能含有 “=,; trn1314″
*/
...
if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
return FAILURE;
}
...
/*
这段代码url_encode 默认设置为1 意味着PHP setcookie的方法都会对value进行url_encode处理 。我们在http head的头部可以看到
*/
这段代码是删除一个cookie
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC);
snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt);
efree(dt);
上面的代码可以用来实现
header("Set-Cookie: A=deleted;expires=Thu, 27-Feb-2014 09:38:34 GMT; Max-Age=0; path=/");
PHP COOKIE 的核心参数
设置cookie的存储路径 表明cookie的有效路径
strlcat(cookie, "; path=", len + 100);
strlcat(cookie, path, len + 100);
设置cookie作用域
strlcat(cookie, “; domain=”, len + 100);
strlcat(cookie, domain, len + 100);
如果设置secure为true 意味只能通过https访问
if (secure) {
strlcat(cookie, "; secure", len + 100);
}
如果设置httponly为true 说明设置的cookie只能被php调用
if (httponly) {
strlcat(cookie, "; httponly", len + 100);
}
将ctr 添加到HEADER里
result = sapi_header_op(SAPI_HEADER_ADD,&ctr TSRMLS_CC);
打开SAPI.c
SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
几个关键的结构体定义:
typedef enum { /* Parameter:*/
SAPI_HEADER_REPLACE, /* sapi_header_line* */
SAPI_HEADER_ADD, /* sapi_header_line* */
SAPI_HEADER_DELETE, /* sapi_header_line* */
SAPI_HEADER_DELETE_ALL, /* void*/
SAPI_HEADER_SET_STATUS /* int */
} sapi_header_op_enum;
typedef struct {
char *header;
uint header_len;
} sapi_header_struct;
typedef struct {
char *line; /* If you allocated this, you need to free it yourself */
uint line_len;
long response_code; /* long due to zend_parse_parameters compatibility */
} sapi_header_line;
找到:
sapi_header_struct sapi_header;
…
/*
将cookie 和 长度加入sapi_header_struct结构体里
*/
case SAPI_HEADER_ADD:
case SAPI_HEADER_REPLACE:
case SAPI_HEADER_DELETE: {
sapi_header_line *p = arg;
if (!p->line || !p->line_len) {
return FAILURE;
}
header_line = p->line;
header_line_len = p->line_len;
http_response_code = p->response_code;
break;
}
…
sapi_header.header = header_line;
sapi_header.header_len = header_line_len;
上述是PHP处理setcookie的基本步骤.