工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.wdlinux.cn 注册 | 登陆
浏览模式: 标准 | 列表分类:php

jpgraph

<?php
include ("../jpgraph.php");
include ("../jpgraph_line.php");//将要用于图表创建的数据存放在数组中
$data =array(19,23,34,38,45,67,71,78,85,90,96,145);
$graph = new Graph(500,300);                                                    //创建新的Graph对象
$graph->SetScale("textlin");                                                   //设置刻度样式
$graph->img->SetMargin(30,30,80,30);                    //设置图表边界
$graph->title->Set("CDN TrafficTotal");        //设置图表标题
$graph->title->SetColor("blue");
$graph->title->SetMargin(20); // Create the linear plot
$lineplot=new LinePlot($data);              // 创建新的LinePlot对象
$lineplot->SetLegend("Line(Mbits)");   //设置图例文字
$lineplot->SetColor("red");                 // 设置曲线的颜色 // Add the plot to the graph
$graph->Add($lineplot);                     //在统计图上绘制曲线 // Display the graph
$graph->Stroke();                         //输出图像
?>

 

-----------

$graph = new Graph(300,200,"auto");    
$graph->img->SetMargin(40,30,20,40);
$graph->SetScale("textlin");
$graph->SetShadow();

// Create a bar pot
$bplot = new BarPlot($datay);
$bplot->SetFillColor("orange");
$graph->Add($bplot);

// Display the graph
$graph->Stroke();

 

-------------

JPGRAPH生成统计图

JpGRAPHP下载地址: http://www.aditus.nu/jpgraph/ 有两个版本, 一个适用PHP 4.0, 还有一个适用PHP 5.1 以上的,如果刚好是PHP 5.0.X 的需要升到5.1以上. (我有试过5.0的运行不起来的).

如果你要用到中文, 需要修改一下配置文件 /src/jpgraph.php
替换 $font_family=FF_FONT1 为 $font_family=FF_SIMSUN

如果你设置的文件编码是UTF-8, 就需要修改掉一些文件里面的代码,不然就会乱码
方法1 在文件 /src/jpgraph_ttf.inc.php
注释掉下面这段代码
//    elseif( $aFF === FF_SIMSUN ) {
//        // Do Chinese conversion
//        if( $this->g2312 == null ) {
//        include_once 'jpgraph_gb2312.php' ;
//        $this->g2312 = new GB2312toUTF8();
//        }
//        return $this->g2312->gb2utf8($aTxt);
//    }

方法2 文件jpgraph_gb2312.php
function gb2utf8($gb) { //在此之后直接加上下面这句代码
return $gb

语言包:
windows系统在C:/WINDOWS/Fonts/下有所有的语言包
LINUX系统,是要自己指定路径的 如果出现语言包找不到的情况,可以自己新建一个目录并且把语言文件上传上去,并且修改下 /src/jpgraph.php 文件里定义的语言包路径
if (!defined('TTF_DIR')) {
    if (strstr( PHP_OS, 'WIN') ) {
    $sroot = getenv('SystemRoot');
        if( empty($sroot) ) {
        $t = new ErrMsgText();
        $msg = $t->Get(12,$file,$lineno);
        die($msg);
        }
    else {
      define('TTF_DIR', $sroot.'/fonts/');
        }
    } else {
    define('TTF_DIR','/usr/share/fonts/truetype/');
    //修改这个路径
    }
}

/src/Examples目录下有很多例子,我只画了一个线状图。

 

require_once('include/jpgraph.php'); //Graph类
require_once('include/jpgraph_line.php'); //LinePlot 类
$aAxisType = 'intlin'//第一个int是X轴类型第2个lin是Y轴类型
$yScaleMin = 0//Y轴最小值, 如果不需要设置,可以为空,或者NULL,下同
$yScaleMax = 11//Y轴最大值
$xScaleMin = 1//X轴最大值
$xScaleMax = 24//X轴最大值

$unitType = '月份';

  
$chartDataTmpArr = array('1' => '1', '2' => '0', '3' => '4', '4' => '5', '5' => '7', '6' => '8', '7' => '4', '8' => '6', '9' => '8', '10' => '7', '11' => '4', '12' => '5', '13' => '4', '14' => '6', '15' => '4', '16' => '2', '17' => '2', '18' => '2', '19' => '2', '20' => '7', '21' => '6', '22' => '1', '23' => '4', '24' => '4');

$chartDataTmpArr2 = array('1' => '2', '2' => '0', '3' => '2', '4' => '2', '5' => '8', '6' => '9', '7' => '5', '8' => '7', '9' => '9', '10' => '7', '11' => '4', '12' => '7', '13' => '2', '14' => '4', '15' => '5', '16' => '6', '17' => '0', '18' => '3', '19' => '6', '20' => '5', '21' => '8', '22' => '9', '23' => '4', '24' => '4');
$graph = new Graph($width = 780 , $height = 400); //创建新的Graph对象
$graph->SetScale($aAxisType, $yScaleMin, $yScaleMax, $xScaleMin, $xScaleMax); //设置刻度模式SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1)

$graph->img->SetMargin(40, 20, 50, 50) ; //设置图表边界
$title = date("Y-m-d H:i:s")."统计图";
$graph->title->SetFont(FF_SIMSUN,FS_BOLD); //设置图表标题的字体类型
$graph->title->Set($wholeTitle);
$graph->title->SetMargin (20);

$graph->xaxis->title->SetFont(FF_SIMSUN);
$graph->xaxis->title->Set($unitType);
$graph->xaxis->title->SetMargin(14);

$graph->legend->SetLineWeight(2); //设置图例文字的字体 

$lineplot = new LinePlot($chartDataTmpArr); //创建要画的一地条曲线的对象
$lineplot->SetWeight(2); //曲线的线宽

$lineplot->SetLegend("进入");//设置图例文字
$graph->legend->Pos0.025, 0.08, "right","center" ); //图例文字框的位置 0.025,0.08 是以右上角为基准的,0.025是距左右距离,0.08是上下距离。
$graph->legend->SetLayout('1'); //如果有两条曲线,他们的图例文字并排放置。
$graph->legend->SetFrameWeight(0); //图例文字外框边框border设置为0
$graph->legend->SetFillColor('#C8C8C8'); //图例文字框内的填充颜色
$graph->legend->SetShadow('#C8C8C8', 0); //设置图例文字框的阴影部分颜色和border
$lineplot->SetColor("orange"); //设置曲线颜色
$graph->Add($lineplot); //在统计图上绘制曲线
    
$lineplot2 = new LinePlot($chartDataTmpArr2); //创建一条新的曲线对象
$lineplot2->SetLegend("出去");
$lineplot2->SetWeight(2);
$lineplot2->SetColor("blue"); 
$graph->Add($lineplot2);

$filename = 'images/strock/'.time().'.png';
$graph->Stroke($filename);

/*如果这里直接调用Stroke()函数,图片会从cache里直接输出,但是有个问题,网页上只能为这个曲线图输出,

别的内容在这个曲线图之前输出就会出错。别的内容放在这个曲线图之后都没输出了。

所以需要传递一个文件名,这样在本地就会存储内容。*/

echo '<img src="'.$filename.'" />';

/* 存放图片的文件夹会有比较多的图片,如果是LINUX服务器的话可以设置一个cronjob,定时清空下图片。

还有另一种方法 比如画图文件为 drawImage.php 可以用另一个文件viewImage.php以内容<img src ="drawImage.php" /> 的方法把图片载入进来,这样可以不用生成图片文件, 

而且图片显示位置可以随便放. 不过这样做是有问题的,比如说他要载入的数据是动态的, 

那就没办法把那么一大串的数组也都穿进去. 或许可以用serialize 函数来处理一堆的数据,

再在drawImage.php中用unserialize函数还原数据.没试过. */

php编译时出libiconv错

/root/php-5.2.12/ext/iconv/iconv.c:2615: undefined reference to `libiconv'
/root/php-5.2.12/ext/iconv/iconv.c:2615: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o:/root/php-5.2.12/ext/iconv/iconv.c:2537: more undefined references to `libiconv' follow
ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_ctor':
/root/php-5.2.12/ext/iconv/iconv.c:2491: undefined reference to `libiconv_open'
ext/xmlrpc/libxmlrpc/.libs/encodings.o: In function `convert':
/root/php-5.2.12/ext/xmlrpc/libxmlrpc/encodings.c:73: undefined reference to `libiconv_open'
/root/php-5.2.12/ext/xmlrpc/libxmlrpc/encodings.c:81: undefined reference to `libiconv'
/root/php-5.2.12/ext/xmlrpc/libxmlrpc/encodings.c:101: undefined reference to `libiconv_close'
collect2: ld returned 1 exit status
make: *** [sapi/cli/php] ?.. 1
 
 
处理方法:
./configure ............
 
vi Makefile
找到下面这行:
EXTRA_LIBS = -lcrypt ...
在最后添加-liconv
保存后make通过;make install通过。

php绘图库jpgraph

 jpgraph这个强大的绘图组件能根据你的需要画出任意图形,甚至"aleax的网站访问量统计图"这种也相当简单好画.只要你能提供数据,它就能画图.  简单的说, 画图就像你刚学数据结构时候编写的一些处理数据算法, 而这里只是多了几个调用绘图函数的过程来把处理的数据填进去自动画图.

  除了简单易用, 它还有一个好处: 支持中文。

  先到官方网站下载相应的库,注意有支持php4.*和php5.*两种版本的, 选择合适你的下载,然后先了解一下文件的组织结构最上层目录有doc 和 src 两个文件夹, doc 里面是文档和类库说明, src 是一些配置文件和绘制某一 "图元" 的php文件,注意,我说的"图元"的意思就是它们是一张图的基本组成部分,你完全可以自由组合画出复杂的图形。 src里还有一个example文件夹, 里面有几百个例子,都是相当简单的,我们完全可以不必看文档只要模仿里面的例子就可以快速画出图来。 运行几个图形,挑几个能抓住你眼睛的图形,看一下代码,组合一下功能,就出来了,画图简单到只要五分钟,中文支持就更简单了,内置支持simsun字附,在要图上写中文时SetFont(FF_SIMSUN,FS_BOLD) 就可以了.

  下面是我组合的一个例子,代码很简单,因为数据我没有处理, 这里只演示画图的功能代码 , 当然,填充的数据是很灵活的,可以来自数据库,可以由你重新写算法处理,X轴显示的数据也一样,至于画曲线图,柱图,饼图,还是混合图,就随你选了

    include ("date/jpgraph.php");
    include ("date/jpgraph_line.php");
    include ("date/jpgraph_error.php");
    $datay = array(1,3,13,5,8,6,17,21,15,7,4,1); //填充的数据  
    $graph = new Graph(400,200,"auto");
    $graph->img->SetMargin(35,35,35,35);  
    $graph->img->SetAntiAliasing();
    $graph->SetScale("textlin");
    $graph->SetShadow();
    $graph->title->Set("**曲线图");
    $graph->xaxis->title->Set("$year");
    $graph->xaxis->title->SetFont(FF_SIMSUN,FS_BOLD);
    $graph->yaxis->title->Set("身高(cm)");
    $graph->SetMarginColor("lightblue");
    $graph->yaxis->title->SetFont(FF_SIMSUN,FS_BOLD);
    $graph->title->SetFont(FF_SIMSUN,FS_BOLD);
    $graph->xaxis->SetPos("min");
    $graph->yaxis->HideZeroLabel();
    $graph->ygrid->SetFill(true,'#EFEFEF@0.5','#BBCCFF@0.5');
    $a=array("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");//X轴
    $graph->xaxis->SetTickLabels($a);
    $graph->xaxis->SetFont(FF_SIMSUN);
    $graph->yscale->SetGrace(20);    
    $p1 = new LinePlot($datay);
    $p1->mark->SetType(MARK_FILLEDCIRCLE);
    $p1->mark->SetFillColor("red");
    $p1->mark->SetWidth(4);
    $p1->SetColor("blue");
    $p1->SetCenter();
    $graph->Add($p1);
    $graph->Stroke();

http://tech.ddvip.com/2008-10/122449617280389.html

 

-------------------

比如我想让x轴标上time,y轴标上flux

$g   =   new   Graph(500,400);
$g-> xaxis-> title-> Set( "time ");
$g-> yaxis-> title-> Set( "flux ");

 

--------------------

http://www.docin.com/p-113240144.html

http://www.leapsoul.cn/?p=1367

Cookie与Session结合的一个初始化简例

看到这几天问有关Session为何无法使用的帖子比较多,我把我一直用的一段Session初始化代码发出来给大家参考一下。再每个页面头部引入这段代码,就可以直接使用$_SESSION存储数据

$sessionId session_id();              //尝试获取由PHP自身获得的SessionID(来源途径有URL或Cookie)

if(empty($sessionId) || preg_match('/[^A-Za-z0-9]/i'$sessionId)) {    //检查此ID是否合法

          
$sessionId $_COOKIE['PHPSESSID'];          //如ID不合法尝试从Cookie中获取

}

if(empty(
$sessionId) || preg_match('/[^A-Za-z0-9]/i'$sessionId)) { //再次检查ID是否合法

          
$sessionId md5(microtime());         //如还未有合法ID则生成一个

}

session_id($sessionId);         //使用新生成的ID(或者原先取到的合法ID)

session_start();              //启动Session

setcookie('PHPSESSID'$sessionIdtime() + 180);    //设置Session有效期(180秒)

http://bbs.phpchina.com/viewthread.php?tid=78712

file_get_contents超时问题及解决方案

经常会使用php中的file_get_contents()函数去抓取远程页面, 对方页面文件过大、对方页面反应时间太久或网络传输慢等原因都可能会导致file_get_contents()执行时间超过php的最大执行时间。而一 旦file_get_contents出错即会终止整个程序。

测试用例

 

?
1
2
3
4
5
6
7
8
<?php
  
ini_set("max_execution_time", 2);
$url = "http://aymoo.cn/files/jQuery1.2API.chm";
$html = file_get_contents($url);
var_dump($html);
  
?>

 

上面代码首先将php的最大执行时间设置为2秒,然后去远程读取170KB的文件,按照本人的网络环境下载170KB文件需时超过1s.

 

现象

Fatal error: Maximum execution time of 2 second exceeded in C:\wamp\www\phptest\timeout.php on line 4

这是由网络造成的php执行超时,在file_get_contents超时时即报错并且程序停止执行。而基本上大多数需求是即使发生错误也要求程序继续向下执行。

解决办法

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
ini_set("max_execution_time", 2);
$url = "http://aymoo.cn/files/jQuery1.2API.chm";
//$html = file_get_contents($url);
   
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec($ch);
curl_close ($ch);
   
var_dump($html);
?>

现象

bool(false)

成功解决了超时导致程序不能继续执行的问题。

这里需要注意的是,设置curl的CURLOPT_TIMEOUT的值应该小于php最大执行时间。

为什么要说应该而不是必须?用两个例子对比来说明,假设抓取页面需4s。

example 1
max_execution_time 为 2
CURLOPT_TIMEOUT 为 3

example 2
max_execution_time 为 10
CURLOPT_TIMEOUT 为 20

我对这个过程的理解是,php监控整个脚本的时间,curl监控抓取页面的时间。对例1, 抓取远程页面的过程中已经达到php最大执行时间,得到的结果和file_get_contents一样。
例2中,整个脚本的执行时间不到5s, 所以不受设定时间的限制.

 

-------------------------------------------

 

一、增加超时的时间限制
这里需要注意:set_time_limit只是设置你的PHP程序的超时时间,而不是file_get_contents函数读取URL的超时时间。
我一开始以为set_time_limit也能影响到file_get_contents,后来经测试,是无效的。真正的修改file_get_contents延时可以用resource $context的timeout参数:

复制代码 代码如下:
$opts = array(
‘http'=>array(
‘method'=>”GET”,
‘timeout'=>60,
)
);
$context = stream_context_create($opts);
$html =file_get_contents('http://www.example.com', false, $context);
fpassthru($fp);

二、一次有延时的话那就多试几次
有时候失败是因为网络等因素造成,没有解决办法,但是可以修改程序,失败时重试几次,仍然失败就放弃,因为file_get_contents()如果失败将返回 FALSE,所以可以下面这样编写代码:

复制代码 代码如下:
$cnt=0;
while($cnt < 3 && ($str=@file_get_contents('http…'))===FALSE) $cnt++;

PHP cookie和session的分析

cmpan(at)qq.com
流水孟春
lib.cublog.cn

转载请注


1. PHPCOOKIE

cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。
PHP
http协议的头信息里发送cookie, 因此 setcookie() 函数必须在其它信息被输出到浏览器前调用,这和对 header() 函数的限制类似。

1.1
设置cookie:
   
可以用 setcookie() setrawcookie() 函数来设置 cookie。也可以通过向客户端直接发送http头来设置.
1.1.1
使用setcookie()函数设置cookie:
bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, bool secure [, bool httponly]]]]]] )
    
name:   cookie
变量名
     value:   cookie
变量的值
     expire: 
有效期结束的时间,
     path:   
有效目录,
     domain:
有效域名,顶级域唯一
     secure: 
如果值为1,cookie只能在https连接上有效,如果为默认值0,httphttps都可以.
例子:
<?php
$value = 'something from somewhere';

setcookie("TestCookie", $value); /* 简单cookie设置 */
setcookie("TestCookie", $value, time()+3600); /* 有效期1个小时 */
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1); /* 有效目录 /~rasmus,有效域名example.com及其所有子域名 */
?>

设置多个cookie变量: setcookie('var[a]','value');用数组来表示变量,但他的下标不用引号.这样就可以用$_COOKIE[‘var’][‘a’]来读取该COOKIE变量.

1.1.2.
使用header()设置cookie;
header("Set-Cookie: name=$value[;path=$path[;domain=xxx.com[;...]]");
后面的参数和上面列出setcookie函数的参数一样.
比如:

$value = 'something from somewhere';
header("Set-Cookie:name=$value");

1.2 Cookie的读取:

直接用php内置超级全局变量 $_COOKIE就可以读取浏览器端的cookie.
上面例子中设置了cookie"TestCookie",现在我们来读取:

print $_COOKIE['TestCookie'];

COOKIE是不是被输出了?!

1.3 删除cookie
只需把有效时间设为小于当前时间, 和把值设置为空.例如:
setcookie("name","",time()-1);
header()类似.

1.4 常见问题解决:

1) 用setcookie()时有错误提示,可能是因为调用setcookie()前面有输出或空格.也可能你的文档使从其他字符集转换过来,文档后面可能带有BOM签名(就是在文件内容添加一些隐藏的BOM字符).解决的办法就是使你的文档不出现这种情况.还有通过使用ob_start()函数有也能处理一点.
2) $_COOKIEmagic_quotes_gpc影响,可能自动转义
3) 使用的时候,有必要测试用户是否支持cookie
<!--[if !supportLineBreakNewLine]-->

1.5 cookie工作机理:

有些学习者比较冲动,没心思把原理研究,所以我把它放后面.
a) 服务器通过随着响应发送一个
httpSet-Cookie,在客户机中设置一个cookie(多个cookie要多个头).
b) 客户端自动向服务器端发送一个httpcookie,服务器接收读取.

HTTP/1.x 200 OK
X-Powered-By: PHP/5.2.1
Set-Cookie: TestCookie=something from somewhere; path=/
Expires: Thu, 19 Nov 2007 18:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-type: text/html

这一行实现了cookie功能,收到这行后
Set-Cookie: TestCookie=something from somewhere; path=/
浏览器将在客户端的磁盘上创建一个cookie文件,并在里面写入:

TestCookie=something from somewhere;
/

这一行就是我们用setcookie('TestCookie','something from somewhere','/');的结果.也就是用header('Set-Cookie: TestCookie=something from somewhere; path=/');的结果.
<!--[endif]-->




2. PHPSession

session使用过期时间设为0cookie,并且将一个称为session ID的唯一标识符(一长串字符串),在服务器端同步生成一些session文件(可以自己定义session的保存类型),与用户机关联起来.web应用程序存贮与这些session相关的数据,并且让数据随着用户在页面之间传递.

访问网站的来客会被分配一个唯一的标识符,即所谓的会话 ID。它要么存放在客户端的 cookie,要么经由 URL 传递。

会话支持允许用户注册任意数目的变量并保留给各个请求使用。当来客访问网站时,PHP 会自动(如果 session.auto_start 被设为 1)或在用户请求时(由 session_start() 明确调用或 session_register() 暗中调用)检查请求中是否发送了特定的会话 ID。如果是,则之前保存的环境就被重建。

2.1 sessionID的传送

2.1.1 通过cookie传送sessin ID

     使用session_start()调用session,服务器端在生成session文件的同时,生成session ID哈希值和默认值为PHPSESSID的session name,并向客户端发送变量为(默认的是)PHPSESSID(session name),值为一个128位的哈希值.服务器端将通过该cookie与客户端进行交互.
   session变量的值经php内部系列化后保存在服务器机器上的文本文件中,和客户端的变量名默认情况下为
PHPSESSID的coolie进行对应交互.
     即服务器自动发送了http头:header('Set-Cookie: session_name()=session_id(); path=/');
setcookie(session_name(),session_id());
   
当从该页跳转到的新页面并调用session_start(),PHP将检查与给定ID相关联的服务器端存贮的session数据,如果没找到,则新建一个数据集.

2.1.2
通过URL传送session ID
只有在用户禁止使用cookie的时候才用这种方法,因为浏览器cookie已经通用,为安全起见,可不用该方法.
<a href="p.php?<?php print
session_name() ?>=<?php print session_id() ?>">xxx</a>,也可以通过POST来传递session值.

2.2 session基本用法实例

<?php
// page1.php
session_start();
echo 'Welcome to page #1';
/* 创建session变量并给session变量赋值 */
$_SESSION['favcolor'] = 'green';
$_SESSION['animal'] = 'cat';
$_SESSION['time'] = time();

// 如果客户端使用cookie,可直接传递session到page2.php
echo '<br /><a href="page2.php">page 2</a>';

// 如果客户端禁用cookie
echo '<br /><a href="page2.php?' . SID . '">page 2</a>';
/*
 默认php5.2.1下,SID只有在cookie被写入的同时才会有值,如果该session
 对应的cookie已经存在,那么SID将为(未定义)空
 */

?>

<?php
// page2.php
session_start();
print $_SESSION['animal']; // 打印出单个session
var_dump($_SESSION); // 打印出page1.php传过来的session值
?>


2.3 使用session函数控制页面缓存.
    很多情况下,我们要确定我们的网页是否在客户端缓存,或要设置缓存的有效时间,比如我们的网页上有些敏感内容并且要登录才能查看,如果缓存到本地了,可以直接打开本地的缓存就可以不登录而浏览到网页了.

    使用session_cache_limiter('private');可以控制页面客户端缓存,必须在session_start()之前调用.
更多参数见http://blog.chinaunix.net/u/27731/showart.php?id=258087的客户端缓存控制.

    
控制客户端缓存时间 session_cache_expire(int);单位(s).也要在session_start()前调用.

    这只是使用session的情况下控制缓存的方法,我们还可以在header()中控制控制页面的缓存.

2.4 删除session

要三步实现.
<?php
session_destroy();                                      // 第一步: 删除服务器端session文件,这使用
setcookie(session_name(),'',time()-3600);  // 第二步: 删除实际的session:
$_SESSION = array();                                  // 第三步: 删除$_SESSION全局变量数组
?>

2.5 sessionPHP大型web应用中的使用

对于访问量大的站点,用默认的session存贮方式并不适合,目前最优的方法是用数据库存取session.这时,函数bool session_set_save_handler ( callback open, callback close, callback read, callback write, callback destroy, callback gc )就是提供给我们解决这个问题的方案.
该函数使用的6个函数如下:

1.   bool open() 用来打开会话存储机制,

2.   bool close() 关闭会话存储操作.

3.  mixde read() 从存储中装在session数据时使用这个函数

4.   bool write() 将给定session ID的所有数据写到存储中

5.   bool destroy() 破坏与指定的会话ID相关联的数据

6.   bool gc()  对存储系统中的数据进行垃圾收集

例子见php手册session_set_save_handler() 函数.
如果用类来处理,
session_set_save_handler(
    array('className','open'),
    array('className','close'),
    array('className','read'),
    array('className','write'),
    array('className','destroy'),
    array('className','gc'),
)
调用className类中的6个静态方法.className可以换对象就不用调用静态方法,但是用静态成员不用生成对象,性能更好.

2.6 常用session函数:

bool   session_start(void); 初始化session
bool   session_destroy(void)
: 删除服务器端session关联文件
string session_id()
当前sessionid
string session_name()
当前存取的session名称,也就是客户端保存session IDcookie名称.默认PHPSESSID
array  session_get_cookie_params()
与这个session相关联的session的细节.
string session_cache_limiter()
控制使用session的页面的客户端缓存
ini    session_cache_expire()
控制客户端缓存时间
bool   session_destroy()    
删除服务器端保存session信息的文件
void   session_set_cookie_params ( int lifetime [, string path [, string domain [, bool secure [, bool httponly]]]] )设置与这个session相关联的session的细节
bool session_set_save_handler ( callback open, callback close, callback read, callback write, callback destroy, callback gc )定义处理session的函数,(不是使用默认的方式)
bool session_regenerate_id([bool delete_old_session]) 分配新的session id


2.7 session安全问题
攻击者通过投入很大的精力尝试获得现有用户的有效会话ID,有了会话id,他们就有可能能够在系统中拥有与此用户相同的能力.
因此,我们主要解决的思路是效验session ID的有效性.

<?php

if(!isset($_SESSION['user_agent'])){
    $_SESSION['user_agent'] = $_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'];
}

/* 如果用户session ID是伪造 */
elseif ($_SESSION['user_agent'] != $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']) {
   
session_regenerate_id();
}
?>


2.8 Session
通过cookie传递和通过SID传递的不同:
php5.2.1session的默认配置的情况下,当生成session的同时,服务器端将在发送header set-cookie同时生成预定义超级全局变量SID(也就是说,写入cookie和抛出SID是等价的.),$_COOKIE['PHPSESSID']存在以后,将不再写入cookie,也不再生成超级全局变量SID,此时,SID将是空的.



2.9 session使用实例

<?php
/**
 * 效验session的合法性
 *
 */

function sessionVerify() {
    if(!isset($_SESSION['user_agent'])){
        $_SESSION['user_agent'] = MD5($_SERVER['REMOTE_ADDR']
        .$_SERVER['HTTP_USER_AGENT']);
    }
    /* 如果用户session ID是伪造,则重新分配session ID */
    elseif ($_SESSION['user_agent'] != MD5($_SERVER['REMOTE_ADDR']
    . $_SERVER['HTTP_USER_AGENT'])) {
        session_regenerate_id();
    }
}

/**
 * 销毁session
 * 三步完美实现,不可漏
 *
 */

function sessionDestroy() {
    session_destroy();
    setcookie(session_name(),'',time()-3600);
    $_SESSION = array();
}
?>

 

注明:

    session 出现头信息已经发出的原因与cookie一样.
    在php5中,所有php session 的注册表配置选项都是编程时可配置的,一般情况下,我们是不用修改其配置的.要了解php的session注册表配置选项,请参考手册的Session 会话处理函数处.

 
 
 
 
      session的保存数据的时候,是通过系列化$_SESSION数组来存贮,所以有系列化所拥有的问题,可能有特殊字符的值要用base64_encode函数编码,读取的时候再用base64_decode解码

简述Session与Cookie区别

Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。

服务器也可以通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。

可以试一下,即使不写Cookie,在使用request.getCookies();取出的Cookie数组的长度也是1,而这个Cookie的名字就是
JSESSIONID
,还有一个很长的二进制的字符串,是SessionID的值。

Cookie是客户端的存储空间,由浏览器来维持。

在一些投票之类的场合,我们往往因为公平的原则要求每人只能投一票,在一些WEB开发中也有类似的情况,这时候我们通常会使用COOKIE来实现,例如如下的代码:
< % cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null)
  doStuffForNewbie();
//没有访问过  
}

else
{
  doStuffForReturnVisitor(); //已经访问过了
}

% >



      这是很浅显易懂的道理,检测COOKIE的存在,如果存在说明已经运行过写入COOKIE的代码了,然而运行以上的代码后,无论何时结果都是执行doStuffForReturnVisitor(),通过控制面板-Internet选项-设置-察看文件却始终看不到生成的cookie文件,奇怪,代码明明没有问题,不过既然有cookie,那就显示出来看看。
cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null)
  out.println("Has not visited this website");
}

else
{
  for (int i = 0; i < cookie.length; i++)
  {
    out.println("cookie name:" + cookies[i].getName() + "cookie value:" +
        cookie[i].getValue());
  }
}


        运行结果:
cookie name:JSESSIONID cookie value:KWJHUG6JJM65HS2K6

为什么会有cookie呢,大家都知道,http是无状态的协议,客户每次读取web页面时,服务器都打开新的会话,而且服务器也不会自动维护客户的上下文信息,那么要怎么才能实现网上商店中的购物车呢,session就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过SessionID来区分不同的客户,session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,我们叫做session cookie,以区别persistent cookies,也就是我们通常所说的cookie,注意session cookie是存储于浏览器内存中的,并不是写到硬盘上的,这也就是我们刚才看到的JSESSIONID,我们通常情是看不到JSESSIONID的,但是当我们把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,我们就可以在地址栏看到sessionid=KWJHUG6JJM65HS2K6之类的字符串。
        明白了原理,我们就可以很容易的分辨出persistent cookies和session cookie的区别了,网上那些关于两者安全性的讨论也就一目了然了,session cookie针对某一次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本(通常是加密的),而且可能会遭到cookie欺骗以及针对cookie的跨站脚本攻击,自然不如session cookie安全了。
        通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到了,此时我们可以先把sessionid保存在persistent cookie中,然后在新窗口中读出来,就可以得到上一个窗口SessionID了,这样通过session cookie和persistent cookie的结合我们就实现了跨窗口的session tracking(会话跟踪)。
        在一些web开发的书中,往往只是简单的把Session和cookie作为两种并列的http传送信息的方式,session cookies位于服务器端,persistent cookie位于客户端,可是session又是以cookie为基础的,明白的两者之间的联系和区别,我们就不难选择合适的技术来开发web service了。

Records:71123456789