Posts Tagged ‘ PHP

php关于任意文件下载

//文档类型对照表
$filetype = array(
'chm'=>‘application/octet-stream’,
‘ppt’=>’application/vnd.ms-powerpoint’,
‘xls’=>’application/vnd.ms-excel’,
‘doc’=>’application/msword’,
‘exe’=>’application/octet-stream’,
‘rar’=>’application/octet-stream’,
‘js’=>”javascript/js”,
‘css’=>”text/css”,
‘hqx’=>”application/mac-binhex40″,
‘bin’=>”application/octet-stream”,
‘oda’=>”application/oda”,
‘pdf’=>”application/pdf”,
‘ai’=>”application/postsrcipt”,
‘eps’=>”application/postsrcipt”,
‘es’=>”application/postsrcipt”,
‘rtf’=>”application/rtf”,
‘mif’=>”application/x-mif”,
‘csh’=>”application/x-csh”,
‘dvi’=>”application/x-dvi”,
‘hdf’=>”application/x-hdf”,
‘nc’=>”application/x-netcdf”,
‘cdf’=>”application/x-netcdf”,
‘latex’=>”application/x-latex”,
‘ts’=>”application/x-troll-ts”,
‘src’=>”application/x-wais-source”,
‘zip’=>”application/zip”,
‘bcpio’=>”application/x-bcpio”,
‘cpio’=>”application/x-cpio”,
‘gtar’=>”application/x-gtar”,
‘shar’=>”application/x-shar”,
‘sv4cpio’=>”application/x-sv4cpio”,
‘sv4crc’=>”application/x-sv4crc”,
‘tar’=>”application/x-tar”,
‘ustar’=>”application/x-ustar”,
‘man’=>”application/x-troff-man”,
‘sh’=>”application/x-sh”,
‘tcl’=>”application/x-tcl”,
‘tex’=>”application/x-tex”,
‘texi’=>”application/x-texinfo”,
‘texinfo’=>”application/x-texinfo”,
‘t’=>”application/x-troff”,
‘tr’=>”application/x-troff”,
‘roff’=>”application/x-troff”,
‘shar’=>”application/x-shar”,
‘me’=>”application/x-troll-me”,
‘ts’=>”application/x-troll-ts”,
‘gif’=>”image/gif”,
‘jpeg’=>”image/pjpeg”,
‘jpg’=>”image/pjpeg”,
‘jpe’=>”image/pjpeg”,
‘ras’=>”image/x-cmu-raster”,
‘pbm’=>”image/x-portable-bitmap”,
‘ppm’=>”image/x-portable-pixmap”,
‘xbm’=>”image/x-xbitmap”,
‘xwd’=>”image/x-xwindowdump”,
‘ief’=>”image/ief”,
‘tif’=>”image/tiff”,
‘tiff’=>”image/tiff”,
‘pnm’=>”image/x-portable-anymap”,
‘pgm’=>”image/x-portable-graymap”,
‘rgb’=>”image/x-rgb”,
‘xpm’=>”image/x-xpixmap”,
‘txt’=>”text/plain”,
‘c’=>”text/plain”,
‘cc’=>”text/plain”,
‘h’=>”text/plain”,
‘html’=>”text/html”,
‘htm’=>”text/html”,
‘htl’=>”text/html”,
‘rtx’=>”text/richtext”,
‘etx’=>”text/x-setext”,
‘tsv’=>”text/tab-separated-values”,
‘mpeg’=>”video/mpeg”,
‘mpg’=>”video/mpeg”,
‘mpe’=>”video/mpeg”,
‘avi’=>”video/x-msvideo”,
‘qt’=>”video/quicktime”,
‘mov’=>”video/quicktime”,
‘moov’=>”video/quicktime”,
‘movie’=>”video/x-sgi-movie”,
‘au’=>”audio/basic”,
‘snd’=>”audio/basic”,
‘wav’=>”audio/x-wav”,
‘aif’=>”audio/x-aiff”,
‘aiff’=>”audio/x-aiff”,
‘aifc’=>”audio/x-aiff”,
‘swf’=>”application/x-shockwave-flash”);

$filepath = ‘http://www.wemvc.com/logo.jpg’;
$filename = ‘logo.jpg’;
$filetype = $filetype['jpg'] ;

$query = file_get_contents($filepath);

header(“Content-type: “.$filetype);
header(“Content-Disposition: inline; filename = “.$filename);
header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0′);
header(‘Expires: 0′);
header(‘Pragma: public’);
echo $query;
?>

PHP一维、二维以及多维的数组排序方法

1、一维数组排序

a、sort–本函数对数组进行排序。当本函数结束时数组单元将被从最低到最高重新安排。注:本函数为 array 中的单元赋予新的键名。这将删除原有的键名而不仅是重新排序

<?php
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
foreach ($fruits as $key => $val) {
    echo "fruits[".$key."] = " . $val . "\n";
}
?>

上例将输出:
# fruits[0] = apple
# fruits[1] = banana
# fruits[2] = lemon
# fruits[3] = orange

b、asort — 对数组进行排序并保持索引关系。本函数对数组进行排序,数组的索引保持和单元的关联。主要用于对那些单元顺序很重要的结合数组进行排序。

<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
arsort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

上例将输出:
a = orange
d = lemon
b = banana
c = apple

2、多维数组排序

<?php
$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);
?>

本例中将把 volume 降序排列,把 edition 升序排列

现在有了包含有行的数组,但是 array_multisort() 需要一个包含列的数组,因此用以下代码来取得列,然后排序

<?php
// 取得列的列表
foreach ($data as $key => $row) {
    $volume[$key]  = $row['volume'];
    $edition[$key] = $row['edition'];
}

// 将数据根据 volume 降序排列,根据 edition 升序排列
// 把 $data 作为最后一个参数,以通用键排序
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
?>

数据集合现在排好序了,结果如下:
volume | edition
——-+——–
98 | 2
86 | 1
86 | 6
85 | 6
67 | 2
67 | 7

你或许尚未了解PHP的那10件事情

1.使用 ip2long() 和 long2ip() 函数来把 IP 地址转化成整型存储到数据库里。这种方法把存储空间降到了接近四分之一(char(15) 的 15 个字节对整形的 4 个字节),计算一个特定的地址是不是在一个区段内页更简单了,而且加快了搜索和排序的速度(虽然有时仅仅是快了一点)。

2.在验证 email 地址的时候使用 checkdnsrr() 函数验证域名是否存在。这个内置函数能够确认指定的域名能够解析成 IP 地址。该函数的PHP 文档的用户评论部分有一个简单的用户自定义函数,这个函数基于 checkdnsrr(),用来验证 email 地址的合法性。对于那些认为自己的 email 地址是 “joeuser@wwwphp.net” 而不是 “joeuser@php.net” 的家伙们,这个方法可以很方便的抓住他们。

3.如果你使用的是 PHP 5 和 MySQL 4.1 或者更高的版本,考虑抛弃 mysql_* 系列函数改用改进版的 mysqli_* 系列函数。一个很好的功能就是你可以使用预处理语句,如果你在维护一个数据库密集型站点,这个功能能够加快查询速度。一些评估分数。

4.学会爱上三元运算符。

5.如果你在项目中感觉到有可复用的部分,在你写下一行代码前先看看 PEAR 中是否已经有了。很多 PHP 程序员都知道 PEAR 是一个很好的资源库,虽然还有很多程序员不知道。这个在线资源库包含了超过 400 个可以复用的程序片段,这些程序片段你可以立即用刀你的程序里。除非说你的项目真的是非常特别的,你总能找到帮你节省时间的 PEAR 包。(参见 PECL)

6.用 highlight_file() 来自动的打印出格式化的很漂亮的源代码。如果你在留言板、IRC 这些地方寻求一个脚本的帮助的话,这个函数用起来非常的顺手。当然了,要小心不要意外的泄露出你的数据库连接信息和密码等。

7.使用 error_reporting(0) 函数来防止用户看到潜在的敏感错误信息。]在理想情况下,发布服务器应该在 php.ini 里完全禁止。但是如果你用的是一个共享的 web 服务器的话,你没有自己的 php.ini 文件,那么这种情况下你最好的选择就是在所有脚本的第一行前加上 error_reporting(0);(或者使用 require_once() 方法)。这就能够在出错的时候完全屏蔽敏感的 SQL 查询语句和路径名。

8.在网数据库中存储很大的字符串之前使用 gzcompress() 和 gzuncompress() 来显式的压缩/解压字符串。这个 PHP 内置函数使用 gzip 算法,可以压缩普通文本达 90%。在我每次要读写 BLOB 类型的字段的时候都使用这些函数。唯一额例外就是当我需要全文检索的时候。

9.通过“引用”传递参数的方法从一个函数中得到多个返回值。就像三元运算符一样,大部分受过正式编程训练的程序员都知道这个技巧。但是那些 HTML 背景大于 Pascal 背景的程序员都或多或少的有过这样的疑问“在仅能使用一次 return 的情况下,从一个函数里返回多个值?”答案就是在变量前加上一个 “&” 符号,通过“引用”传递而非“值”传递。

10.完全理解“魔术引号”和 SQL 注入的危险性。我希望阅读到这里的开发者都已经很对 SQL 注入和了解了。不过我还是把这条列在这里,是因为这个确实有点难以理解。如果你还没有听说过这种说法,那么把今天剩下的时间都用来 Google、阅读吧。

php面向对象详解

面向对象 对象概念是面向对象技术的核心。在显示世界里我们所面对的事情都是对象,如计算机、电视机、自行车等。在面向对象的程序设计中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象.

对象的主要三个特性
对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为。
对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型。
对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同。

面向对象模型

面向对象的概念:
oop(面向对象的编程)它能是其代码更加简洁易于维护并且具有更强的可重性

什么是类:
类是具有相同属性和服务的一组对象的集合比如说人,书,轮船,车都属于类,他为属于该类的对象做了一个统一的抽象描述,在编程的语言中类是一个单独的程序,它应该有一个类名包括属性的说明和服务两个部分。
什么是对象:
对象是系统中描述客观事件的一个实体,他是构成系统的一个基本单位。*数据与代码都被捆绑在一个实体当中*,一个对象由一组属性和对这组属性进行操作的一组行为组成。
从抽象的角度来说,对象是问题域或实现域中某些事物的一个抽象。他反映该事物在系统中保存的信息和发挥的作用:它是一组属性和有权对这些属性进行操作的一个封装体。客观世界是由对象和对象之间的联系组成的。
类和对象的关系:
类与对象的关系就如模具和铸件的关系,类的实力化的结果就是对象,而对对象的抽象就是类,类描述了一组有相同特性(属性)和相同行为的对象。

类与属性和方法
PHP中定义类语法格式:
class classname [可选属性]{
public $property [=value];... //用public声明一个公共标识 然后给予一个变量 变量也可以赋值
function functionname ( args ){ //类的方法里的成员函数
代码} ...
//类的方法(成员函数)
}

生成对象(类的实例化): $对象名=new classname( );
使用对象的属性
在一个类中,可以访问一个特殊指针$this当在该类中通过一个操作设置或访问该变量时,使用$this->name来引用.
对象的生成
定义好类后用一个new来声明,由于对象资料的封装特性,对象是无法由主程序区块直接访问的须通过对象来调用类中所定义的属性和行为函数,间接地达成存取控制类中资料的目的。
对象和类的关系
对象和类的关系:
对象是实际存在的,占有动态资源。
类是对象的蓝图,可能占有静态资源。
对象属性占有动态资源
类(静态)属性实际上是有类名字空间上的“全局变量”
性能考虑:
每个对象要单独占用数据空间
增加的调用层次可能消耗执行时间
方法的参数形式和传递方式
方法的参数可以是基本数据类型、数组和类对象。
基本数据类型:值参传递
数组:值参传递
类对象:引用传递
构造函数
构造函数是在类中起到初始化的作用
构造函数的生成方法与其他函数一样只是其名称必须是__construct().
语法格式:function __construct(参数){
。。。。。。。。
}
范例:
class Person{
public $name;
public $sex;
public $age;
function __construct($name,$sex,$age){
echo "我是构造函数&lt;br&gt;";
$this-&gt;name=$name;
$this-&gt;sex=$sex;
$this-&gt;age=$age;
}

输出结果:初始化
析构函数
当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。应在退出前在析构函数中用释放内存。
析构函数__destruct 析构函数没有任何参数
范例:
class person{
function _ _destruct( )
{ echo "bye bye !“; }
}
$a=new person();

访问类型
public 公共的(公共修饰符) 类内部与类外部都可以访问的
private 私有的(私有修饰符) 只能在类内部访问
protected 受保护的(保护成员修饰符) 子类可以访问 类外部不可以访问

oop的三个重要特性
封装,继承,多态
封装性:封装性就是把对象的属性和行为结合成一个独立的单位。
封装一个类需要两步 第一步是私有化一个类 第二步是用set和get 做出读取赋值的操作
他的好处是:隐藏类的实现细节,可以方便加入逻辑控制性,限制对属性的不合理操作,便于修改增强代码的可维护性。

__get与__set
一般说把类私有话更符合现实的逻辑。
预定义两种函数来进行获取与敷值操作。
__get 获取值通常是域的值
__set 设置值通常是域的值
__call 调用一个对象中不存在的方法时,就会产生错误call()这个方法来处理这种情况。

静态属性和方法
static关键字 来声明静态方法
static静态变量 在类的内部生成一个静态变量 就是能够被所有类的实力化共想 也就是说静态成员则放到了“初始化静态段”,在类第一次被加载的时候放入的,可以让堆内存里面的每个对象所共享
使用方法:self::$静态属性、self::静态方法
static function p(){
echo self::$country;
echo self::PI;//访问常量
//echo $this-&gt;name;在静态方法中只能操作静态属性
//self::p();
}

外部调用:类::$静态属性、类::静态方法

const关键字:用来生成常量 常量是唯一的不能改变的 惯例常量为大写
const CONSTANT = 'constant value'; 生成一个常量
echo self::CONSTANT;//类内部访问
echo ClassName::CONSTANT;//类外部访问

继承性
B类的对象拥有A类的全部属性与行为,称作B对A类的继承。
假如一个类从多个类中继承了属性与服务,这称为多继承,通常我们成为继承类为子类被继承类为父类,在PHP中只有单继承,但一个父类可以被多个类继承,但是一个子类只能有一个父类,但是允许关联继承,通过继承可以减化类的定义。
extende声明继承关系
语法格式:class B extends A 此范例指明 B继承了A
类的外部访问对子类是有效的
子类与父类的属性与方法
子类继承父类的所有内容,但父类中的private部分不能直接访问
子类中新增加的属性和方法是对父类的扩展
子类中定义的与父类同名的属性是对父类属性的覆盖,同名的方法也是对父类方法的覆盖

重写的方法
在子类中,使用parent访问父类中的被覆盖的属性和方法
parent::__construce();
parent::$name;
parent::fun();

覆盖父类原有属性
clone克窿对象 语法格式$c=clone $p; $c克窿的对象$p 输出echo $c->name;

对象比较
===两个比较运算符。
==是比较两个对象的内容。
===是比较对象的句柄,即引用地址。

instanceof操作符用于检测对象实力是否属于某一个类的类型 属于返回true 不属于返回false
__clone()如果想在克隆后改变原对象的内容,需要在__clone()中重写原本的属性和方法
function __clone(){
$this-&gt;name="我是一个克隆人";
}

final表示一个类是最终版本 也就是说它不能在被子类调用

多态性

多态性是指在父类中定义的属性或行为被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在父类及其各个子类中具有不同的语义。
就是说同一种方法在子类与父类中执行的结果不同。
class A {
function info(){
echo “A INFO”;
}
}
class B extends A {
function info(){
echo “B INFO”;
}
}
class C extends A {
function info(){
echo “C INFO”;
}
}
function printinfo($obj){
function printinfo(A $obj){
if($obj instanceof A)
$obj-&gt;info();
$obj-&gt;info();
}
}
$a=new A(); $b=new B(); $c=new C();
printinfo($a); //输出A INFO
printinfo($b); //输出B INFO
printinfo($c); //输出C INFO

抽象方法和抽象类

抽象方法是作为子类摸版使用的。
abstract class Person{
public $name;
abstract function getInfo();
}
抽象类不能被实力话,一个抽象类中,必须有一个抽象方法。但是抽象类中可以定义动态函数。
接口
当一个类继承了一个接口之后,它要覆盖接口的所有方法,接口只能声明常量,接口的方法必须定义为共有否则无法继承,接口可以与多个接口间继承
语法:
interface PCI{
const TYPE="PCI";
//public $name; error
function start();
function stop();
}

接口中的方法可以声明为static
interface A{ function a();}
interface B{ function b();}
interface C extends A{ function c();}
class D implements B,C{
function a(){}
function b(){}
function c(){}
}

PHP中$_SERVER的详细参数与说明

php编程中经常需要用到一些服务器的一些资料,特把$_SERVER的详细参数整理下,方便以后用到.

$_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root相关。
$_SERVER['argv'] #传递给该脚本的参数。
$_SERVER['argc'] #包含传递给程序的命令行参数的个数(如果运行在命令行模式)。
$_SERVER['GATEWAY_INTERFACE'] #服务器使用的 CGI 规范的版本。例如,“CGI/1.1”。
$_SERVER['SERVER_NAME'] #当前运行脚本所在服务器主机的名称。
$_SERVER['SERVER_SOFTWARE'] #服务器标识的字串,在响应请求时的头部中给出。
$_SERVER['SERVER_PROTOCOL'] #请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
$_SERVER['REQUEST_METHOD'] #访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。
$_SERVER['QUERY_STRING'] #查询(query)的字符串。
$_SERVER['DOCUMENT_ROOT'] #当前运行脚本所在的文档根目录。在服务器配置文件中定义。
$_SERVER['HTTP_ACCEPT'] #当前请求的 Accept: 头部的内容。
$_SERVER['HTTP_ACCEPT_CHARSET'] #当前请求的 Accept-Charset: 头部的内容。例如:“iso-8859-1,*,utf-8”。
$_SERVER['HTTP_ACCEPT_ENCODING'] #当前请求的 Accept-Encoding: 头部的内容。例如:“gzip”。
$_SERVER['HTTP_ACCEPT_LANGUAGE']#当前请求的 Accept-Language: 头部的内容。例如:“en”。
$_SERVER['HTTP_CONNECTION'] #当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。
$_SERVER['HTTP_HOST'] #当前请求的 Host: 头部的内容。
$_SERVER['HTTP_REFERER'] #链接到当前页面的前一页面的 URL 地址。
$_SERVER['HTTP_USER_AGENT'] #当前请求的 User_Agent: 头部的内容。
$_SERVER['HTTPS'] — 如果通过https访问,则被设为一个非空的值(on),否则返回off
$_SERVER['REMOTE_ADDR'] #正在浏览当前页面用户的 IP 地址。
$_SERVER['REMOTE_HOST'] #正在浏览当前页面用户的主机名。
$_SERVER['REMOTE_PORT'] #用户连接到服务器时所使用的端口。
$_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名。
$_SERVER['SERVER_ADMIN'] #管理员信息
$_SERVER['SERVER_PORT'] #服务器所使用的端口
$_SERVER['SERVER_SIGNATURE'] #包含服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] #当前脚本所在文件系统(不是文档根目录)的基本路径。
$_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用。
$_SERVER['REQUEST_URI'] #访问此页面所需的 URI。例如,“/index.html”。
$_SERVER['PHP_AUTH_USER'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
$_SERVER['PHP_AUTH_PW'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
$_SERVER['AUTH_TYPE'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型

PHP学习文件处理与文件上传

PHP对文件的处理
PHP 在服务器端文件的应用上,相关的范畴不仅仅在于用户与服务器资料库间的各种连接存取操作,也可以通过 PHP 内建的文件处理函数,来进行一般文件处理操作。
basename — 返回路径中的文件名部分
语法格式:$path = “/home/httpd/html/index.php”;
$file = basename($path); // $file is set to “index.php”
$file = basename($path,”.php”); // $file is set to “index”
pathinfo():分析文件当前路径
语法格式:$path_parts = pathinfo(“/www/htdocs/index.html”);
echo $path_parts["dirname"] . “\n”; /www/htdocs 文件路径
echo $path_parts["basename"] . “\n”; index.html 文件与扩展名
echo $path_parts["extension"] . “\n”; html 文件格式
文件类型与相关信息
filesize():计算文件的大小(byte)
语法格式:$bytes=filesize(“a.txt”);
echo $bytes round($bytes/1024,2);
fileatime():文件最后一次访问时间(时间戳)
语法格式:echo date(“Y-m-d g:i:sa”,fileatime);
filectime():文件建立时间
语法格式:echo date(“Y-m-d g:i:sa”,filectime);
filemtime():文件最后一次更新时间
语法格式:echo date(“Y-m-d g:i:sa”,filemtime);
fileperms():文件属性以及权限10进制
语法格式:echo substr(base_convert(fileperms(a.txt),10,8),3);
fileowner():文件所有者的uid(仅在Linux系统下有用)
语法格式:echo fileowner(“a.txt”);
文件的操作
‘r’ 只读方式打开,将文件指针指向文件头。
‘r+’ 读写方式打开,将文件指针指向文件头。
‘w’ 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
‘w+’ 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
‘a’ 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
‘a+’ 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
‘x’ 创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。
‘x+’ 创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。
fopen() — 打开文件或者 URL
fclose() — 关闭一个已打开的文件指针
fread() — 读取文件内容
fwrite()–写入文件
语法格式:if(!$f=@fopen(“file03.php”,”x”)){//打开一个文件 x方法写入
die(“文件读取失败”); //读取失败
}
fwrite($f,”kkkkkkkkkk”); //向那个文件写 写什么
echo fread($f,10); //读取这个文件的内容
fclose($f); 关闭打开文件

file() — 把整个文件读入一个数组中
语法格式:$arr=file(“file03.php”);
print_r($arr); //读取文件返回数组
readfile() –读入一个文件并写入到输出缓冲。
语法格式:$str=readfile(“file03.php”);
echo $str; 输出
一个文件记数器的写法:
$f=fopen(“file03.php”,”r”);
$i=fread($f,1000);
echo “这是您第{$i}次访问”;
fclose($f);
$f=fopen(“file03.php”,”w”);
$i++;
fwrite($f,$i);
fclose($f);
““““““““““““““““““““
file_get_contents() – 将整个文件读入一个字符串
语法格式:file_get_contents(文件名称或URL)
file_put_contents() –?将一个字符串写入文件,和依次调用 fopen(),fwrite() 以及 fclose() 功能一样
file_put_contents(文件名称,写入数据)

feof() — 测试文件指针是否到了文件结束的位置
ftell() — 返回文件指针读/写的位置
语法格式ftell(文件指针)
flock() — 轻便的咨询文件锁定
语法格式:flock(文件指针,控制参数)
文件指针:是一个已经打开(fopen)的文件指针控制参数:
“LOCK_SH”表示要取得共享锁定(读取程序),(PHP4.0.1以前版本设置1)。
“LOCK_EX”表示要取得独占锁定(写入程序),(PHP4.0.1以前版本中设置为 2)。
“LOCK_UN”表示要释放锁定(无论共享或独占),(PHP4.0.1以前版本中设置为 3)。
“LOCK_NB”表示如果你不希望 flock() 在锁定时堵塞,则给控制参数再加上这个参数
fseek( ) — 在文件指针中定位
语法结构: fseek(文件指针,移动字元数 [,起始位置常数])
文件指针:不能用于在 fopen() 中以 “http://” 或 “ftp://” 格式打开所返回的文件指针。
移动字元数:为正数时,将文件指针向前移动指定个数:为负数时,将文件指针向后移动指定个数:
起始位置常数:
SEEK_CUR – 设定位置为当前位置。
SEEK_SET – 设定位置等于文件开头。(默认值)
SEEK_END – 设定位置为文件尾。

rewind( ) — 倒回文件指针的位置,也就是将文件指针移向文件的开头位置。
语法结构: rewind(文件指针)
注意:如果将文件以附加(“a” 或者 “a+”)模式打开,写入文件的任何数据总是会被附加在后面,不管文件指针的位置
chgrp( ) — 改变文件所属的组
语法结构:chgrp(文件名称,群组名称)
filegroup( ) — 取得文件的组
语法结构:filegroup(文件名称)
chmod( ) — 改变文件模式
语法结构:chmod(文件名称,权限常数)755 666
chown( ) — 改变文件的所有者
语法结构:chown(文件名称,使用者)
fileowner( ) — 取得文件的所有者
语法结构:fileowner(文件名称)
posix_getpwuid() 来将其解析为用户名。

copy( ) — 拷贝文件
语法结构:copy(来源文件,目的文件)
返回类型:bool型,如果成功则返回 TRUE,失败则返回 FALSE。
参数说明:将来源文件拷贝到目的文件。
unlink( ) — 删除文件
语法结构:unlink(目标文件)
返回类型:bool型,如果成功则返回 TRUE,失败则返回 FALSE。
参数说明:删除指定的目标文件
rename( ) — 重命名一个文件或目录
语法结构:rename(旧文件名,新文件名)
返回类型:bool型,如果成功则返回 TRUE,失败则返回 FALSE。
参数说明:尝试把旧文件名重命名为新文件名。
文件属性处理
file_exists( ) — 检查文件或目录是否存在
语法结构:file_exists(文件名称)
返回类型:bool型,若存在返回 true,否则返回 false。
filesize( ) — 取得文件大小
语法结构:filesize(文件名称)
返回类型:返回文件大小字节数,若出错返回 false.
filetype( ) — 取得文件类型
语法结构:filetype(文件名称)
返回类型:返回文件类型。可能的值有 fifo,char,dir,block,link,file 和 unknown。 出错则返回 false
is_dir( ) — 判断给定文件名是否是一个目录
语法结构:is_dir(名称)
返回类型:如果文件名存在并且是一个目录则返回 true,否则返回 false。
is_executable( ) — 判断给定文件名是否可执行
语法结构:is_executable(名称)
返回类型:如果文件存在且可执行则返回 TRUE,否则返回 FALSE。
is_file( ) — 判断给定文件名是否为一个正常的文件
语法结构:is_file(名称)
返回类型:如果文件存在且为正常的文件则返回 TRUE。
is_link( ) — 判断给定文件名是否为一个符号连接
语法结构:is_link(名称)
返回类型:如果文件存在并且是一个符号连接则返回 true。
is_readable( ) — 判断给定文件名是否可读
语法结构:is_readable(文件名称)
返回类型:如果文件存在并且可读则返回 TRUE。
is_writable( ) — 判断给定的文件名是否可写
语法结构:is_writable(文件名称)
返回类型:如果文件存在并且可写则返回 TRUE。

实现iterator接口的目录读取
Iterator接口的标准方法
current():返回当前列表(list)中的元素值。
next():用于在一个列表中向下移动一个位置。
valid():检测在当前列表中是否还有下一个元素,如果有,返回true,否则返回false。
rewind():可以访问指定特征的元素列表,在开始操作iterator时,会将指针设置在顶部。
DirectoryIterator自定义的类
getATime ():文件最后访问时间
getCTime ():文件最后的修改时间
getGroup ():文件所属组(仅UNIX)
getInode ():文件的节点(仅UNIX)
getOwner ():文件的宿主(仅UNIX)
getPerms ():访问该文件的权限
getSize ():文件的大小
getType ():文件的类型
getFileName ():文件的名称
getPath ():文件的路径
isDir ():是否是目录
isExecutable ():是否可以执行
isFile ():是否是文件
isLink ():是否是软链接文件
isReadable ():是否可读
isWritable ():是否可写
isDot ()方法分别过滤掉“.”和“..”目录。

$dname=$_GET["dname"]; //获取from表的信息
if(isset($dname)&&!empty($dname)){ //判断变量是否被设置 检测一个变量是否为空
$dir=new DirectoryIterator(“{$dname}”); //new一个类
echo $dir->getPath().” //类的方法
}else{
$dir=new DirectoryIterator(“D:\\”); //new d://目录
echo $dir->getPath();
}
$delname=$_GET["del"];
if(isset($delname)&&!empty($delname)){
if(unlink(“{$dir->getPath()}\\$delname”))
echo “删除成功”;
}
while($dir->valid()){
if($dir->isDir())
echo “<a href=’file14.php?dname={$dir->getPath()}\\{$dir->current()}’>”.
“{$dir->current()}</a><br>”;
else
echo “{$dir->current()} <a href=’#'>复制</a>”.
” <a href=’file14.php?del={$dir->current()}’>删除</a><br>”;
$dir->next();
}
范例2:function showdir($iter){ //设置一个函数方法 并赋值
for(;$iter->valid();$iter->next()){ //检测目录是否还有下一个目录 想下移动一位
if($iter->isDir() && $iter->isDot()){//检测是否是目录 并过滤掉.和..目录位置
echo “目录”.$iter->current().”<br>”; //指向返回列表元素的值
}else{
echo $iter->current().$iter->getSize().”字节<br>”; 反则 返回列表的值 并查看文件大小
}
}
}
showdir(new DirectoryIterator(“C:/”)); //传参 new一个系统默认类
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PHP文件上传
与文件系统和服务器的交互
文件上传`使用目录函数 `与文件系统的交互`使用程序执行函数`与环境变量交互

文件上传
在B/S程序中文件上传已经成为一个常用功能。其目的是客户可以通过浏览器(Browser)将文件上传到服务器(Server)上的指定目录
PHP中文件上传的基础知识
表单提交`对文件的操作
何为文件上传?
为了满足传递文件信息的需要:HTTP协议实现了文件上传机制,从而可以将客户端的文件通过自己的浏览器上传到服务器上指定目录存放。

HTML规范规定上传文件时表单头必须使用
<html>
<head><title>文件上传</title></head>
<body>
<form action=”todo.php” method=”post” enctype=”multipart/form-data”> //返回值 post 方式上传 表示要上传一个文件
<input type=”hidden” name=”MAX_FILE_SIZE” value=”100000″>
上传文件:<input type=”file” name=”userfile”>
提交:<input type=”submit” value=”提交查询”>
</form>
</body>
</html>
注意几个特征属性:
POST方法:
表单最常用的功能,向目标页面传递变量,我们在上传文件的时候,会在表单中设置相应的属性,来完成文件的传递.
enctype=”multipart/form-data”
这样服务器就会知道,我们要传递一个文件,这样服务器可以知道上载的文件带有常规的表单信息。
MAX_FILE_SIZE
此字段必须在文件输入字段之前,控制最大的传递文件的大小(字节) ——真的可以控制吗?
<input type=”file” name=”userfile”>
设置浏览器文件输入浏览按钮
我们在服务器端的php.ini中设置对表单传递的数据进一步判断
file_uploads = On /Off 是否允许文件上传
upload_max_filesize = 2M 上传的文件的最大大小
post_max_size = 8M POST数据所允许的最大大小
表单传递的数据,文件只是其中的一部分,所以设置时,upload_max_filesize应该小于post_max_size

超级全局数组$_FILES
PHP程序中,需要处理的上传数据保存在全局数组中$_FILES(超级全局数组)
保存$_FILES数组中的元素,将HTML表单的type=”file”标记的名称name=”userfile” 存放在数组中。
存储在$_FILES['userfile']['name']中的值是:客户端文件系统的文件的名称
存储在$_FILES['userfile']['type']中的值是:客户端传递的文件的类型
存储在$_FILES['userfile']['size']中的值是:文件的字节的大小
存储在$_FILES['userfile']['tmp_name']中的值:文件被上传后在服务器存储的临时全路径
“““““““““““““““““““““`
存储在$_FILES['userfile']['error']中的值是:文件上传的错误代码-php 4.2以后增加的功能
存储在$_FILES['userfile']['error']中的值
值为0:表示没有发生任何错误。
值为1:表示上传文件的大小超出了约定值。文件大小的最大值是在PHP配置文件中指定的,该指令是:upload_max_filesize。
值为2:表示上传文件大小超出了HTML表单隐藏域属性的MAX_FILE_SIZE元素所指定的最大值。
值为3:表示文件只被部分上传。
值为4:表示没有上传任何文件。
““““““““““““““““““
is_uploaded_file( )检测是否是上传文件
move_uploaded_file(临时路径/临时文件名,目的路径/目的文件名 ) 函数将存放在临时目录下的上传文件拷贝出来,存放到指定目录的指定文件名,如果目标存在将会被覆盖。
范例:print_r($_FILES["upfile"]);//将表单提交的系统存放在这
echo “文件名字”.$_FILES["upfile"]["name"];//文件名字
if($_FILES["upfile"]["error"]<=1){//错误代码小于1 大于1表示有错误
echo “请选择文件”;
}
if(is_uploaded_file($_FILES["upfile"]["tmp_name"])){//检测这个文件是否是上传文件 文件的临时路径
echo ‘是上传文件’;
move_uploaded_file($_FILES["upfile"]["tmp_name"],”./upload/”.$_FILES["upfile"]["name"]);
//将临时文件转移到upload目录 文件名 为原名
}else{
echo ‘不是上传文件’;
}
文件上传后的临时存放目录
上传的文件被放置到服务器端临时目录:/tmp目录里面 命名为一个唯一的,随机生成的临时文件名。 注:该文件在程序执行完后将自动被删除掉。在删除前可以像本地文件一样操作。
/tmp目录是默认的上传临时文件存放地点, 如果需要更改这个目录: 可以编辑/etc/php.ini 文件File Uploads 段的upload_tmp_dir 属性值。
当配置文件php.ini的register_globals属性被设置成on的情况
<input type=file name=myfilename>
将生成全局变量:$myfilename等
“““““““““““““““““““““““`
当需要上传多个文件的情况,有两种实现的解决方法:
使用不同的表单元素
<input type=file name=file_a>
<input type=file name=file_b>
使用数组格式的表单元素
<input type=file name=file[1]>
<input type=file name=file[2]>
““““““““““““““““““““““““`
使用目录函数
opendir?–?打开目录句柄
closedir?–?关闭目录句柄
readdir?–?从目录句柄中读取条目
语法格式:$d=opendir(“./upload”); //打开这个文件目录
while($s=readdir($d)){ //循环输出读取到的条目
echo $s.”<br>”;
}
closedir($d); //关闭句柄
创建和修改目录
mkdir?–?新建目录
rmdir?–?删除目录
mkdir(“D:\\up”);//创建一个目录
rmdir(“up”);//删除一个目录
磁盘操作
disk_free_space():统计某个磁盘的剩余空间
disk_total_space():显示逻辑磁盘的容量
echo disk_free_space(“D:\\”)/1024/1024/1024;
echo disk_total_space(“D:\\”)/1024/1024/1024;
getcwd():返回当前脚本所在路径
chdir():类似DOS的cd命令,改变当前路径
echo getcwd();//查看当前脚本路径
chdir(“D:\\”);//改变
使用程序执行函数
exec( ) 函数可以将要执行的命令作为参数。
passthru( ) 结果直接输出显示到浏览器。
system( )也是直接输出显示到浏览器,但有返回值

php中COOKIE与SESSION联用实现SESSION跨域

大家都知道SESSION是不可以跨域的,也就是说: A.WEMVC.COM这个域的可执行文件不可以访问到B.WEMVC.COM的SESSION,这个是SESSION的特性,同样也是出于安全角度才这样的.

在一般情况下,一个网站只有一个域名,www.wemvc.com,但是也有些网站架构是由多个子域名组建的.所以就需要SESSION可以跨子域被访问到,这样才可以实现用户的跨域登录.就是说客户在A下登录的,同样B也同时登录了,不需要用户再次登录,同时也实现了参数的跨域传递.当然不可跨域的SESSION本身已经可以帮助我们做很多事情了,那么跨域后的SESSION呢.读到这里是否很激动人心,当然你也可能是正在为SESSION跨域而发愁而找到这篇文章的,同样也祝贺你.我们长话断说了,开始我们今天的课程:COOKIE与SESSION联用实现SESSION跨域.

首先让我们再重新温习下PHP中的COOKIE和SESSION:

COOKIE:

定义:

cookie 常用于识别用户。cookie 是服务器留在用户计算机中的小文件。每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie。通过 PHP,您能够创建并取回 cookie 的值。PS:其中文名叫”曲奇”.

在PHP中用setCookie函数来设置COOKIE,该函数一共有7个参数(在此我要向曾经我面试过的一位同仁道歉,当时我把答案说成了6个,SORRY~,同时我也提醒广大作家尽快更新自己的文章,在PHP5.2.0版本中已经增加为7个参数.),这7个参数分别为 string $name [, string $value [, int $expire [, string $path [, string $domain [, bool $secure [, bool $httponly ]]]]]] .

name

The name of the cookie. 规定 cookie 的名称。

value

The value of the cookie. This value is stored on the clients computer; do not store sensitive information. Assuming the name is ‘cookiename’, this value is retrieved through $_COOKIE['cookiename'] 规定 cookie 的值。

expire

The time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. In other words, you’ll most likely set this with the time() function plus the number of seconds before you want it to expire. Or you might use mktime(). time()+60*60*24*30 will set the cookie to expire in 30 days. If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes).规定 cookie 的有效期。

 

Note: You may notice the expire parameter takes on a Unix timestamp, as opposed to the date format Wdy, DD-Mon-YYYY HH:MM:SS GMT, this is because PHP does this conversion internally.
expire is compared to the client’s time which can differ from server’s time.

path

The path on the server in which the cookie will be available on. If set to ‘/’, the cookie will be available within the entire domain . If set to ‘/foo/’, the cookie will only be available within the /foo/ directory and all sub-directories such as /foo/bar/ of domain . The default value is the current directory that the cookie is being set in.规定 cookie 的服务器路径。

domain

The domain that the cookie is available. To make the cookie available on all subdomains of example.com then you’d set it to ‘.example.com’. The . is not required but makes it compatible with more browsers. Setting it to www.example.com will make the cookie only available in the www subdomain. Refer to tail matching in the » spec for details.规定 cookie 的域名。

secure

Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client. When set to TRUE, the cookie will only be set if a secure connection exists. The default is FALSE. On the server-side, it’s on the programmer to send this kind of cookie only on secure connection (e.g. with respect to $_SERVER["HTTPS"]).规定是否通过安全的 HTTPS 连接来传输 cookie。

httponly

When TRUE the cookie will be made accessible only through the HTTP protocol. This means that the cookie won’t be accessible by scripting languages, such as JavaScript. This setting can effectly help to reduce identity theft through XSS attacks (although it is not supported by all browsers). Added in PHP 5.2.0. TRUE or FALSE.规定是否必须通过HTTP协议来定义访问COOKIE,防止XSS攻击.

SESSION全面教程

SESSION在这里就不过多的讲解了,主要是:

哈哈,不是我懒噢,这里只讲跨域.

OK,大概温习了下COOKIE和SESSION,开始实现我们的跨域.

首先我描述下我的思路,COOKIE可以指定域名,也就是说它可以跨域子域,例如:setcookie(‘name’,'joshua’,time()+3600*24,’/',’wemvc.com’),那么A.wemvc.com,B.wemvc.com都可以访问到$_COOKIE['name'],值也均为’joshua’.同理,SESSION ID也可以设置成这个域名,那么A.wemvc.com和B.wemvc.com都可以得到同一个SESSION ID,那么我们的目的也就达到了.因为知道了同一个SESSION ID就可以访问到这个SESSION中的值了.SESSION有多种方式存储,文件\数据库\内存等,我们采用数据库存储,因为如果A.wemvc.com,B.wemvc.com不在同一台服务器上,那么内存和文件的存储方式就很难实现跨域了,至于到底又没有方法,本人还没有试过.

首先在数据库中创建一张SESSION表:

CREATE TABLE `sessions` (
`sid` varchar(32) NOT NULL default '',
`expiry` int(20) unsigned NOT NULL default '0',
`value` text NOT NULL,
PRIMARY KEY  (`sid`),
KEY `expiry` (`expiry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

然后写一个类,这个类用于读取\插入\更新\删除以及垃圾回收SESSION

class session{
private $db;
function __construct($db){
$this-&gt;db=$db;
}
public function open($save_path,$session_name){
return true;
}
public function close(){
$this-&gt;db=null;
return true;
}
public function read($sid){
$rs=$this-&gt;db-&gt;query("select * from sessions where sid='".$sid."'");
foreach ($rs as $row){
return $row['value'];
}
return null;
}
public function write($sid,$value){
if(is_null($oldvalue=$this-&gt;read($sid))){
//insert
return $this-&gt;db-&gt;query("insert into sessions (sid,expiry,value)values('".$sid."','".time()."','".$value."')");
}else{
//update
return $this-&gt;db-&gt;query("update sessions set expiry='".time()."',value='".$value."' where sid='".$sid."'");
}
}
public function destroy($sid){
return $this-&gt;db-&gt;query("delete from sessions where sid='".$sid."'");
}
public function gc($max_life_time){
return $this-&gt;db-&gt;query('delete from sessions where expiry+'.$max_life_time.'&lt;'.time());
}
}

我来解释下这个类:
private $db; 类的DATABASE属性.
function __construct($db) 类的构造函数,在声明类时,可以直接传递DB属性到类中,当然如果还不明白可以先GOOGLE一下”PHP 类 construct 方法”;
public function open($save_path,$session_name) session打开,没有什么花头,直接返回TRUE;
public function close() session关闭,同理open,但注意要关闭DB连接;
public function read($sid) session读取,传值SID,在数据表中将这个SID的VALUE作为返回值返回;
public function write($sid,$value) session的写入与更新,这个你会有疑问,为什么set expiry=’”.time().”‘,稍后答案在清空过期SESSION GC方法中便会揭晓;
public function destroy($sid) session的销毁,很简单,就是把数据表中等于这个SID的数据删除掉;
public function gc($max_life_time) 清空过期session,把超过max_life_time的SESSION都销毁掉,也就是SESSION的创建时间加上最大生存时间小于现在时间( expiry+’.$max_life_time.’<’.time())的SESSION数据删除掉,这下你会明白为什么在写入和更新SESSION的方法中为什么写当前时间了吧,当然这个写法不是绝对的,随个人意愿只要你的SQL写正确了,也就可以了.

好我们接着来看更重要的部分:

上面的类中需要一个数据库链接属性,所以声明对象的时候需要这样:
$session=new session(your db connect adapter);

数据库链接我可以提供大家一个PDO的方法,参照使用:

function connect_db($arrPDODB){
$db=new PDO($arrPDODB['db_driver'].':host='.$arrPDODB['db_host'].';dbname='.$arrPDODB['db_name'],$arrPDODB['db_user'],$arrPDODB['db_password']);
$db-&gt;query("set names 'utf8'");
return $db;
}

SO,上面声明对象部分你可以这样写:

$session=new session(connect_db($arrPDODB));

接下来:
//设置色session id的名字
ini_set('session.name', 'sid');
//不使用 GET/POST 变量方式
ini_set('session.use_trans_sid', 0);
//设置垃圾回收最大生存时间
ini_set('session.gc_maxlifetime', 3600);
//使用 COOKIE 保存 SESSION ID 的方式
ini_set('session.use_cookies', 1);
ini_set('session.cookie_path', '/');
//多主机共享保存 SESSION ID 的 COOKIE,注意此处域名为一级域名
ini_set('session.cookie_domain', '
wemvc.com');
//将 session.save_handler 设置为 user,而不是默认的 files
session_module_name('user');
session_set_save_handler(array($session,'open'),
array($session,'close'),
array($session,'read'),
array($session,'write'),
array($session,'destroy'),
array($session,'gc'));

以上都是SESSION的设置,不明白的多搜索下手册,我喜欢刨根究底这样的学习方式,这样你可以学透一个知识点,而不是知道一知半解,就认为自己懂了或者会了.

最后在你需要的地方将SESSION启动:

session_start();

最后再提供一个如何防止Session伪造攻击的博文,希望能够仔细阅读.

好了,大功告成,只要在每个执行文件之前包含这个类,并启动它,你的程序可以跨域了,呵呵.当然也可以跨一级域名.你可以在我写出下一篇博文之前自己先研究下啊.

另外,先说一句,其实AJAX也可以跨子域,当时给我下一篇博文作铺垫了.哈哈,欢迎大家与我一同讨论学习.

2008年9月26日更新:

新增了一个demo程序,程序很简单,没有写入库的东西,适合新手学习.

附:

demo_session_1

程序讲解:很简单的 a b 两个文件夹代表你两个域,把你的虚拟机设置为a.yourdomain.com、b.yourdomain.com就可以了。先把这个搞懂,再考虑session入库的事情。session入库主要是因为一个网站有多台服务器的情况下,若session还是以默认的文件型保存的话,多服务器是行不通的。

demo_session 2

程序讲解:这份程序添加了入库功能,数据表的创建,文件上面有的。

PHP中的SESSION全面教程

一、session概述
session是什么,刚开始我也不明白,非专业词典翻译为会议,会议期。直到接触asp后才知道session是干什么的,有什么用。
作个不太恰当的比喻吧(虽然不恰当,但意义却是一样的),session就好象你和你女友(或妻子)之间的感情似的,session是你和网站之间的感情。
session在WEB技术中占有非常重要的份量。由于网页是一种无状态的连接程序,因此你无法得知用户的浏览状态。因此我们必须
通过session记录用户的有关信息,以供用户再次以此身份对web服务器提供要求时作确认,例如,我们在某些网站中常常要求用户登录,
但我们怎么知道用户已经登录了呢,如果没有session的话,登录信息是无法保留的,那岂不要让用户在每一页网页中都要提供
用户名和密码。
当然,session不光用于用户身份认证功能,还可能用于其它方面,以后我们会提到的。
session用中文来解释就是会话期。一个会话期开始于用户输入一个站点的网址时,结束于他离开这个站点时。
session最早出现在动态脚本语言Active Server Pages中,它的功能之强大,是一句话无法说清楚的。
当 php还在3.0版本时,session是它永远的痛。虽然php具有执行速度快,使用灵活,功能强大等优点,但因为session的问题,使很多站点的 开发放弃了php,至少我的老板是这样认为的。当时有很多php免费函数库提供在php3上实现session的方案,但都让人感觉不正宗。
就好象你花好几千大洋买的手机却配置一个很粗糙的草作的袋子一样,虽然功能是一样的,但总让人觉得别扭。php4的出现让php在session问题上
有了翻身的机会。虽然它的session实现还不是很理想(主要是效率问题),但毕竟是它自己实现的,而且可以实际使用了。
那 我们用session干什么呢,你说了半天,我用不上的话,你岂不有卖纸张之嫌。OK,我们来看看session有什么用:作过网站的人都有这样的体会, 在一页页面中的变量(在本章都指服务器端变量,下同)是不能在下一页中用的,虽然有一些办法可以实现,比如用form,urlstring等等
但 有些对于用户来说是不方便的,即使让form自动提交,但其中的延时在现今的网络状况下足以让人窒息,而这两种方法都明显加大程序员的负担。如果你正在开 发一个大型项目,那这些额外的负担是不能忽略的。而有了session就好办了,session中注册的变量可以作为全局变量使用。什么,全局变量?
好极了。这样一来,你知道有什么用了吧:最主要的用于用户身份认证,程序状态记录,页面之间参数传递。
说了它这么半天的好处,你已经动心了吧,先别高兴,它还有缺点呢:它是用文件保存的变量(当然效率不高了,虽然可以用别的方式,但
很麻烦的),不能保存对象。与之相对的是,asp中的session可以保存对象变量,用内存变量来保存session变量。但为什么我们还选用php呢,呵呵,
为什么,你能从本书的开始看到这章,想必你也应该明白了吧,你还不明白,Faint,你再从头看起吧,我保证你成为PHP专家^_^。
session是怎样实现的呢?呵呵,你一定以为很高深吧,我来告诉你它的秘密。如果说只保存变量的话,很多读者都明白,这是很简单的,
但前面我们说过,http协议是一种无状态的连接,你怎么知道那个变量是谁的,这个变量又是谁的呢?在session实现中用cookie实现的。cookie
存在于客户端,也就是用户的机器中,里面保存着用户的session ID,也就是session号码,当用户的浏览器请求服务器时把session ID也一起送到
服务器,这样服务器就可以识别你是谁,也就可以把变量识别开了。这样我们就不难理解了,为什么有时session会失效了。不信的话,你可以试试:
在IE的”工具”菜单上有”Internet选项”菜单,打开后再选”安全”->”自定义级别”,将安全设置中的”允许使用每个对话cookies”设为禁用,再看看
session能不能用。这下明白了吧!不过php4在linux/unix平台上可以自动检查cookies状态,当cookies 不可用时,自动会把session ID
附带在url上进行传递。这是它在session方面比asp多的唯一的优点了。

二、php3,4中session的实现

在php3中是没有session这种东东的,但我们又需要,怎么办呢?别急,有很多人替你做了这些,这其中最有名的要算phplib了。你可以去国外下
载,也可以上国内大部分php站点下载。我们要做的第一件事是让phplib和php3结合在一起使它能工作。为了能实现这方面的功能,我们需要先安装phplib。
跟着我来做,很容易的(以下方法在win2000+php3.0.16+apache1.3.12+phplib7.2c+mysql3.23.21 for win32 上通过)
phplib最基本的功能包括用户认证,Session管理,权限及数据库的抽象化。
怎样使用phplib来实现session功能呢?
一、首先你将phplib解开,里面有一个目录叫”php”,将这个目录拷贝到apache的安装目录下。以下以笔者的机器为例:
我的apache安装在d:apache 目录下,我将上面的”php”目录拷贝到d:apache,并将phplib下的pages目录下的文件和目录一起拷贝到
d:apachehtdocs下,注意不带目录本身。
phplib的类库需要根据系统进行初始化,你可以修改local.inc文件,其中包含着一些基本参数,你可以根据自己机器的实际情况来进行修改。
将d:apachephpprepend.php3文件中的一段程序改为如下样子:

if (!isset( $_PHPLIB) or !is_array( $_PHPLIB)) {
$_PHPLIB["libdir"] = “d:/apache/php/”; //这儿改为你放phplib下php目录的路径
}

然后将d:apachephplocal.inc文件改如下:

class DB_Example extends DB_Sql {
var  $Host = “localhost”;//你的mysql数据库所在主机名
var  $Database = “test”;//数据库名
var  $User = “root”;//数据库用户名
var  $Password = “”;//数据库用户口令
}

最后一步执行解开的phplib目录中的stuff目录下的create_database.mysql文件,生成初始表。
我们说明一下phplib的工作原理,每一个使用phplib的页面首先必须可以找到运行phplib所必须类库文件,我们可以在php3.ini中设置auto_prepend
变量来支持,phplib分发包中包含一个prepend.php3文件,将auto_prepend指定为”d:/apache/php/prepend.php3″(带引号)后,各页面就会自动包含phplib类库,我们还可以
将phplib类库所在目录加进include变量中,以便可以找到这些文件,当然,最苯的办法就是指定phplib的绝对路径,这可不是个好主意,可移植性太差!
第二步,每一个使用phplib的页面中,你必须首先调用page_open函数进行初始化。这会告诉phplib,你现在或将来会用到状态保存。一个典型的
page_open例子如下:
<?php
page_open(array(“sess” => “Example_Session”));
?>

数组变量(sess)用来初始化一些状态保存对象,注意:必须使用phplib内置名(sess),这些内置名是你在local.ini中所定义的,page_open
函数必须在页面内容输出到浏览器之前被调用。php3脚本最后应以page_close()结束,这将会将有关状态数据写回到数据库中,如果你忘了的话,
结果你应该能想到,哈哈,你的变量全丢了,可不要怪我没告诉你…

因为phplib使用了Cookies来保存状态信息,所以page_open()函数必须在页面内容输出到浏览器之前被调用, 这里的页面内容可以是任何HTML
信息或者空行,如果你发现了错误”Oops – SetCookie called after header has been sent”,这表明在page_open()之前向浏览器输出了些什么,
你要特别留意空行,因为非常难找到,典型的错误是在<? 和 ?>标记之间输出了空行,你应检查在local.inc和prepend.php3文件中是否包含了空行,
这也是一个非常容易出错的地方。为了减少出错的可能,我们可以这样书写初始化程序:
<?
page_open(array(“sess” => “Example_Session”));
?>
<html>
…..
</html>
第三步,具体使用。
当一个用户访问了该网站后,随即用户的session就开始了,如果用户的浏览器支持cookie的话,将会建立一个session的id放入cookie,
这个唯一的ID是由PHP3随机生成,然后又用随机种子字串进行md5加密过了的,这里的cookie应该叫做session cookie,因为这个cookie是不会
写到用户硬盘里去的,当一个session期结束的时候,该cookie也被完结了。如果用户浏览器不支持cookie的话,那么 该session的id将会放入url链中,
因为是加密过的,所以窃取了也没用。session ID存放着用户的有关信息,如用户已认证、认证到期时间、用户权限,和其他一些你可能需要的信息,
方便我们取用。
Session其实就是用户一次会话的过程。Session并不是仅仅用来跟踪用户的注册,实际上,它还可以有其它的使用场合,你可以用它来存储任何你想要
存贮的信息,这些信息可以在用户随后访问的页面中派上用场,当然前提是那些页面要使用PHPLIB。方法很简单,注册一个变量后即可在随后的页面中使用它,
直至session结束。方法:

<?php  $sess->register( “variable_name”); ?>

注意,这里的variable_name不是变量值,而是变量名,可以先指定变量名,随后再赋值。你在某个页面中可以改变变量的值,随后的页面访问该变量时
会得到改变后的值。变量的类型是多样的,可以是一个字串,一个数字,一个数组。举例来说明:
第一页:
<?php
page_open(array(“sess” => “Example_Session”));
$sess->register( “first”); //注意变量名前不需要加 $
if (iset( $firstname)) {
$first =  $firstname;
}
…..
page_close();
?>
第二页:
<?php
page_open();//开始session

echo  $first;//看看效果

page_close();//保存状态信息
?>

注册完一个变量,当页面最后调用page_close()函数后,各个session变量会被写回到数据库中。如果你忘记调用page_close()函数的话,
变量就不会被写回数据库,将出现不可预知的后果。当变量被使用完毕,你不再需要用到时,可以调用以下函数将变量删除:
<?php
page_open(array(“sess” => “Example_Session”));

$sess->unregister( “variable_name”);

page_close();
?>

PHPLIB 7.0中,使用了一种存储结构,它允许你存储session数据到数据库中、共享内存中或者LDAP中。PHPLIB使用了数据库类,这使得你有
了更多的选择,你可以选用oracle8,mysql,postgresql等等数据库来保存状态信息。

关于phplib中的其它功能以及有关session的其它函数的使用,你可以参看它带的手册,或上它的网站看在线文档。它的老家在
http://phplib.netuse.de/index.php3
php4的session实现大都从phplib学来的,它也靠cookies保存session id,用文件系统保存变量(默认情况下)。因此,它的session
变量不能保存对象(事实上能保存对象内容,但没有意义,因为它是保存在磁盘上的,不是活的对象,充其量也就是对象尸体。)不过这点的限制不是太
大,我们在大部分情况下都只需要保存变量就行了。当然你也可以将session保存在数据库中,下一小节中我们会讲到怎样将session保存在数据库中。
在php4中由于比php3多了session支持,所以在php.ini文件中也多了session配置选项。下面我们来看看各项的作用与意义:

[Session]
session.save_handler = files ; handler used to store/retrieve data(用什么保存session变量,默认情况下用文件)
session.save_path = c:/temp ; argument passed to save_handler(保存session变量的目录,在linux/unix下为/tmp,在win下设为你的目录)
; in the case of files, this is the
; path where data files are stored
session.use_cookies = 1 ; whether to use cookies(是否使用cookies,当然,在win下别无选择)
session.name = PHPSESSID
; name of the session(默认session使用的cookies名,建议不要改动)
; is used as cookie name
session.auto_start = 0 ; initialize session on request startup(是否自动启用session,当为1时,在每页中就可以不必调用session_start()函数了)
session.cookie_lifetime = 0 ; lifetime in seconds of cookie(设定 cookie 送到浏览器后的保存时间,单位为秒。缺省值为 0,表示直到浏览器关闭。)
; or if 0, until browser is restarted
session.cookie_path = / ; the path the cookie is valid for(cookie)(cookies有效路径)
session.cookie_domain = ; the domain the cookie is valid for(cookies有效域名)
session.serialize_handler = php ; handler used to serialize data(定义序列化数据的标识,本功能只有 WDDX 模块或 PHP 内部使用。缺省值为 php)
; php is the standard serializer of PHP
session.gc_probability = 1 ; percentual probability that the (设定每次临时文件开始处理 (gc, garbage collection) 处理概率。缺省值为 1。 )
; garbage collection process is started
; on every session initialization
session.gc_maxlifetime = 1440 ; after this number of seconds, stored(设定保存session的临时文件被清除前的存活秒数)
; data will be seen as garbage and
; cleaned up by the gc process
session.referer_check = ; check HTTP Referer to invalidate (决定参照到客户端的 Session 代码是否要删除。有时在安全或其它考虑时,会设定不删除。缺省值为 0。)
; externally stored URLs containing ids
session.entropy_length = 0 ; how many bytes to read from the file(设定 session 从高熵值资源读取的位数。缺省值为 0.)
session.entropy_file = ; specified here to create the session id(设定 session 代码建立时,使用外部高熵值资源或文件来建立,例如 UNIX 系统上的 /dev/random 或 /dev/urandom。 )
; session.entropy_length = 16
; session.entropy_file = /dev/urandom
session.cache_limiter = nocache ; set to {nocache,private,public} to (设定session 缓冲限制)
; determine HTTP caching aspects
session.cache_expire = 180 ; document expires after n minutes(文档有效期,单位为分钟)

在windows平台下,php4.01pl2以前的版本会出现设置session.save_path 后出错的情况,这是php的一个bug,在php4.01pl2及以后已经修正了。如果你用以前的版本,
你可以将session.save_path设为”./”,或设为”/temp”,并在你放置php脚本的当前盘根目录下建一个名为temp的目录即可(我的php脚本放在d:apachehtdocs下,则我在d:盘根目录下建一名为temp的目录)。
在php4中有关session的函数主要有以下这些:

session_start: 初始化session,需要用session的每一个页面最开始处调用。
session_destroy: 结束 session,在需要结束session处调。
session_name: 存取目前 session 名称。
session_module_name: 存取目前 session 模块。
session_save_path: 存取目前 session 路径。
session_id: 存取目前 session id号。
session_register: 注册新的session变量。
session_unregister: 删除已注册session变量。
session_is_registered: 检查session变量是否注册。
session_decode: Session 数据解码。
session_encode: Session 数据加密。

通常情况下我们只需要调用三个函数即可。
即sesssion_start()、session_register()、session_is_registered()。
在需要用到session的每一页的最开始处调用session_start()函数,
一个典型的使用session的页面如下:
<?session_start()?>
<html>
….
<body>
<?
$var=”hello”;
session_register(“var”);//注册 $var变量,注意没有 $符号

if(session_is_registered(“var”))//检查变量是否注册
echo “haha,注册了!”;
else
echo “sorry,还没有注册!”;

?>
</body>
</html>

php4中session处理的定制

我们需要扩充6个函数,当然这些函数不需你去调用,对我们来说是透明的。

这几个函数是:
sess_open( $sess_path,  $session_name);

这个函数被session处理程序调用来作初始化工作。需要传给它的两个参数是 $sess_path,它对应你的php.ini文件中的session.save_path
选项; $session_name,它对应php.ini中的session.name 选项。它们具体怎样工作,请看下面的例子。

sess_close();

这个函数在页面结束执行并且session处理程序需要关闭时被调用。(注意,不要和sess_destory混淆了,它是用来结束session的)

sess_read( $key);

这个函数在session处理程序读取指定session键值( $key)时。
这个函数检索并返回标识为 $key的session数据.(注意:你不用担心怎样序列化和反序列化数据,如果你不知道这是什么意思,不要担心它)

译者注:序列化是将变量或对象在程序结束或需要时保存在文件中,在下次程序运行或需要时再调入内存的技术,有别于只保存数据的方法。

sess_write( $key,  $val);

这个函数据在session处理程序需要将数据保存时调用,这种情况经常在你的程序结束时发生。
它负责将数据保存在下次能用sess_read( $key)函数检索的地方。

sess_destroy( $key);

这个函数在需要消毁session时。它负责删除session并且清除环境。

sess_gc( $maxlifetime);
这个函数负责清理碎片。在这种情况下,它负责删除过时的session数据。session处理程序会偶尔调用它们。

现在我们已经清楚了我们提供的函数。

定制程序可以用mysql数据库或DBM文件保存session数据。取决于你的需要。
如果你决定使用mysql作支持,那需要作以下工作:

首先我们在mysql中创建一个sessions数据库,并且创建一个sessions表。先运行你的mysql客户端并且执行下面的命令:
mysql> CREATE DATABASE sessions;

mysql> GRANT select, insert, update, delete ON sessions.* TO phpsession@localhost
-> IDENTIFIED BY phpsession;

mysql> CREATE TABLE sessions (
-> sesskey char(32) not null,
-> expiry int(11) unsigned not null,
-> value text not null,
-> PRIMARY KEY (sesskey)
-> );

下一步,修改session_mysql.php文件的 $SESS_DB* 变量使其匹配你机器上的数据库设置。

(很抱歉,由于版权原因,我不能把以下代码中的英文去掉,只好加些注释了:)
==================================================================================
<?
/* ————————————————————————
* session_mysql.php
* ————————————————————————
* PHP4 MySQL Session Handler
* Version 1.00
* by Ying Zhang (ying@zippydesign.com)
* Last Modified: May 21 2000
*
* ————————————————————————
* TERMS OF USAGE:
* ————————————————————————
* You are free to use this library in any way you want, no warranties are
* expressed or implied. This works for me, but I dont guarantee that it
* works for you, USE AT YOUR OWN RISK.
*
* While not required to do so, I would appreciate it if you would retain
* this header information. If you make any modifications or improvements,
* please send them via email to Ying Zhang <ying@zippydesign.com>.
*
* ————————————————————————
* DESCRIPTION:
* ————————————————————————
* This library tells the PHP4 session handler to write to a MySQL database
* instead of creating individual files for each session.
*
* Create a new database in MySQL called “sessions” like so:
*
* CREATE TABLE sessions (
* sesskey char(32) not null,
* expiry int(11) unsigned not null,
* value text not null,
* PRIMARY KEY (sesskey)
* );
*
* ————————————————————————
* INSTALLATION:
* ————————————————————————
* Make sure you have MySQL support compiled into PHP4. Then copy this
* script to a directory that is accessible by the rest of your PHP
* scripts.
*确信你的php4有mysql支持,然后把这个脚本拷贝到和你的php脚本有关的目录。
* ————————————————————————
* USAGE:(使用方法)
* ————————————————————————
* Include this file in your scripts before you call session_start(), you
* dont have to do anything special after that.
*包含这个文件到你要使用session的文件中,必须在调用session_start()之前,否则,
*会很惨的,不要怪我没告诉你。 这样就不需要再做什么工作了,还和你以前用session的方法一样。
*/

$SESS_DBHOST = “localhost”; /* database server hostname */
$SESS_DBNAME = “sessions”; /* database name */
$SESS_DBUSER = “phpsession”; /* database user */
$SESS_DBPASS = “phpsession”; /* database password */

$SESS_DBH = “”;
$SESS_LIFE = get_cfg_var(“session.gc_maxlifetime”);

function sess_open( $save_path,  $session_name) {
global  $SESS_DBHOST,  $SESS_DBNAME,  $SESS_DBUSER,  $SESS_DBPASS,  $SESS_DBH;

if (!  $SESS_DBH = mysql_pconnect( $SESS_DBHOST,  $SESS_DBUSER,  $SESS_DBPASS)) {
echo “<li>Cant connect to  $SESS_DBHOST as  $SESS_DBUSER”;
echo “<li>MySQL Error: “, mysql_error();
die;
}

if (! mysql_select_db( $SESS_DBNAME,  $SESS_DBH)) {
echo “<li>Unable to select database  $SESS_DBNAME”;
die;
}

return true;
}

function sess_close() {
return true;
}

function sess_read( $key) {
global  $SESS_DBH,  $SESS_LIFE;

$qry = “SELECT value FROM sessions WHERE sesskey =  $key AND expiry > ” . time();
$qid = mysql_query( $qry,  $SESS_DBH);

if (list( $value) = mysql_fetch_row( $qid)) {
return  $value;
}

return false;
}

function sess_write( $key,  $val) {
global  $SESS_DBH,  $SESS_LIFE;

$expiry = time() +  $SESS_LIFE;
$value = addslashes( $val);

$qry = “INSERT INTO sessions VALUES ( $key,  $expiry,  $value)”;
$qid = mysql_query( $qry,  $SESS_DBH);

if (!  $qid) {
$qry = “UPDATE sessions SET expiry =  $expiry, value =  $value WHERE sesskey =  $key AND expiry > ” . time();
$qid = mysql_query( $qry,  $SESS_DBH);
}

return  $qid;
}

function sess_destroy( $key) {
global  $SESS_DBH;

$qry = “DELETE FROM sessions WHERE sesskey =  $key\”;
$qid = mysql_query( $qry,  $SESS_DBH);

return  $qid;
}

function sess_gc( $maxlifetime) {
global  $SESS_DBH;

$qry = “DELETE FROM sessions WHERE expiry < ” . time();
$qid = mysql_query( $qry,  $SESS_DBH);

return mysql_affected_rows( $SESS_DBH);
}

session_set_save_handler(
“sess_open”,
“sess_close”,
“sess_read”,
“sess_write”,
“sess_destroy”,
“sess_gc”);
?>
=================================================================
定制使用dbm文件时的接口
=================================================================
<?
/* ————————————————————————
* session_dbm.php
* ————————————————————————
* PHP4 DBM Session Handler
* Version 1.00
* by Ying Zhang (ying@zippydesign.com)
* Last Modified: May 21 2000
*
* ————————————————————————
* TERMS OF USAGE:
* ————————————————————————
* You are free to use this library in any way you want, no warranties are
* expressed or implied. This works for me, but I dont guarantee that it
* works for you, USE AT YOUR OWN RISK.
*
* While not required to do so, I would appreciate it if you would retain
* this header information. If you make any modifications or improvements,
* please send them via email to Ying Zhang <ying@zippydesign.com>.
*
* ————————————————————————
* DESCRIPTION:
* ————————————————————————
* This library tells the PHP4 session handler to write to a DBM file
* instead of creating individual files for each session.
*
* ————————————————————————
* INSTALLATION:
* ————————————————————————
* Make sure you have DBM support compiled into PHP4. Then copy this
* script to a directory that is accessible by the rest of your PHP
* scripts.
*确信你的php4有DBM支持。拷贝这个文件在你的php脚本目录。
* ————————————————————————
* USAGE:
* ————————————————————————
* Include this file in your scripts before you call session_start(), you
* dont have to do anything special after that.
* 在调用session_start()之前请包含这个文件。之后就不需要作什么工作了。
*/

$SESS_DBM = “”;
$SESS_LIFE = get_cfg_var(“session.gc_maxlifetime”);

function sess_open( $save_path,  $session_name) {
global  $SESS_DBM;

$SESS_DBM = dbmopen(“ $save_path/ $session_name”, “c”);
return ( $SESS_DBM);
}

function sess_close() {
global  $SESS_DBM;

dbmclose( $SESS_DBM);
return true;
}

function sess_read( $key) {
global  $SESS_DBM,  $SESS_LIFE;

$var = “”;
if ( $tmp = dbmfetch( $SESS_DBM,  $key)) {
$expires_at = substr( $tmp, 0, strpos( $tmp, “|”));

if ( $expires_at > time()) {
$var = substr( $tmp, strpos( $tmp, “|”) + 1);
}
}

return  $var;
}

function sess_write( $key,  $val) {
global  $SESS_DBM,  $SESS_LIFE;

dbmreplace( $SESS_DBM,  $key, time() +  $SESS_LIFE . “|” .  $val);
return true;
}

function sess_destroy( $key) {
global  $SESS_DBM;

dbmdelete( $SESS_DBM,  $key);
return true;
}

function sess_gc( $maxlifetime) {
global  $SESS_DBM;

$now = time();
$key = dbmfirstkey( $SESS_DBM);
while ( $key) {
if ( $tmp = dbmfetch( $SESS_DBM,  $key)) {
$expires_at = substr( $tmp, 0, strpos( $tmp, “|”));
if ( $now >  $expires_at) {
sess_destroy( $key);
}
}

$key = dbmnextkey( $SESS_DBM,  $key);
}
}

session_set_save_handler(
“sess_open”,
“sess_close”,
“sess_read”,
“sess_write”,
“sess_destroy”,
“sess_gc”);
?>

=================================================================
具体怎么用就不用多说了,因为这些函数都是php引擎调用的,与我们无关的。我们只需照上述配置后就行了,你用的还是以前的session函数。
看看下面的代码就知道了:)

session定制的测试代码
==================================================================
<?
/* ————————————————————————
* test.php
* ————————————————————————
* PHP4 Customer Session Handler Test Script
* Version 1.00
* by Ying Zhang (ying@zippydesign.com)
* Last Modified: May 21 2000
*/

/* default to DBM handler */
if (! isset( $handler)) {
$handler = “dbm”;
}

/* default action is increment */
if (! isset( $action)) {
$action = “increment”;
}

/* load up the appropriate session handling script, depending on the handler */
if ( $handler == “dbm”) {
include(“session_dbm.php”);

} elseif ( $handler == “mysql”) {
include(“session_mysql.php”);

} else {
echo “<li>Unrecognized handler ( $handler)”;
die;
}

/* start the session and register a simple counter */
session_start();
session_register(“count”);

/* figure out what we should do, depending on the action */
switch ( $action) {
case “increment” :
$count = isset( $count) ?  $count + 1 : 0;
break;

case “destroy” :
session_destroy();
break;

case “gc” :
$maxlife = get_cfg_var(“session.gc_maxlifetime”);
sess_gc( $maxlife);
break;

default:
echo “<li>Unknown action ( $action)”;
break;
}
?>

<h1>Session Test Script</h1>
<ul>
<li>Handler: <b><?= $handler?></b>
<li>Action: <b><?= $action?></b>
<li>Count: <b><?= $count?></b>
</ul>

<hr size=1>
<form>
<table>
<tr>
<td>Handler:</td>
<td>
<select name=”handler”>
<option value=”dbm”>DBM</option>
<option value=”mysql”>MySQL</option>
</select>
</td>
</tr>
<tr>
<td>Action:</td>
<td>
<select name=”action”>
<option value=”increment”>Increment</option>
<option value=”destroy”>Session Destroy</option>
<option value=”gc”>Force Garbage Collection</option>
</select>
</td>
</tr>
<tr>
<td></td>
<td><br><input type=”submit”></td>
</tr>
</table>
</form>
=======================================================================

三、session应用举例

以下这些例子片断仅供参考,你可以定制也可以不定制session,随你便:)
(1)用于用户认证
<?
session_start();
$dbh = mysql_connect(“localhost:3306″,”xxxx”,”xxxx”);
mysql_select_db(“znsoft”);//选择数据库
$query=”select userid from reguser where userid= $userid and pass= $pass “;
// $userid  $pass 是登录form传递过来的用户名和密码
$res=mysql_query( $query, $dbh);
if( $row=mysql_fetch( $res))
{
$reguser= $row[0];
?>
<script>
alert(“ok,哥们,欢迎你!”);
</script>
<?
}
else
{
$reguser=”";
?>
<script>
alert(“sorry,你不是注册用户!”);
</script>
<?

…………..//你自己放上代码吧
}
session_register(“reguser”);
?>
另一页面中检查是否已经登录
================
<?
session_start();

if(isset( $reguser)&& $reguser!=”")//已经登录
{
echo “欢迎你,哥们”;
}
else//没有登录呀
echo “请注册吧”;
?>
退出功能
===============================
<?
session_destroy();
//或  $reguser=”";
?>

(2)用于传递变量

本程序用于在页面之间传递变量
<?
$name=”m.y”;
if(!sesion_is_registered(“name”))//没有注册session变量 name
session_register(“name”);//注册 变量 name
?>
第二页
===================
<?
echo  $name;

//不想用了,删掉吧
if(session_is_registered(“name”))//是否注册,如果已经注册
session_unregister(“name”);//当然删掉啦
?>

优化PHP代码

1.如果一个方法可静态化,就对它做静态声明。速率可提升至4倍。

2.echo 比 print 快。

3.使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接。

4.在执行for循环之前确定最大循环数,不要每循环一次都计算最大值。

5.注销那些不用的变量尤其是大数组,以便释放内存。

6.尽量避免使用__get,__set,__autoload。

7.require_once()代价昂贵。

8.在包含文件时使用完整路径,解析操作系统路径所需的时间会更少。 阅读全文

好的PHP编程习惯

有些人呢不信,信不信呢,由你决定,反正我是信,呵呵。 进入正题:

PS:此篇文章尤其适合正在找工作面试的同志。

1、使用单引号括起来的字符串

当使用双引号来括字符串时,PHP解释器会对其进行变量替换、转义等操作,如“\n”。如果你只想输出一个基本的字符串,就用单引号吧,这样会节省一些资源。当然,如果你需要进行变量替换的,那就必须用双引号了,但其他情况下还是用单引号吧。

2、字符串的输出

你认为以下哪一条语句的运行速度最快?

print “Hi my name is $a. I am $b”;
echo “Hi my name is $a. I am $b”;
echo “Hi my name is “.$a.”. I am “.$b;
echo “Hi my name is “,$a,”. I am “,$b;
echo ‘Hi my name is ‘,$a,’. I am ‘,$b;

也许这看起来很奇怪,但事实上最后一条的运行速度是最快的。print比echo要慢,在字符串中进行变量替换时会慢,而连接字符串要比用逗号 连接来得慢,最后一句则是第一个习惯的体现。所以,不在字符串中进行变量替换不仅会加快程序运行速度,也会让你的代码在任何语法高亮显示的编辑器中显得更 为易懂(变量会被高亮显示出来)。很少人知道echo的参数可以用逗号连接,且速度会比字符串连接要来得快。最后再用上第一个习惯,那这条语句就非常好 了。 阅读全文