PHP利用curl函数后台远程登录正方教务系统
从去年想这个事情怎么解决,今年终于算是把他搞清楚了,但验证码必须要填。
如果你能像360抢票哪有自动识别验证码,那就没事了。废话不多扯了。回归正题
这里要用CURL。
设计思路:先登录页面获取COOKIES,然后拿着cookies找服务器要验证码。最后提供服务器需要的全部信息。
(这种思维是完全模拟游览器访问页面,根本区别出来是人还机器)
代码如下 | 复制代码 |
|
访问正方教务系统的首页,第一获取页面中的HTML,第二是获取cookies。
其他的就想问?获取HTML有啥用?
如果你细心观察教务系统首页的HTML的话,你会发现里面有很多隐藏字段,而这些字段又是变化的。
所以你干脆把HTML都获取然后解析,然后把需要的字段都桃出来
看到没有,那么的隐藏字段,都是提交数据的必须,而且不能多。
页面效果
接下来我要将一个最重要的问题,怎么获取验证码?
开始我想直接
代码如下 | 复制代码 |
|
不就行了?这样验证码虽然是出来,但这个验证码不属于你,所以在你存远程登录时候,都会告诉你,验证码错误
那怎么获取属于自己的验证码呢?这时候,自然想到的是cookies。
服务器是怎么区分游览器请求是不是同一个人,就看cookies里面的sessionid了
这样。你拿着你在首页获取到的cookies,再找服务器要你的验证码,它会给错?
代码如下 | 复制代码 |
public function getImg() |
然后再在其他页面调用这个方法,你就可以获取到验证码。
CURL的PHP请求跟你游览器发出的PHP属于两个不同的线程,所以,他们的cookies是不同共用的。
————————–
这样你就可以登录了,但不要以为这样登录了,你可以操作全部功能了,那你就想错了。还有一个很小的细节。。
本文介绍了PHP会话控制,主要阐述以下几点内容:
• 会话控制的产生背景/概念
• cookie的维护与生命周期(有效时间)
• session的维护与生命周期(回收机制)
• cookie与session之间的区别与联系
• 问题1:禁用cookie后session为什么会失效?
• 问题2:IE浏览器下丢失session,每次刷新页面,都会生成新的sessionID(Firefox浏览器正常)
• session、cookie简单实例
.session配置方法
.session安全设置
● 理解会话控制的概念
理解一个概念就需要理解他的背景及产生的原因,这里引入WEB环境及其HTTP协议。会话控制产生的背景:
阅读过HTTP协议相关资料的同学都会知道HTTP协议是WEB服务器与客户端(浏览器)相互通信的协议,它是一种无状态协议,所谓无状态,指的是不会维护http请求数据,http请求是独立的,不持久的。也就是说HTTP协议没有一个内建的机制来维护两个事务之间的状态或者说是关系吧。当一个用户在请求一个页面后再去请求另外一个页面时,HTTP将无法告诉我们这两个请求是否来自同一个用户。
由此我们就会觉得很奇怪了,平时我们在论坛逛帖子或电商网站购物时,只要我们在这个站点内,不论我们怎么跳转,从一个页面跑到另一个页面,网站总会记得我是谁,比如告诉你购买了哪些东西。这是怎么做到的呢,估计大家猜到了,这就是运用了HTTP会话控制。在网站中跟踪一个变量,通过对变量的跟踪,使多个请求事物之间建立联系,根据授权和用户身份显示不同的内容、不同页面。
PHP Session会话控制:
PHP的session会话是通过唯一的会话ID来驱动的,会话ID是一个加密的随机数字,由PHP生成,在会话的生命周期中都会保存在客户端。我们知道客户端(也就是浏览器)保存数据的地方只有cookie,所以PHP的会话ID一般保存在用户机器的cookie中。了解cookie后我们知道,浏览器是可以禁用cookie的,这样会话就会失效。所以PHP会话控制还有一种模式,就是在URL中传递会话ID。如果在浏览网站时我们稍加留心的话,有些URL中有一串看起来像随机数字的字符串,那么其实很有可能就是URL形式的会话控制。
讲到这里,有些人可能会有疑问了,客户端只是保存一个会话ID,那么会话控制中保存的会话变量比如你购物时买的物品列表等,它们是存放在哪个地方的呢?很显然,会话变量是在服务器端使用的,那么这些会话变量必定存放在服务器端。默认情况下,会话变量保存在服务器的普通文件中(也可以自己配置使用数据库来保存,可以Google一下),会话ID的作用就像是一把钥匙,在服务器端保存会话的文件中找到该会话ID对应的会话变量,比如购买物品的列表。
那么会话控制的整个过程可能就像这个样子,用户登录或者第一次浏览某个站点的页面时,该站点会生成一个PHP的会话ID并通过cookie发送到客户端(浏览器)。当用户点击该站点的另一个页面时,浏览器开始连接这个URL。在连接之前,浏览器会先搜索本地保存的cookie,如果在cookie中有任何与正在连接的URL相关的cookie,就将它提交到服务器。而刚好在登陆或第一次连接时,已经产生了一个与该网站URL相关的cookie(保存的会话ID),所以当用户再次连接这个站点时,站点就可以通过这个会话ID识别出用户,从服务器的会话文件中取出与这个会话ID相关的会话变量,从而保持事务之间的连续。
接下来我们了解下两个重要的概念:cookie和session
● 关于cookie的维护与生命周期
cookie是在服务器端被创建并写回到客户端浏览器,浏览器接到响应头中关于写cookie的指令则在本地临时文件夹中
创建了一个cookie文件,其中保存了你的cookie内容,cookie内容的存储是键值对的方式,键和值都只能是字符串。例如:
文件:Cookie:administrator@localhost/
内容格式:voteID100101localhost/15361167667230343893360385046430343691*
cookie的创建:
setcookie()函数设置cookie,函数原型如下
setcookie(name, value, expire, path, domain);
注释:cookie标题头必须在发送其他标题头之前发送,否则就无效(这是cookie的限制,而不是PHP的限制)。在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码(为防止 URL 编码,请使用 setrawcookie() 取而代之)。
cookie的维护:
cooke有四个标识符:cookie的name,domain,path,secure标记。要想在将来改变这个cookie的值,需要发送另一个具有相同cookie name,domain,path的Set-Cookie消息头,这将以一个新
的值来覆盖原来cookie的值。然而,如果仅仅只是改变这些选项的某一个也会创建一个完全不同的cookie,如只是更改了name值。
cookie失效时间:
可以设置过期时间,如果不设置则是会话级别的,即关闭浏览器就会消失。当cookie创建时包含了失效日期,这个失效日期则关联了以name-domain-path-secure为标识的cookie。要改变一个cookie的失效日期,你必须指定同样的组合。当改变一个cookie的值时,你不必每次都设置失效日期,因为它不是cookie标识信息的组成部分。例如:
setcookie(vote ,$id+1,time()+3600*24);
setcookie(vote,$id);在cookie上的失效日期并没有改变,因为cookie的标识符是相同的。实际上,只有你手工的改变cookie的失效日期,否则其失效日期不会改变。这意味着在同一个会话中,一个会话cookie可以变成一个持久化cookie(一个可以在多个会话中存在的),反之则不可。为了要将一个持久化cookie变为一个会话cookie,你必须删除这个持久化cookie,这只要设置它的失效日期为过去某个时间之后再创建一个同名的会话cookie就可以实现。
需要记得的是失效日期是以浏览器运行的电脑上的系统时间为基准进行核实的。没有任何办法来来验证这个系统时间是否和服务器的时间同步,所以当服务器时间和浏览器所处系统时间存在差异时这样的设置会出现错误。
cookie自动删除:
cookie会被浏览器自动删除,通常存在以下几种原因:
会话cooke(Session cookie)在会话结束时(浏览器关闭)会被删除
持久化cookie(Persistent cookie)在到达失效日期时会被删除,如:
setcookie("vote", "", time()-3600);如果浏览器中的cookie限制到达,那么cookies会被删除以为新建cookies创建空间。
● 关于session的维护与生命周期
Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器创建生成一个唯一的sessionID,用该sessionID为标识符来存取服务器端的Session存储空间,在会话期间,分配给客户端的唯一sessionID,用来标识当前用户,与其他用户进行区分。通过SessionID接受每一次访问的请求,从而识别当前用户,跟踪和保持用户的具体资料,以及session变量,可在session中存储数字或文字资料.比如session_name.这些信息都保存在服务器端。当然,sessionID也可以作为会话信息保存到数据库中,进行session持久化。这样可以跟踪用户的登陆次数、在线与否、在线时间等从而维护HTTP无状态事物之间的关系。session的内容存储是键值对的列表,键是字符串类型,session的存储更方便,值可以是对象。
在session会话期间,session会分别保存在客户端和服务器端两个文件,客户端可以是cookie方式保存的sessionID(默认的保存方式)或通过url字符串形式传递。服务器端一般以文本的形式保存在指定的session目录中。在服务器端我们可以通过session.use_cookies来控制客户端使用哪一种保存方式。如果定义为cookie保存方式,我们可以通过session.cookie_lifetime(默认值0,闭浏览器就清除)来控制被保存在client上的cookie的有效期。而如果客户端用cookie方式保存的sessionID,则使用“临时”的cookie保存(cookie的名称为PHPSESSID,通过Firebug你可以了解到详细的信息,该名称你可以通过php.ini session.name进行更改),用户提交页面时,会将这一SessionID提交到服务器端,来存取session数据。这一过程,是不用开发人员干预的。
Session的创建:
session_start() //开始一个会话及返回已经存在会话
功能:初始化Session,也标识着session生命周期的开始。要使用session,必须初始化一个session环境,有点类似于OOP概念中调用构造函数构创建对象实例一样。session初始化操作,声明一个全局数组$_SESSION,映射寄存在内存的session数据。如果session文件已经存在,并且保存有session数据,session_start()则会读取session数据,填入$_SESSION中,开始一个新的session生命周期。
说明:这个函数没有参数,且返回值为true,如果使用基于cookie的sessin,那么在session_satrt()之前不能有任何的输出,包括空白
如果在php.ini中session.auto_start=1开启,则在每个页面执行session_start(),不需要手工设置,该选项默认为关闭状态,开启后不能将对象放入session中。
Session ID:
用户session唯一标识符,随机生成的一串字符串,具有唯一性,随机性。主要用于区分其它用户的session数据。用户第一次访问web页面的时候,php的session初始化函数调用会分配给当前来访用户一个唯一的ID,也称之为session_id。
获得session_id():
echo $_COOKIE['PHPSESSID'].'<br/>';
echo $_COOKIE[session_name()].'<br/>';
echo session_id().'<br/>';
session数据:
我们把需要通过session保存的用户状态信息,称为用户session数据,也称为session data。一般是在当前session生命周期内,相应的$_SESSION数据。一旦调用了session_start()初始化session,就意味着开始了一个session生命周期。也就是宣布了,可以使用相关函数操作$_SESSION来管理session数据。这个session生命周期产生的数据并没有实时地写入session文件,而是通过$_SESSION变量寄存在内存中。$_SESSION是一个全局变量,类型是Array,映射了session生命周期的session数据,寄存在内存中。在session初始化的时候,从session文件中读取数据,填入该变量中。在session(生命周期)结束时,将$_SESSION数据写回session文件。
注册一个会话变量:
从PHP4.1以后,会话变量保存在超级全局数组$_SESSION中。要创建一会话变量,只需要在数组中设置一个元素,如:
代码如下 | 复制代码 |
$_SESSION['domain'] = blog.www.111cn.net; $_SESSION['poll']=$_SESSION[poll] + 1; |
使用一个会话变量:
echo $_SESSION['blogdomain']; //打印出blog.www.111cn.net,使用会话前必须先使用session_start()函数启动一个会话
注销Session变量/销毁会话:
代码如下 | 复制代码 |
unset($_SESSION); //销毁单个会话变量 |
如:unset($_SESSION['blogdomain']);
#unset($_SESSION)这个函数会将全局变量$_SESSION销毁,而且还没有可行的办法将其恢复。用户也不再可以注册$_SESSION变量,所以此函数千万不可使用。
session_unset(); //多项释放。将所有登陆在session文件里的变量释放出来
#在session生命周期,从当前session中注销全部session数据,让$_SESSION成为一个空数组。它与unset($_SESSION)的区别在于:unset直接删除$_SESSION变量,释放内存资源;另一个区别在于,session_unset()仅在session生命周期能够操作$_SESSION数组,而unset()则在整个页面(page)生命周期都能操作$_SESSION数组。session_unset()同样不进行任何IO操作,只影响$_SESSION数组。
$_SESSION=array(); //多项释放,释放所有登录在$_SESSION参数里的变量
session_destroy();
#当使用完一个会话后,首先应该注销所有的变量,然后再调用该函数结束当前的会话,并清空会话中的所有资源,删除服务器上的session文件.该函数不会unset(释放)和当前session相关的全局变量,也不会删除客户端的session cookie
#如果说session_start()初始化一个session的话,而它则注销一个session。意味着session生命周期结束了。在session生命周期结整后, session_unset, $_SESSION['domain'] 都将不能操作$_SESSION数组,而$_SESSION数组依然可以被unset()等函数操作。这时,session意味着是未定义的,而$_SESSION依然是一个全局变量,他们脱离了关映射关系。
通过session_destroy()注销session,除了结束session生命周期外,它还会删除sesion文件,但不会影响当前$_SESSION变量。即它会产生一个IO操作。
备注:
1、php默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数
2、session_unset()和unset()函数区别:
在session生命周期,session_unset()从当前session中注销全部session数据,让$_SESSION成为一个空数组。它与unset($_SESSION)的区别在于:unset直接删除$_SESSION变量,释放内存资源;另一个区别在于,session_unset()仅在session生命周期能够操作$_SESSION数组,而unset()则在整个页面(page)生命周期都能操作$_SESSION数组。session_unset()同样不进行任何IO操作,只影响$_SESSION数组。
Session生命周期(session lifetime):Session失效时间与过期回收机制
我们把初始化session开始,直到注销session这段期间,称为session生命周期
默认的,php会将session保存在php.ini配置中session.save_path设定的目录下,文件名为这个样子:sess_ves0d7uvdsab9k6sig73mnn592。每一个文件对应了一个session(会话)。session文件格式大致如下:
poll_200|i:1;poll_100|i:3; //#变量名|类型:长度:值
设置SESSION的生命周期:
php session是基于cookie的,所以要设置session的生命周期,首先要设置cookie的失效时间。因为在客户端(如浏览器)登录网站时,SESSION 是否有用,首先找客户端是否有 COOKIE,通过COOKIE 中的 SESSION ID 去找服务器上的文件。
代码如下 | 复制代码 |
session_start(); $lifeTime = 24 * 3600; // 保存一天 setcookie(session_name(), session_id(), time() + $lifeTime, "/"); 其实PHP5 Session还提供了一个函数 session_set_cookie_params(); 来设置PHP5 Session的生存期的,该函数必须在 session_start() 函数调用之前调用: $lifeTime = 24 * 3600; // 保存一天 session_set_cookie_params($lifeTime); session_start(); |
在服务器端,php如何判断session文件是否过期?
session.gc_maxlifetime = 1440 (初始值)
#设置session存活时间,单位是秒。每次GC启动后, 会通过stat得到session文件最后访问的unix时间,通过现在时间减去文件最后访问时间之间大于session.gc_maxlifetime,则会删除该文件。
如果"最后的修改时间"到"现在"超过了session.gc_maxlifetime(默认是1440)秒,也就是说在这里设置的时间内,该文件没有被修改过,这个session文件就被认为是过期了,由于php5的session采用被动的回收机制,过期的session文件不会自己消失,而是通过触发“回收”来处理过期的session,那么在下一次session回收的时候,如果这个文件仍然没有被更改过,这个session文件就会被删除(session就过期了)。
session回收何时发生?
默认情况下,每一次php请求,就会有1%的概率发生回收,所以可能简单的理解为“每100次php请求就可能有一次回收概率发生”。这个概率是通过以下参数控制的:
session.gc_probability = 1 (初始值)
session.gc_divisor = 100 (初始值)
#由这二个函数决定了启用GC的概率,默认是1/1000。也就是说,每一千次用户请求中有一次会启动GC回收session。启动GC进程不宜过于频繁。过于频繁访问的网站,并发量大的网站,可减小PHP GC的启动频率。PHP GC回收session会降低php的执行效率。
这两个合起来就是启动Gabadge Collection(gc)进程管理概率的,在session初使化时(session_start())。Gabadge Collection启动后跟踪session信息文件。其启动概率为session.gc_probability/session.gc_divisor。也就是说不是每个session信息文件都有100%的被系统当作垃圾来处理的。如果直接关闭浏览器的话,session信息文件很多情况下都是留在了服务器上,如果把概率改成了100%,虽然Gabadge Collection百分之百被启动了,但是这会对服务器添加负荷,也就失去了GC本身的意义了。
补充说明:
1、假设这种情况session.gc_maxlifetime=1440,如果某个session文件最后修改时间是1440秒之前,那么在下一次回收(1/100的概率)发生前,这个session仍然是有效的;
2、如果你的session使用session.save_path中使用别的地方保存session,session回收机制有可能不会自动处理过期session文件。这时需要定时手动(或者crontab)的删除过期的session:cd /path/to/sessions; find -cmin +24 | xargs rm;
3、注意,当服务器端session文件数量没有得到有效的回收,逐渐增长到GB或更大级别时可能你的站点在存取session时就会越来越缓慢,多见于站点登入登出会受到影响;
4、写日志、周报、月报等时候我们最后提交的关头,有时会出现”无效的操作,请登陆后重试”等消息,其原因也不言而喻,可能就是session失效,gc清除那些已经“超时”的session文件。
一些特殊情况:
因为回收机制会检查文件的“最后修改时间”,所以如果某个会话是活跃的,但是session的内容没有改变过,那么对应的session文件也就没有改变过,回收机制会认为这是一个长时间没有活跃的session而将其删除。这是我们不愿看到的,可以通过增加如下的简单代码解决这个问题:
代码如下 | 复制代码 |
<?php if(!isset($_SESSION['last_access'])||(time()-$_SESSION['last_access'])>120) $_SESSION['last_access'] = time(); ?> |
//代码会每隔120秒,尝试修改修改一次session
● 了解cookie与session之间的区别与联系
相同点:都可以在解决HTTP无状态的问题,使同一个客户端在访问网站的多次请求中,可以保存,设置信息,并且在请求事物之间建立联系。
不同点:简单的说cookie的信息保存在客户端,session的信息保存在服务器端。
Session采用键值对,也就是说ID存放客户端,而值放在服务器端,是通过用户的ID去找服务器上对应的值,这种方式值放置在服务器端,有个时间限制,时间到则服务器自动回收/释放。
Cookies则有两种方法,一种方法是把值保存在浏览器的变量中,当浏览器关闭时结束,另一种方法是保存在硬盘中,只要时间不过期,下次还可使用。
联系:当客户端使用基于Cookie方式保存的SessionID时,SessionID一般保存在cookie中。
备注:cookie在相同内核的浏览器之间是共享的,不同内核浏览器是不共享的例如火狐和IE(存放位置都不同,当然不共享)。不同内核浏览器不能共享cookie,也会产生不同sessionid。
● 问题1:禁用cookie后session为什么会失效?
首先说明一点:session不一定必须依赖cookie,只是php默认客户端sessionid基于cookie方式保存。
到此,我想你也应该了解了php默认的session客户端保存方式是基于cookie的,所以一旦客户端禁用Cookie,那么session跨页将会失效,不知道这么描述是否合适,通俗的说无状态的东西要变的有状态,只能两边都进行比对,如果用cookie方式保存的SessionID,客户端这边的比对条件就放到cookie里,所以客户端禁用cookie,session便也会随之失效。php的session客户端ID一般有两种保存方式:cookie和url方式。如果是cookie中保存session ID,就可以看到浏览器的cookie中有一个PHPSESID变量(可以通过firefox查看)。如果是URL传递的(建议使用隐藏表单传递),就可以看到形如:index.php?PHPSESID=ves0d7uvdsab9k6sig73mnn592的URL。例如:
demo1.php
代码如下 | 复制代码 |
<?php demo2.php |
运行上面的代码,在客户端cookie正常情况下,我么可以在demo2.php中打印出$_SESSION['blog']的值为:http://www.111cn.net。但是,现在如果你手动禁用客户端的cookie,再运行该实例,可能就得不到结果了。因为默认的客户端sessionid保存方式在跨页后,读取不到前一页的sessionid,当执行session_start();将又会产生一个session文件,与之对应产生相应的session id,用这个session id是取不出前面提到的第一个session文件中的变量的,因为这个session id不是打开它的“钥匙”。如果在session_start();之前加代码session_id($sessionid);将不产生新的session文件,直接读取与这个id对应的session文件。简单的说就是在前一页取得session id,然后想办法传递到下一页,在下一页的session_start();代码之前加代码session_id(传过来的sessionid); 例如:
demo.php
代码如下 | 复制代码 |
<?php demo2.php |
除此之外,我们还可以将客户端PHPSESID存放到文件中,如:
demo.php
代码如下 | 复制代码 |
session_start(); demo2.php |
当客户端禁用cookie,可以通过以下几种方式改变session对客户端cookie的依赖,使session抛开客户端cookie:
1、设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项,让PHP自动跨页传递session id。当session.use_trans_sid为有效时,ession.use_only_cookies一定要设置为无效0。
2、手动通过URL传值、隐藏表单传递session id。
3、用文件、数据库等形式保存session_id,在跨页过程中手动调用。
PHP也提供一个函数:
output_add_rewrite_var ( string $name , string $value ) # 变量名 变量值
说明:此函数给URL重写机制添加名/值对。 这种名值对将被添加到URL(以GET参数的形式)和表单(以input隐藏域的形式),当透明URL重写用 session.use_trans_sid 开启时同样可以添加到session ID。 要注意,绝对URL(http://www.111cn.net/..)不能被重写。此函数的行为由url_rewriter.tags php.ini 参数控制。
代码如下 | 复制代码 |
<? session_start(); output_add_rewrite_var('PHPSESSID',session_id ()); echo '<a href="demo2.php" _fcksavedurl="demo2.php">demo</a>'; ?> |
这样sessionID会跟在URL后面而且from中会出现sessionID的hidden值。
改变session客户端ID保存方式:
session.use_cookies //控制客户端保存SessionID时使用哪一种方式,当它为“1”时,就说明启动了session cookie(初始值为1)
可以使用上面我们提到的函数来查询得到目前的session id:echo $_COOKIE["PHPSESSID"];
但是,如果client的浏览器不支持cookie的话,即使session.use_cookies这个参数的值等于“1”,用上述的查询也只会得到null。
php.ini中两个和该选项相关的配置参数:
session.use_cookies = 1 //是否使用cookies(默认值为1)
session.use_only_cookies=1 //为1时只使用cookie;为0时可使用cookie和其它方式,这时如果客户端cookie可用,则session还是默认用cookie(默认值为1)
注意:如果客户的浏览器是支持cookie的,强烈推荐“session.use_only_cookies = 1”,当session.use_only_cookies为有效时,即使想通过URL来传递session id也会被认为无效,这样可以减少通过sessionid被攻击的可能性。上面两个配置,在php代码页面中设置方式:
ini_set('session.use_cookies','1');
ini_set('session.use_only_cookies','1');
● IE下丢失session,每次刷新页面,都会生成新的sessionID(Firefox浏览器都正常)
如果你的服务器或站点出现这种问题,请正确配置session.cookie_path网站域,如果配置错误可能会引起以下常见故障:
(1)客户端的每个PHPSESSID在服务器端都会一对一的对应生成一个独立的session记录存储在服务器端,故服务器端session文件冗余将会增多(GC回收机制异常时、站点访问量较大时)
(2)使用session记录相关信息的站点可能在除Firefox(Chrome未测试)之外的浏览器下访问出现问题,例如:购物车无法记录选购项目、站点登录失败等
session.cookie_path 是指 session 生效的网站域;
session.save_path 是指存储 session 临时文件的路径。
例如:session.cookie_path= / //cookie的有效路径
补充:如果所有浏览器访问刷新产生新sessionID,请检查客户端是否禁用了cookie。
● session简单实例
使用session防止表单重复提交:
代码如下 | 复制代码 |
<?php vote.php 投票动作执行页面 |
例子
-cookie运用和Session会话处理
一.Cookie
的应用
设置cookie:setcookie()函数可以在客户端生成一个cookie 文件,这个文件可以保存到
期时间、名称、值等。
创建cookie
<?php
setcookie(‘name’,'Lee’,time()+(7*24*60*60));//设置一个过期时间为7天的cookie
?>
参数1:cookie 名称
参数2:cookie 值
参数3:cookie 过期时间
查看cookie
打开火狐浏览器:工具–页面信息-安全-查看cookie,可以查看到当前的cookie信息
读取cookie
代码如下 | 复制代码 |
<?php echo $_COOKIE['name']; ?> 删除cookie <?php setcookie(‘name’,”); setcookie(‘name’,'Lee’,time()-1); ?> |
使用Cookie 的限制
1、必须在HTML 文件的内容输出之前设置;
2、不同的浏览器对Cookie 的处理不一致,且有时会出现错误的结果。
3、限制是在客户端的。一个浏览器能创建的Cookie 数量最多为30 个,并且每个不能
超过4KB,每个WEB 站点能设置的Cookie 总数不能超过20 个。
二.Session
会话处理
在使用session 会话处理,必须开始session,使用session_start()开始会话。
创建session 并读取session
代码如下 | 复制代码 |
<?php
|
####################################
# 配置文件中session常用设置
####################################
[Session]
; 定义了存储和获取与会话相关联数据的处理器名称。四种:①files 文件(默认) ②mm 共享内存 ③sqlite SQLite数据库 ④user 用户自定义的函数
session.save_handler = files
; 传送到save_handler的参数. 在使用文件的情况下, 这里是数据文件被保存的路径.
; 注意: Windows 用户必须改变此值来使用PHP的会话函数.
;
; 和在 4.0.1一样, 你可以定义如下路径:
;
; session.save_path = "N;/path"
;
; 这里的 N 是一个整数. 使用此参数会在目录内建立一个N层深度的子目录用来保存session文件,
; 而不是将所有session文件保存在同一个/path目录内.
; 这对你或当你的操作系统在一个目录内保存太多文件时出现问题很有帮助.
; 并且对于处理大量session的服务器提供更高的效率.
;
; 注意 1: PHP不会自动创建目录结构. 你可以使用在ext/session目录内的脚本来创建目录结构.
; 注意 2: 如果你选择使用子目录来保存session,请检查下面关于垃圾回收的配置段
;
; 文件存储模块默认使用600模式来创建文件,在使用中你可以改变此选项
;
; session.save_path = "N;MODE;/path"
;
; 这里的MODE由8进制来表示. 注意这里不会覆盖进程的umask.
;session.save_path = "/tmp"
; 用来设置是否在客户端使用cookie来存放会话ID.
session.use_cookies = 1
; 用来设置是否只使用安全链接协议(https)来发送cookie
;session.cookie_secure =
; 用来决定是否在客户端只使用cookie来存放会话ID,而放弃使用URL,很好的保护了那些在URL中传送session id的用户免于被攻击。 默认是 0.
; session.use_only_cookies = 1
; session的默认名称 (作为cookie名称来使用).
session.name = PHPSESSID
; 用于指定是否在请求开始的时候自动启动session.
session.auto_start = 0
; 用于指定放送到浏览器端的会话cookie的生命周期(单位:秒),或者如果为0表示cookie的生命周期直到浏览器被关闭为止。
session.cookie_lifetime = 0
; cookie有效作用路径.
session.cookie_path = /
; cookie有效的作用域名.可以防止别的域非法读取自己的会话cookie,以增强cookie的安全性
session.cookie_domain =
; 是否将httpOnly标志增加到cookie上, 增加后则cookie无法被浏览器的脚本语言(例如JavaScript)存取.
session.cookie_httponly =
; 用于序列化数据的处理器. php是标准的PHP序列化器.
session.serialize_handler = php
; 定义在每次session初始化时启动'垃圾回收'进程的概率.
; 比例由 gc_probability/gc_divisor来得出,
; 例如. 1/100 意味着在每次请求时有1%的机会启动'垃圾回收'进程.
session.gc_probability = 1
session.gc_divisor = 100
; 指定了经过多少秒数之后,存储的数据会被认为是'垃圾'并且被垃圾回收进程清理掉. 单位:秒。 1440 == 24分钟
; 它的判断依据是最后访问数据的时间,对于FAT文件系统则是最后修改数据的时间。
session.gc_maxlifetime = 1440
; 注意: 如果你使用子目录选项来保存session文件
; (查看在上面的session.save_path), 那么垃圾回收就 *不会* 自动发生.
; 你需要通过一个shell脚本,cron或者其他方法来自行处理垃圾回收.
; 例如, 下面的脚本相当于将session.gc_maxlifetime设置为 1440 (1440 秒 = 24 分钟):
; cd /path/to/sessions; find -cmin +24 | xargs rm
; PHP 4.2 和更早版本有一个未公开的 特性/bug , 此特性允许你在全局初始化一个session变量,即便 register_globals 已经被关闭.
; 如果此特性被使用,PHP 4.3 和更早版本会警告你.
; 你可以关闭此特性并且隔离此警告. 这时候,如果打开bug_compat_42,那此警告只是被显示出来.
session.bug_compat_42 = 1
session.bug_compat_warn = 1
; 检查HTTP Referer来防止带有id的外部URL.
; 用来验证HTTP_REFERER中是否包含指定的字符串(通过下面字段设置),如果包含则会话ID被视为有效。默认为空,表示全部视为有效。
session.referer_check =
; 从此文件读取多少字节.
session.entropy_length = 0
; 在这里指定创建session id.
session.entropy_file =
;session.entropy_length = 16
;session.entropy_file = /dev/urandom
; 设置为 {nocache,private,public,} 来决定HTTP缓冲的类型
; 留空则防止发送 anti-caching 头.
session.cache_limiter = nocache
; 文档在n分钟之后过期.
session.cache_expire = 180
; trans sid 支持默认关闭.
; 使用 trans sid 可能让你的用户承担安全风险.
; 使用此项必须小心.
; - 用户也许通过email/irc/其他途径发送包含有效的session ID的URL给其他人.
; - 包含有效session ID的URL可能被存放在容易被公共存取的电脑上.
; - 用户可能通过在浏览器历史记录或者收藏夹里面的包含相同的session ID的URL来访问你的站点.
session.use_trans_sid = 0
; 选择hash方法
; 0: MD5 (128 bits)
; 1: SHA-1 (160 bits)
session.hash_function = 0
; 当转换二进制hash数据到可读形式时,每个字符保存时有几位.
;
; 4 bits: 0-9, a-f
; 5 bits: 0-9, a-v
; 6 bits: 0-9, a-z, A-Z, "-", ","
session.hash_bits_per_character = 4
; URL rewriter会在已经定义的一组HTML标签内查找URL.
; form/fieldset 是特殊字符; 如果你在这里包含他们, rewriter会增加一个包含信息的隐藏<input>字段否则就是在URL中附加信息.
; 如果你你想遵守XHTML, 删除form的入口.
; 注意 所有合法的入口都需要一个"="符号, 甚至是没有任何值的.
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset="
2.5 session安全问题
攻击者通过投入很大的精力尝试获得现有用户的有效会话ID,有了会话id,他们就有可能能够在系统中拥有与此用户相同的能力.
因此,我们主要解决的思路是效验session ID的有效性.
代码如下 | 复制代码 |
<?php elseif ($_SESSION['user_agent'] != $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']) |
下面我们一起来看我整理了在php开发中一些常用的php函数整理,希望这些函数代码地各位同学同样有帮助哦。
1.关键词高亮
代码如下 | 复制代码 |
function highlight($sString, $aWords) { $sWords = implode ('|', $aWords); |
2.获取你的Feedburner的用户
代码如下 | 复制代码 |
function get_average_readers($feed_id,$interval = 7){ $nb = 0; return round($nb/$interval); |
3.自动生成密码
代码如下 | 复制代码 |
function generatePassword($length=9, $strength=0) { $password = ''; |
4.压缩多个CSS文件
代码如下 | 复制代码 |
header('Content-type: text/css'); /* your css files */ ob_end_flush(); |
5.获取短网址
代码如下 | 复制代码 |
function getTinyUrl($url) { return file_get_contents("http://tinyurl.com/api-create.php?url=".$url); } |
6.根据生日计算年龄
代码如下 | 复制代码 |
function age($date){ $date = date('Y-m-d', $time); return $year_diff; |
7.计算执行时间
代码如下 | 复制代码 |
//Create a variable for start time // Place your PHP/HTML/JavaScript/CSS/Etc. Here //Create a variable for end time echo 'Script took '.$time.' seconds to execute';8.PHP的维护模式 if(basename($_SERVER['SCRIPT_FILENAME']) != 'maintenance.php'){ |
9.阻止CSS样式被缓存
代码如下 | 复制代码 |
<link href="/stylesheet.css?<?php echo time(); ?>" rel="stylesheet" type="text/css" /&glt;10.数字增加 stndrd 等 if( $last == 1 && $seclast == 1) $ext = 'th'; return $rank.$ext; |
通过IP判断来源
这是一个非常实用的代码片段,可以帮助你通过IP来判断访客来源。下面的方法通过接收一个参数,然后返回IP所在地点。如果没有找到,则返回UNKNOWN。
代码如下 | 复制代码 |
function detect_city($ip) { $default = 'UNKNOWN'; if (!is_string($ip) || strlen($ip) < 1 || $ip == '127.0.0.1' || $ip == 'localhost') $ip = '8.8.8.8'; $curlopt_useragent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)'; $url = 'http://ipinfodb.com/ip_locator.php?ip=' . urlencode($ip); $ch = curl_init(); $curl_opt = array( CURLOPT_FOLLOWLOCATION => 1, CURLOPT_HEADER => 0, CURLOPT_RETURNTRANSFER => 1, CURLOPT_USERAGENT => $curlopt_useragent, CURLOPT_URL => $url, CURLOPT_TIMEOUT => 1, CURLOPT_REFERER => 'http://' . $_SERVER['HTTP_HOST'], ); curl_setopt_array($ch, $curl_opt); $content = curl_exec($ch); if (!is_null($curl_info)) { $curl_info = curl_getinfo($ch); } curl_close($ch); if ( preg_match('{<li>City : ([^<]*)</li>}i', $content, $regs) ) { $city = $regs[1]; } if ( preg_match('{<li>State/Province : ([^<]*)</li>}i', $content, $regs) ) { $state = $regs[1]; } if( $city!='' && $state!='' ){ $location = $city . ', ' . $state; return $location; }else{ return $default; } } |
判断一张图片的主色调
下面这个代码非常实用,能帮助你判断一张图片中的主色调,你可以分析任何图片。
代码如下 | 复制代码 |
$i = imagecreatefromjpeg("image.jpg"); for ($x=0;$x<imagesx($i);$x++) { for ($y=0;$y<imagesy($i);$y++) { $rgb = imagecolorat($i,$x,$y); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> & 0xFF; $b = $rgb & 0xFF; $rTotal += $r; $gTotal += $g; $bTotal += $b; $total++; } } $rAverage = round($rTotal/$total); $gAverage = round($gTotal/$total); $bAverage = round($bTotal/$total); |
不显示PHP错误而发送电子邮件取代之
如果你不想在页面中显示PHP错误,也可以通过email来获取错误信息。下面的代码可以帮助你实现。
代码如下 | 复制代码 |
<?php // Our custom error handler function nettuts_error_handler($number, $message, $file, $line, $vars){ $email = " <p>An error ($number) occurred on line <strong>$line</strong> and in the <strong>file: $file.</strong> <p> $message </p>"; $email .= "<pre>" . print_r($vars, 1) . "</pre>"; $headers = 'Content-type: text/html; charset=iso-8859-1' . "rn"; // Email the error to someone... error_log($email, 1, 'you@youremail.com', $headers); // Make sure that you decide how to respond to errors (on the user's side) // Either echo an error message, or kill the entire project. Up to you... // The code below ensures that we only "die" if the error was more than // just a NOTICE. if ( ($number !== E_NOTICE) && ($number < 2048) ) { die("There was an error. Please try again later."); } } // We should use our custom function to handle errors. set_error_handler('nettuts_error_handler'); // Trigger an error... (var doesn't exist) echo $somevarthatdoesnotexist; |
场景说明/问题描述:
Ajax提交页面编码为gb2312,数据库编码为utf8,在不更改页面及数据库编码的情况下插入数据。
自定义函数:
代码如下 | 复制代码 |
function array_iconv($in_charset,$out_charset,$arr){ return eval('return '.iconv($in_charset,$out_charset,var_export($arr,true).';')); } |
函数说明:
var_export设置第二个参数为true,返回数组原型字符串,将字符串转换为utf-8编码,之后再用eval来执行返回。
范例:
代码如下 | 复制代码 |
$postdata = $_POST; $data = array_iconv('gb2312','utf-8',$postdata) print_r($data); |
借助Firefox firebug组件我们可以看到:
再看下数据库:
可以看到编码已经正常且入库成功
下面给各位同学整理了一些关于php array数组的相关处理函数and str字符串处理与正则表达式,希望文章对你会有所帮助。数组的相关处理函数:
1)数组的键值操作函数
array_values();//获取数组中的值
array_keys();//获取数组中的键
in_array();//检查一个值是否在数组中
array_key_exists();//检查一个键是否在数组中
array_flip();//键和值对调
array_reverse();//数组中的值反转
2)统计数组的元素和唯一性
count();//统计数组的个数
array_count_values();//统计数组中值出现的次数
array_unique();//删除数组中重复值
3)使用回调函数处理数组的函数
array_filter();//数组值过滤
array_map();//将回调函数作用到给定数组的单元上
4)数组的排序函数
sort();
//按值把数组值进行排序,升序,不保留key
rsort();
//按值把数组值进行排序,降序,不保留key
asort();
//按值把数组值进行排序,升序,保留key
arsort();
//按值把数组值进行排序,降序,保留key
ksort();
//按键把数组值进行排序,升序,保留key
krsort();
//按键把数组值进行排序,降序,保留key
natsort();
//按自然数排序
natcasesort();
//忽略大小写的自然数排序
array_multisort();//用一个数组对另外一个数组进行排序
SORT_DESC倒序
SORT_ASC正序 array_multisort($arr2,SORT_DESC,$arr);
5)拆分、合并、分解与结合函数
array_slice();//截取一段值 $arr2=array_slice($arr,0,3); 0开始位置,3个 ,返回值:截取的内容
array_splice();//截取一段值,保留一段值
返回值:截取后剩下的内容 //array_splice(3,3,"aa"); 从下标3的位置开始向后截取3个值,aa替换截取的内容
array_combine();//合并,一个是key,一个是value eg: $arr3=array_combine($arr1,$arr2); $arr1为key值 ,$arr2为值
array_merge(); 并集 //合并,键值相同,后面覆盖前面 返回一个新数组 $arr3=array_merge($arr1,$arr2);
array_intersect();//交集
array_diff();//差集
implode();//把数组连接成字符串 eg: $str=implode("|" ,$arr); | 分割符
explode();//把字符串分解成数组 eg: $arr=explode('|',$str);
6)数组与数据结构
array_pop();//从最后弹出一个值,返回弹出值 //unset($arr[count($arr)-1]);
array_push(); array_push($arr,6);//从最后添加一个值,返回数组个数
//$arr[]="aa";
array_shift();//从前面弹出一个值,返回移出值,原数组下标重排
//unset($arr[0]); 原数组下标不重排
array_unshift();//从前面插入一个值,返回数组个数
7)其他有用的数组处理函数
array_rand();//随机取一个key
shuffle();//打乱数组
array_sum();//数组所有值的和
range();//获取一个范围内数组
//range(1,10); 返回数组 array(1,2,3,...,10);
//range(1,10,2); array(1,3,5,7,9); 2代表差值;默认是0不写
字符串处理与正则表达式
————————————————
1.字符串的处理介绍
2.常用的字符串输出函数
3.常用的字符串格式化函数
4.字符串比较函数
5.正则表达式在字符串中的应用
6.与perl兼容的正则表达式函数
字符串的输出:
1)echo "hello world www.111cn.net";
2)print "aaaa";
3)die("输出一条错误消息");
4)printf("--%s----%s--",$a,$b);
%s 字符串
%d 数字
%f 浮点型 //%.2f 小数点后面两位
5)sprintf("$s%s",$a,$b);
不直接输出,而是返回值给一个新的变量
常用的字符串格式化函数:
1.去除空格和字符串填补函数
ltrim() //去左边空格
rtrim() //去右边空格;
trim() //去掉两头空格 $str='abc'; trim($str,'b'); echo $str ; 结果 :ac; 可以删除指定的字符串
str_pad() //向字符串里添加空格或字符串
<?php
$input = "Alien";
echo str_pad($input, 10); // 输出 "Alien "
echo str_pad($input, 10, "-=", STR_PAD_LEFT); // 输出 "-=-=-Alien"
echo str_pad($input, 10, "_", STR_PAD_BOTH); // 输出 "__Alien___"
echo str_pad($input, 6 , "___"); // 输出 "Alien_"
?>
2.字符串大小写转换函数
strtolower()
strtoupper()
ucfirst()
ucwords()
3.与html标签相关联的字符串函数
nl2br()
htmlspecialchars()
strip_tags()
addslashes()
stripslashes()
4.其他字符串格式化函数
strrev()
strlen()//返回字符串的长度
number_format()
md5() //单向不可逆加密
str_shuffle() //随机输出字符串
字符串比较函数:
1.按字节进行字符串的比较
1
strcmp($str1,$str2) //比较字符串的每个字节
strcasecmp()//忽略大小写比较字符串的每个字节
2.按自然排序法时字符串的比较
strnatcmp();
//按自然排序比较字符串中的数字
字符串的分割与拼接:
1.分割
//把字符串分割成数组
explode()
preg_split('//',$str);
2.拼接
//把数组拼接成字符串
implode()
join() //等于implode();
字符串的截取:
substr()
字符串的查找:
strstr()//查找指定字符在字符串中的第一次出现
strrchr()//查找指定字符在字符串中的最后一次出现
strpos()//w在$str中第一次出现的位置
strrpos($str,'w')//w在$str中最后一次出现的位置
字符串的替换:
1
str_replace()
支持多字节文字
mb_substr($str,0,7,"utf-8");
mb_strpos();
mb_strrpos();
mb_strstr();
mb_strtoupper();
mb_strtolower();
正则表达式在字符串中的应用:
一.正则表达式介绍
正则表达式是用于描述字符排列和匹配模式的一种语法规则,它主要用于字符串的模式分割,匹配,查找及替换操作,在php在正则表
达式一般是由正规字符和一些特殊字符联合构成的一个文本模式的程序性描述,这在儿我们使用perl兼容正则表达式
二.正则表达式语法
1.原子 www.111cn.net
1)单个字符,数字
a-z,A-Z,0-9 a-z其中任意一个字符
2)模式单元
(abc) 匹配abc并且成一个单元
3)原子表
[abc]它中的任意一个字符a或b或c
4)重新使用的模式单元
\1,$1
5)普通转义字符
d,D,w,W,s,S
d 匹配一个数字
D 匹配一个非数字
w 匹配字母,数字,下划线
W 除了字母,数字,下划线
s 匹配空白字符,空格,tab
S 除了空白字符,空格,tab
6)转义元字符
*,. []
2.元字符
*,+,?,|,^,$,b,B,[],[^],{m},{m,n},{m,},(),.
d* 一个或多个或0个数字
d+ 一个或多个数字
d? 一个或0个数字
. 任意一个字符
3.模式修正符
i,m,s,U,e
i 忽略大小写
m 视为多行
s 视为一行
U 贪婪模式,最大模式
e 替换的时候用的,可以用函数加工向后引用\1,$1
三.字符串正则表达式函数
1.字符串的匹配与查找
preg_match()
preg_match_all()
preg_grep()
2.字符串的替换
preg_replace()
//问题:正则e修饰符<>
3.字符串的分割与连接
preg_split()
4.正则表达式的web验证应用
1)电子邮件地址
2)url地址
3)电话号码
ubb编辑器:
[url][/url][b]文字[/b]
相关文章
- eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
- 在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
Python astype(np.float)函数使用方法解析
这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08- 这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 在很多网站用户先访问一个要登录的页面,但当时没有登录后来登录了,等待用户登录成功之后肯定希望返回到上次访问的页面,下面我就来给大家介绍登录后跳转回原来要访问的页...2016-11-25
- 本文章完美的利用了php的curl功能实现模拟登录discuz以及模拟发帖,本教程供参考学习哦。 代码如下 复制代码 <?php $discuz_url = ‘ht...2016-11-25
- CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
- 这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
PHP函数分享之curl方式取得数据、模拟登陆、POST数据
废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07- Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
Ruby on Rails实现最基本的用户注册和登录功能的教程
这里我们主要以has_secure_password的用户密码验证功能为中心,来讲解Ruby on Rails实现最基本的用户注册和登录功能的教程,需要的朋友可以参考下...2020-06-30- PHP 函数 strip_tags 提供了从字符串中去除 HTML 和 PHP 标记的功能,该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。由于 strip_tags() 无法实际验证 HTML,不完整或者破损标签将导致更多的数...2014-05-31
- 分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: /* *功能:对字符串进行加密处理 *参数一:需要加密的内容 *参数二:密钥 */ function passport_encrypt($str,$key){ //加密函数 srand(...2015-10-30
SQL Server中row_number函数的常见用法示例详解
这篇文章主要给大家介绍了关于SQL Server中row_number函数的常见用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08- 什么是SSO?单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护...2015-11-08