在php中设置cookie与删除cookie都可以使用php setcookie来实现,如果设置就设置有值,如果删除就设置
cookie value为空或null或时间过期都可以删除,下面我们来看一些实例。
长久以来,在php中删除cookie的时候,都是使用
bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string
$domain [, bool $secure = false [, bool $httponly = false ]]]]]] )
$value 随便写, $expire设置为一个已经过去的时间即可。
官方文档中也是这样写的:
http://www.php.net/manual/en/function.setcookie.php
Example #2 setcookie() delete example
When deleting a cookie you should assure that the expiration date is in the past, to trigger
the removal mechanism in your browser. Examples follow how to delete cookies sent in previous
example:
代码如下 |
复制代码 |
<?php
// set the expiration date to one hour ago
setcookie ("TestCookie", "", time() - 3600);
setcookie ("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?> |
今天遇到一件奇怪的事, 在setcookie的时候,传了一个空字符串给$value,结果竟然是此cookie被删除了
…
代码如下 |
复制代码 |
$name = "post_url";
$value = "";
setcookie($name, $value, time()+60*60*3, "/" );
delete_cookie
|
相当不解。
去翻php 5.4.13 的源码:
ext/standard/head.c
代码如下 |
复制代码 |
173 PHP_FUNCTION(setcookie)
174 {
175 char *name, *value = NULL, *path = NULL, *domain = NULL;
176 long expires = 0;
177 zend_bool secure = 0, httponly = 0;
178 int name_len, value_len = 0, path_len = 0, domain_len = 0;
179
180 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name,
181 &name_len, &value, &value_len, &expires, &path,
182 &path_len, &domain, &domain_len, &secure, &httponly) ==
FAILURE) {
183 return;
184 }
185
186 if (php_setcookie(name, name_len, value, value_len, expires, path, path_len, domain,
domain_len, secure, 1, httponly TSRMLS_CC) == SUCCESS) {
187 RETVAL_TRUE;
188 } else {
189 RETVAL_FALSE;
190 }
191 }
76 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)
77 {
78 char *cookie, *encoded_value = NULL;
79 int len=sizeof("Set-Cookie: ");
80 char *dt;
81 sapi_header_line ctr = {0};
82 int result;
83
84 if (name && strpbrk(name, "=,; trn1314") != NULL) { /* man isspace for 13
and 14 */
85 zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,;
\t\r\n\013\014'" );
86 return FAILURE;
87 }
88
89 if (!url_encode && value && strpbrk(value, ",; trn1314") != NULL) { /* man
isspace for 13 and 14 */
90 zend_error( E_WARNING, "Cookie values cannot contain any of the following ',;
\t\r\n\013\014'" );
91 return FAILURE;
92 }
93
94 len += name_len;
95 if (value && url_encode) {
96 int encoded_value_len;
97
98 encoded_value = php_url_encode(value, value_len, &encoded_value_len);
99 len += encoded_value_len;
100 } else if ( value ) {
101 encoded_value = estrdup(value);
102 len += value_len;
103 }
104 if (path) {
105 len += path_len;
106 }
107 if (domain) {
108 len += domain_len;
109 }
110
111 cookie = emalloc(len + 100);
112
113 if (value && value_len == 0) {
114 /*
115 * MSIE doesn't delete a cookie when you set it to a null value
116 * so in order to force cookies to be deleted, even on MSIE, we
117 * pick an expiry date in the past
118 */
119 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);
120 snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);
121 efree(dt);
122 } else {
123 snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value :
"");
124 if (expires > 0) {
125 const char *p;
126 strlcat(cookie, "; expires=", len + 100);
127 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);
128 /* check to make sure that the year does not exceed 4 digits in length */
129 p = zend_memrchr(dt, '-', strlen(dt));
130 if (!p || *(p + 5) != ' ') {
|
参数中的value在C语言中的类型是char * , 还有一个 value_len标明了它的长度。
如果value_len为0的话,就写了下面的cookie:
值为”deleted”, 过期时间为 Thu, 01-Jan-1970 08:00:01 CST 或者说是 Thu, 01-Jan-1970 00:00:01
GMT
看来setcookie($name, “”) 确实可以删除这个cookie了…
同理,在php中,strval(NULL) === “” , 所以 setcookie($name, NULL) 也就相当于 setcookie($name,
“”),同样可以删除此cookie.
另外,比较好奇的是:
代码如下 |
复制代码 |
if (value && value_len == 0) {
}
else {
} |
else 中包含了 value 为null 的情况, 这是一种什么样的情况呢?
看来setcookie($name, “”) 确实可以删除这个cookie了…
同理,在php中,strval(NULL) === “” , 所以 setcookie($name, NULL) 也就相当于 setcookie($name,
“”),同样可以删除此cookie.
另外,比较好奇的是:
代码如下 |
复制代码 |
if (value && value_len == 0) {
}
else {
} |
else 中包含了 value 为null 的情况, 这是一种什么样的情况呢?
这个文件上传类可以自定上传文件大小与上传文件类型及文件保存地址,使用起来也大兴非常的方法,有一个文就是如果是中文文件名是上传会是乱码,所以大家解决办法就是把页面保存成uft8即可解决。
今天终于算是可以来更新一下paperen的网站,嗯……因为写毕设论文写累了所以就发表一篇关于上传文件类的东东吧,这个类也是自己写的,不知道对大家有没有用,如果觉得可以就拿去用吧。不过在编码上面还是没做好,自己是在utf8的页面将数据进行提交的,所以生成的文件如果保持原来的中文名字的话在文件夹中看到就是乱码的名字,如果不想出现乱码的话需要进行一下编码的转换。?
代码如下 |
复制代码 |
<?php
define('NO_FILE', '不存在上传文件');
define('NOT_ALLOW_EXT', '文件类型不在允许范围内');
define('NOT_ALLOW_SIZE', '文件大小不在允许范围内');
define('HAS_THE_FILE', '该文件已经存在');
define('UPLOAD_FAILED', '上传失败');
define('UPLOAD_SUCCESS', '上传成功');
class file_uploader
{
var $_file;
var $_filesize;
var $_fileext;
var $_filedir;
var $_filename;
var $_filetmpname;
var $allowsize;
var $allowext;
var $neednewname;
var $newname;
var $syslang;
var $report;
function ready($filedir = '', $file, $allowsize = '', $allowext = '', $neednewname = false, $report = 0){
$this->_filedir = is_dir($filedir) ? $filedir : '';
if(empty($file) || !isset($file['size']) || $file['size'] == 0) $this->error(NO_FILE);
$this->_filesize = $file['size'];
$this->_filename = $file['name'];
$this->_filetmpname = $file['tmp_name'];
$this->allowsize = $allowsize;
$this->allowext = $allowext;
$this->neednewname = ($neednewname) ? true : false;
$this->newname = '';
$this->report = $report;
}
function do_upload(){
if(!is_uploaded_file($this->_filetmpname)) $this->error(NO_FILE);
if($this->chk_ext()){
$this->error(NOT_ALLOW_EXT);
return '';
}
if($this->chk_size()){
$this->error(NOT_ALLOW_SIZE);
return '';
}
if($this->neednewname) $this->newname = $this->generate_name().".".$this->get_fileext();
if($this->chk_hasfile()){
$this->error(HAS_THE_FILE);
return '';
}
$filename = empty($this->newname) ? @iconv('utf-8','gb2312',$this->_filename) : $this->newname;
@chmod($this->_filedir.$filename, 0777);
if(move_uploaded_file($this->_filetmpname, $this->_filedir.$filename)){
return $this->result();
}else{
$this->error(UPLOAD_FAILED);
return '';
}
}
function chk_ext(){
if(empty($this->allowext) || in_array($this->get_fileext(), explode("|",$this->allowext))) return false;
return true;
}
function chk_size(){
if(empty($this->allowsize) || get_filesize <= $this->allowsize*1024*1024) return false;
return true;
}
function get_filesize(){
return $this->_filesize;
}
function get_fileext(){
return substr($this->_filename,strrpos($this->_filename,".")+1);
}
function generate_name(){
return substr(md5(time()),26);
}
function chk_hasfile(){
return is_file($this->_filedir.$this->_filename);
}
function error($tip){
echo $tip;
}
function result(){
if($this->report){
$filename = empty($this->newname) ? $this->_filename : $this->newname;
$arr = array('filename' => $filename, 'filesize' => $this->_filesize, 'tip' => UPLOAD_SUCCESS);
return $arr;
}else{
return UPLOAD_SUCCESS;
}
}
}
/***使用方法与参数说明***/
/***
第一个参数$dir 为上传文件存放的路径
第二个参数为$_FILES 为你那个上传文件变量
第三个参数允许文件大小 单位为MB
第四个参数允许的文件类型 格式为jpg|png|gif
第五个参数是否需要生成新的文件名
第六个参数为返回的提示格式 0为直接提示上传正确 1则返回一个数组array('filename' => $filename, 'filesize' => $this->_filesize, 'tip' => UPLOAD_SUCCESS);
***/
//require("类文件");
//$u = new file_uploader;
//$u->ready($dir, $_FILES['upload_file'], false, false, true, 0);
//echo $u->do_upload();
?>
|
随便说下这个类怎样调用吧,方法很简单?
代码如下 |
复制代码 |
$dir = 'upload/';
require("upload_class.php");
$u = new file_uploader;
$u->ready($dir, $_FILES['upload_file'], false, false, true, 0);
echo $u->do_upload();
|
就像N年前那个染头发的广告说的那句,“得左!染黑头发就是这么简单!”一样,这里上传文件的操作也是“上传文件就这么简单!”。当然那个$_FILES['upload_file']是对应表单中的file类型的控件的名字。而需不需要在上传后输出提示就看你自己啦,关于参数在代码那里面有详细说明,不过这里也是放出来吧。?
ready方法的参数说明:
第一个参数$dir 为上传文件存放的路径
第二个参数为$_FILES 为你那个上传文件变量
第三个参数允许文件大小 单位为MB
第四个参数允许的文件类型 格式为jpg|png|gif
第五个参数是否需要生成新的文件名
第六个参数为返回的提示格式 0为直接提示上传正确 1则返回一个数组array('filename' => 上传的文件名字, 'filesize' => 文件大小, 'tip' => 成功上传);?
很好!这样就完成了一篇文章,不过也花了不少时间呢……?
网上有很多 PHP 代码片段可以提高开发效率,也可以学习一下其中的技巧而应用在自己的项目中,下面 我爱水煮鱼 就精选了几个比较有用的 PHP 片段。
从网页中提取关键词
从指定页面中提取关键词并显示出来。
代码如下 |
复制代码 |
$meta = get_meta_tags('http://www.111cn.net/');
$keywords = $meta['keywords'];
// 分割关键词
$keywords = explode(',', $keywords );
// 整理
$keywords = array_map( 'trim', $keywords );
// 去掉空内容
$keywords = array_filter( $keywords );
print_r( $keywords );
|
得到页面中所有的链接
下面代码可以使用 PHP DOM 获取指定页面中的所有链接,仅作抛砖引玉,具体使用自由发挥。
代码如下 |
复制代码 |
$html = file_get_contents('http://www.111cn.net');
$dom = new DOMDocument();
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");
for ($i = 0; $i < $hrefs->length; $i++) {
$href = $hrefs->item($i);
$url = $href->getAttribute('href');
echo $url.'<br />';
}
|
自动把页面中的 URL 转换成可点击的超链接
如果你发表一些文章或者做一些页面,要想放上一个超链接,必须编写一个 a 标签。使用下面这段代码可以方便的将 URL 转换成超链接输出。实现方法比较简单,大体思路就是用正则匹配出来 URL 然后处理输出超链接。
代码如下 |
复制代码 |
function _make_url_clickable_cb($matches) {
$ret = '';
$url = $matches[2];
if ( empty($url) )
return $matches[0];
// 去掉 URL 后面的标点符号
if ( in_array(substr($url, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($url, -1);
$url = substr($url, 0, strlen($url)-1);
}
return $matches[1] . "<a href="$url" rel="nofollow">$url</a>" . $ret;
}
function _make_web_ftp_clickable_cb($matches) {
$ret = '';
$dest = $matches[2];
$dest = 'http://' . $dest;
if ( empty($dest) )
return $matches[0];
if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($dest, -1);
$dest = substr($dest, 0, strlen($dest)-1);
}
return $matches[1] . "<a href="$dest" rel="nofollow">$dest</a>" . $ret;
}
function _make_email_clickable_cb($matches) {
$email = $matches[2] . '@' . $matches[3];
return $matches[1] . "<a href="mailto:$email">$email</a>";
}
function make_clickable($ret) {
$ret = ' ' . $ret;
$ret = preg_replace_callback('#([s>])([w]+?://[w\x80-\xff#$%&~/.-;:=,?@[]+]*)#is', '_make_url_clickable_cb', $ret);
$ret = preg_replace_callback('#([s>])((www|ftp).[w\x80-\xff#$%&~/.-;:=,?@[]+]*)#is', '_make_web_ftp_clickable_cb', $ret);
$ret = preg_replace_callback('#([s>])([.0-9a-z_+-]+)@(([0-9a-z-]+.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);
$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
$ret = trim($ret);
return $ret;
}
|
用 PHP 生成 Data URI 代码
通常把图片编码成 Data URI 格式用在网页中来减少 HTTP 请求来提升前端性能。同时还有一些其他的用途。下面代码可以将文件编码成 Data URI。
代码如下 |
复制代码 |
function data_uri($file, $mime) {
$contents=file_get_contents($file);
$base64=base64_encode($contents);
echo "data:$mime;base64,$base64";
}
|
将远程图片下载到本地服务器
特别是转载文章等,为了防止对方网站关掉而导致图片丢失,通常会在发表文章的时候,将远程服务器上的图片下载到本地服务器上。下面代码简单的实现了这个需求,更多的储存位置、遍历链接还需要你自己自定义:
代码如下 |
复制代码 |
$image = file_get_contents('http://www.111cn.net/logo.gif');
file_put_contents('/images/logo.gif', $image);
|
去掉文中的无用标签
当从一些文本编辑器(例如 Word)中将文本复制到网页编辑器中时,可能会有一些额外的无用标签,例如一些指定文字样式的 style 等。下面代码可以通过正则匹配来去掉这些无用标签,净化文本:
代码如下 |
复制代码 |
function cleanHTML($html) {
// 首先去掉无用的标签(可以自定义更多需要清除的标签)
$html = ereg_replace("<(/)?(font|span|del|ins)[^>]*>","",$html);
// 然后再运行两遍去掉无用属性
$html = ereg_replace("<([^>]*)(class|lang|style|size|face)=("[^"]*"|'[^']*'|[^>]+)([^>]*)>","<1>",$html);
$html = ereg_replace("<([^>]*)(class|lang|style|size|face)=("[^"]*"|'[^']*'|[^>]+)([^>]*)>","<1>",$html);
return $html
}
|
如果你也收藏了一些有用的 PHP 代码
压缩页面输入就是把所有没有用的字符转去掉,然后所有代码放到一起,这样对于seo是有帮助,但是对于代码可读性很差,我们经常会看到很多网站这样做了,如果要手动来把html中字符空格删除很麻烦,于是就有了php输出压缩HTML页面实例了。
对于服务器输出的 HTML 代码,是否也可以进行压缩呢?
下面就是一个对 HTML 进行压缩的函数:
代码如下 |
复制代码 |
function wpjam_minify_html($html) {
$search = array(
'/>[^S ]+/s', // 删除标签后面空格
'/[^S ]+</s', // 删除标签前面的空格
'/(s)+/s' // 将多个空格合并成一个
);
$replace = array(
'>',
'<',
'\1'
);
$html = preg_replace($search, $replace, $html);
return $html;
}
|
对于 WordPress 博客来说,将上面的函数和下面的代码复制到当前主题的 functions.php 文件中,就可以实现输出页面 HTML 代码的压缩:
代码如下 |
复制代码 |
if(!is_admin()){
add_action("wp_loaded", 'wp_loaded_minify_html');
function wp_loaded_minify_html(){
ob_start('wpjam_minify_html');
}
}
|
当然上面的做法都是了网站seo优化了,我们有更好的办法就是结合上面的页面压缩输出再把服务器gzip压缩打开,这样页面会更小哦,关于 apacheapache服务器开启gzip压缩实例
在php上传文件或图片时我们会碰到要限制上传文件的类型,如果我们单只限制后缀名是很容易给绕过去的,下面我找了一些后辍名对应mine对照表,希望对大家有帮助。
使用PHP脚本上传文件时需要将文件格式处理为PHP所认识的文件类型,例如(.jpg的文件格式为image/jpeg)。这个格式的判断首先是由浏览器完成的,浏览器通过表单的提交判断是某类文件,再提交给php进行处理。
有时候不同浏览器对文件类型的定义不相同,因此有时候需要对不同的浏览器做判断。其实可以将不同浏览器的类型都加入到判断中。
下面提供一张IE和火狐浏览器的文件类型对照表:
ie |
火狐 |
id |
后缀名 |
php识别出的文件类型 |
0 |
gif |
image/gif |
1 |
jpg |
image/jpeg |
2 |
png |
image/png |
3 |
bmp |
image/bmp |
4 |
psd |
application/octet-stream |
5 |
ico |
image/x-icon |
6 |
rar |
application/octet-stream |
7 |
zip |
application/zip |
8 |
7z |
application/octet-stream |
9 |
exe |
application/octet-stream |
10 |
avi |
video/avi |
11 |
rmvb |
application/vnd.rn-realmedia-vbr |
12 |
3gp |
application/octet-stream |
13 |
flv |
application/octet-stream |
14 |
mp3 |
audio/mpeg |
15 |
wav |
audio/wav |
16 |
krc |
application/octet-stream |
17 |
lrc |
application/octet-stream |
18 |
txt |
text/plain |
19 |
doc |
application/msword |
20 |
xls |
application/vnd.ms-excel |
21 |
ppt |
application/vnd.ms-powerpoint |
22 |
pdf |
application/pdf |
23 |
chm |
application/octet-stream |
24 |
mdb |
application/msaccess |
25 |
sql |
application/octet-stream |
26 |
con |
application/octet-stream |
27 |
log |
text/plain |
28 |
dat |
application/octet-stream |
29 |
ini |
application/octet-stream |
30 |
php |
application/octet-stream |
31 |
html |
text/html |
32 |
htm |
text/html |
33 |
ttf |
application/octet-stream |
34 |
fon |
application/octet-stream |
35 |
js |
application/x-javascript |
36 |
xml |
text/xml |
37 |
dll |
application/octet-stream |
38 |
dll |
application/octet-stream |
|
id |
后缀名 |
php识别出的文件类型 |
0 |
gif |
image/gif |
1 |
jpg |
image/pjpeg |
2 |
png |
image/x-png |
3 |
bmp |
image/bmp |
4 |
psd |
application/octet-stream |
5 |
ico |
image/x-icon |
6 |
rar |
application/octet-stream |
7 |
zip |
application/x-zip-compressed |
8 |
7z |
application/octet-stream |
9 |
exe |
application/octet-stream |
10 |
avi |
video/avi |
11 |
rmvb |
application/vnd.rn-realmedia-vbr |
12 |
3gp |
application/octet-stream |
13 |
flv |
application/octet-stream |
14 |
mp3 |
audio/mpeg |
15 |
wav |
audio/wav |
16 |
krc |
application/octet-stream |
17 |
lrc |
application/octet-stream |
18 |
txt |
text/plain |
19 |
doc |
application/msword |
20 |
xls |
application/vnd.ms-excel |
21 |
ppt |
application/vnd.ms-powerpoint |
22 |
pdf |
application/pdf |
23 |
chm |
application/octet-stream |
24 |
mdb |
application/msaccess |
25 |
sql |
text/plain |
26 |
con |
application/octet-stream |
27 |
log |
text/plain |
28 |
dat |
text/plain |
29 |
ini |
application/octet-stream |
30 |
php |
application/octet-stream |
31 |
html |
text/html |
32 |
htm |
text/html |
33 |
ttf |
application/octet-stream |
34 |
fon |
application/octet-stream |
35 |
js |
text/html |
36 |
xml |
text/xml |
37 |
dll |
application/octet-stream |
38 |
class |
application/java |
|
下面看一个实例
代码如下 |
复制代码 |
$temppath=$upfile['tmp_name'];
$fileinfo=pathinfo($upfile['name']);
$extension=$upfile['type'];
//echo $extension;
//exit;
switch( $extension )
{
case 'application/msword':
$extension ='doc';
break;
case 'application/vnd.ms-excel':
$extension ='xls';
break;
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
$extension ='docx';
break;
case 'application/vnd.ms-powerpoint':
$extension ='ppt';
break;
case 'application/pdf':
$extension ='pdf';
break;
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
$extension ='xlsx';
break;
default:
die('只允许上传doc,docx,xls,pdf,ppt文件 <a href="a.php">重新上传</a>');
}
|
上面实例就限制了只能上传doc,docx,xls,pdf,ppt了,这样如果有人想利用后缀名上传其它如php或asp文件就存在会提示上传文件不合法。