Reader's Digest

Digest your Internet

PHP实现文件安全下载

Written By: dch1 - May• 01•08
你一定会笑我”下载文件”如此简单都值得说?当然并不是想象那么简单。例如你希望客户要填完一份表格,才可以下载某一文件,你第一个想法一定是用”Redirect”的方法,先检查表格是否已经填写完毕和完整,然后就将网址指到该文件,这样客户才能下载,但如果你想做一个关于”网上购物”的电子商务网站,考虑安全问题,你不想用户直接复制网址下载该文件,笔者建议你使用PHP直接读取该实际文件然后下载的方法去做。程序如下:

$file_name = “info_check.exe”;

$file_dir = “/public/www/download/”;

if (!file_exists($file_dir . $file_name)) { //检查文件是否存在

echo “文件找不到”;

exit;

} else {

$file = fopen($file_dir . $file_name,”r”); //打开文件

//输入文件标签

Header(“Content-type: application/octet-stream”);

Header(“Accept-Ranges: bytes”);

Header(“Accept-Length: “.filesize($file_dir . $file_name));

Header(“Content-Disposition: attachment; filename=” . $file_name);

//输出文件内容

echo fread($file,filesize($file_dir . $file_name));

fclose($file);

exit;}

而如果文件路径是”http”或者”ftp”网址的话,则源代码会有少许改变,程序如下:

$file_name = “info_check.exe”;

$file_dir = “www.easycn.net/”;

$file = @ fopen($file_dir . $file_name,”r”);

if (!$file) {

echo “文件找不到”;

} else {

Header(“Content-type: application/octet-stream”);

Header(“Content-Disposition: attachment; filename=” . $file_name);

while (!feof ($file)) {

echo fread($file,50000);

}

fclose ($file);

}

这样就可以用PHP直接输出文件了。

php.ini 配置详细选项

Written By: dch1 - May• 01•08
php.ini 或 php3.ini 是 PHP 在启动时会读取的配置文件。该文件的存放路径为 /usr/local/lib/。在 PHP 3.x 版的配置文件为 php3.ini;而在 PHP 4.x 版改为 php.ini。若 PHP 安装成服务器的模块,则在 Web 服务器启动执行时会读取,之后就不再读取,因此改动配置的话要重新启动 Web 服务器。若使用独立 PHP CGI 方式,则每次都读一次。
要看目前的系统配置,可以用phpinfo()看到。以下为选项配置

php_value name value
配置变量名称和值。本选项需 PHP 4.x 版之后才能使用。

php_flag name on|off
配置标志布尔变量选项。本选项需 PHP 4.x 版之后才能使用。

php_admin_value name value
配置 Apache 的配置文件变量。原来在 .htaccess 的配置改到这个选项配置。本选项需 PHP 4.x 版之后才能使用。

php_admin_flag name on|off
配置布尔变量当标志。本选项需 PHP 4.x 版之后才能使用。

asp_tags boolean
配置 PHP 程序是否解析以 ASP Script 语法 <% %> 的标记 (tag)。本选项在 PHP 3.0.4 之后才可使用。更多的细节可以参考>嵌入方法的部份。

auto_append_file string
配置本选项可以让指定的文件附加在原 PHP 程序后面自动执行。若 PHP 程序中有用到 exit() 函数,则指定的文件不会执行。参数 string 即为指定自动执行的文件。

auto_prepend_file string
配置本选项可以让指定的文件在原 PHP 程序之前自动执行。参数 string 即为指定自动执行的文件。

cgi_ext string
本选项配置 CGI 程序的扩展名。

display_errors boolean
本选项配置是否要将执行的错误信息显示在用户的浏览器上。

doc_root string
配置服务器的文件及 PHP 文件放置的根目录。

engine boolean
本选项需要使用apache的模块方式使用 PHP。可配置是否要使用 PHP 引擎。在 httpd.conf 中加入 php3_engine on/off 亦可配置某目录或某虚拟网站是否要用 PHP 解析器。

error_log string
本选项用来配置错误记录文件。在 UNIX 系统上参数 string 即为文件名。Windows NT 会将记录记在事件检视器的日志之中。Windows 95/98 则不支持系统记录。

error_reporting integer
本选项用来配置系统记录的等级。参数 integer 即为等级的级数标志,可以加在一起,默认值为 7,见下表
级数 说明
1 一般的错误
2 一般的警告
4 解析错误
8 非关键的警告

open_basedir string
本选项用来配置提供 PHP 存取的最底层目录。从该指定目录之下的文件或目录,PHP 程序才能存取。使用本选项主要是为了系统安全性的考虑。参数 string 即为要限制的最底层目录节点。值得注意的是在 UNIX 系统中,若该节点之下的文件或目录有符号链结 (symbolic link),则可能会让使用本选项的目的打折,因此在目录的设计上考虑,也是 Webmaster 的重要任务。默认值是所有文件均可存取。在 PHP 3.0.7 版之后,可以配置多个底层目录。

gpc_order string
配置 GET/POST/COOKIE 三种模块的顺序及规则。参数 string 即为要配置的规则,例如:配置成 “GP” 表示忽视 cookie,并在存取方法 (method) 相同时,以 POST 取代 GET。

ignore_user_abort string
默认值为 Off。用来配置当传输未完成时,用户端断线是要继续处理。

include_path string
为 PHP 程序中 require、include 及 fopen_with_path 等函数的文件搜寻路径。在 UNIX 或 Windows 中的斜线方向不同。

log_errors boolean
指定程序错误时是否要记录在 log 文件中。

magic_quotes_gpc boolean
配置 GET/POST/COOKIE 三种模块的特殊字符,包含单引号、双引号、反斜线、及空字符 (NUL) 是否要自动加入反斜线当溢出字符。

magic_quotes_runtime boolean
配置返回资料是否自动加入反斜线当溢出字符。

magic_quotes_sybase boolean
配置 sybase 资料中单引号要自动加上反斜线当溢出字符。

max_execution_time integer
配置程序最久执行时间。单位是秒。

memory_limit integer
配置程序最多使用多少内存。

short_open_tag boolean
配置是否使用短的 PHP 标记 (<? ?>)。若不使用,则必须要用 <?php 作为程序的开头,若要使程序合乎 XML 的标准则要关闭本功能。

track_errors boolean
打开本选项可使最后的错误信息跟着全局变量 $php_errormsg。

track_vars boolean
打开本选项可让用户输入的字符串自动解析到变量之中,而不用自己处理。

upload_tmp_dir string
指定上传文件临时路径。

user_dir string
指定用户根目录的路径。

warn_plus_overloading boolean
若打开本选项,字符串间就只能用英文的句号 (.) 链接,而不能用加号 (+) 链接字符串。

SMTP string
在 Windows 系列操作系统中,用来指定 SMTP 服务器,供 mail 函数使用。参数 string 为 SMTP 服务器名字。

sendmail_from string
配置 “From: ” 字符串供 Windows 系列操作系统使用 mail 函数。

sendmail_path string
配置 sendmail 程序的放置路径。例如 /usr/sbin/sendmail。

safe_mode boolean
配置 PHP 在安全模式下执行。

safe_mode_exec_dir string
配置安全模式程序执行的路径。

debugger.host string
指定远端调试的服务器名称,可以是 IP 或 Domain Name。

debugger.port string
配置远端调试服务器的端口 (port)。

debugger.enabled boolean
配置是否可以为调试模式。

enable_dl boolean
本选项要使用apache模块 (Apache module) 的方式才有效。用来配置 PHP 的函数可否作用。当系统处于安全模式 (safe-mode) 时,本选项 enable 也无法使用 dl() 函数。

extension_dir string
配置动态函数的路径。

extension string
PHP 启动时所要载入的动态扩充功能。

mysql.allow_persistent boolean
配置是否允许 MySQL 数据库持续连接 (persistent connections),会影响函数。

mysql.max_persistent integer
配置每个处理程序最多保持几个 MySQL 持续连接。

mysql.max_links integer
配置每个处理程序最多开几个 MySQL 连接,包括持续连接。

msql.allow_persistent boolean
配置是否允许 mSQL 数据库持续连接 (persistent connections),会影响函数。

msql.max_persistent integer
配置每个处理程序最多保持几个 mSQL 持续连接。

msql.max_links integer
配置每个处理程序最多开几个 mSQL 连接,包括持续连接。

pgsql.allow_persistent boolean
配置是否允许 Postgres 数据库持续连接 (persistent connections),会影响函数。

pgsql.max_persistent integer
配置每个处理程序最多保持几个 Postgres 持续连接。

pgsql.max_links integer
配置每个处理程序最多开几个 Postgres 连接,包括持续连接。

sybase.allow_persistent boolean
配置是否允许 Sybase 数据库持续连接 (persistent connections),会影响函数。

sybase.max_persistent integer
配置每个处理程序最多保持几个 Sybase 持续连接。

sybase.max_links integer
配置每个处理程序最多开几个 Sybase 连接,包括持续连接。

sybct.allow_persistent boolean
配置是否允许 Sybase-CT 数据库持续连接 (persistent connections),默认值是打开的。

sybct.max_persistent integer
配置每个处理程序最多保持几个 Sybase-CT 持续连接。默认值为 -1 表示无限制。

sybct.max_links integer
配置每个处理程序最多开几个 Sybase-CT 连接,包括持续连接。默认值为 -1,表示没有限制。

sybct.min_server_severity integer
配置 Sybase-CT 服务器错误报告的最少笔数。默认值为 10。

sybct.min_client_severity integer
配置 Sybase-CT 客户端错误报告的最少笔数。默认值为 10。

sybct.login_timeout integer
配置 Sybase-CT 最久可以使用的登入时间。默认值为 1 分钟。

sybct.timeout integer
配置 Sybase-CT 的 query 操作时间限制。默认值为无限制。

sybct.hostname string
配置 Sybase-CT 可连接机器名称。默认值不设限

ifx.allow_persistent boolean
配置是否允许 Informix 数据库持续连接 (persistent connections),会影响函数。

ifx.max_persistent integer
配置每个处理程序最多保持几个 Informix 持续连接。

ifx.max_links integer
配置每个处理程序最多开几个 Informix 连接,包括持续连接。

ifx.default_host string
配置 Informix 默认连接的服务器名称,供ifx_connect()或ifx_pconnect()函数使用。

ifx.default_user string
配置 Informix 默认连接的用户帐号,供ifx_connect()或ifx_pconnect( 函数使用。

ifx.default_password string
配置 Informix 默认连接的用户密码,供ifx_connect()或ifx_pconnect() 函数使用。

ifx.blobinfile boolean
配置 Informix 长位类模式,0 表在内存;1 表在文件中。亦可以在 PHP 程序中使用ifx_blobinfile_mode()函数来修改。

ifx.textasvarchar boolean
配置 Informix 文字模式默认值,0 表返回 blob 的代码;1 表返回 varchar 字符串。亦可在 PHP 程序中使用ifx_textasvarchar() 函数来修改配置。

ifx.byteasvarchar boolean
配置 Informix 位组模式默认值,0 表返回 blob 的代码;1 表返回 varchar 字符串。亦可在 PHP 程序中使用ifx_byteasvarchar() 来修改配置。

ifx.charasvarchar boolean
配置 Informix 返回字符串的字尾空格是否要自动去除。

ifx.nullformat boolean
配置 NULL 字段的返回方式,true 表示返回字符串 NULL,false 表格返回字符串 “”。亦可在 PHP 程序中以ifx_nullformat() 修改。

bcmath.scale integer
配置 BC 高精确度函数库的小数点位数。

browscap string
配置浏览器的开文件能力名。

uodbc.default_db string
配置 ODBC 默认连接的数据库名称,供odbc_connect()或odbc_pconnect()函数使用。

uodbc.default_user string
配置 ODBC 默认连接的用户帐号,供odbc_connect()或odbc_pconnect()函数使用。

uodbc.default_pw string
配置 ODBC 默认连接的用户密码,供odbc_connect()或函数使用。

uodbc.allow_persistent boolean
配置是否允许 ODBC 数据库持续连接 (persistent connections),会影响odbc_pconnect()函数。

uodbc.max_persistent integer
配置每个处理程序最多保持几个 ODBC 持续连接。

uodbc.max_links integer
配置每个处理程序最多开几个 ODBC 连接,包括持续连接。
以下和 session 有关的配置值,都在 PHP 4.x 以上的版本方支持。在 php.ini 的配置文件中。

session.save_handler
定义 session 储存资料的文件名称。默认值为 files。

session.save_path
定义 session 储存资料的文件路径。默认值为 /tmp。

session.name
配置 session 所使用的 cookie 名称。默认值为 PHPSESSID。

session.auto_start
配置 session 是否自动打开。默认值为 0 (否)。

session.lifetime
配置 cookie 送到浏览器后的保存时间,单位为秒。默认值为 0,表示直到浏览器关闭。

session.serialize_handler
定义连续/解连续资料的标头,本功能只有 WDDX 模块或 PHP 内部使用。默认值为 php。

session.gc_probability
配置每笔要求回应时的废物蒐集 (gc, garbage collection) 处理机率。默认值为 1。

session.gc_maxlifetime
配置废物被清除前的存活秒数。

session.extern_referer_check
决定参照到客户端的 Session 代码是否要删除。有时在安全或其它考虑时,会配置不删除。默认值为 0。

session.entropy_file
配置 session 代码建立时,使用外部高熵值资源或文件来建立,例如 UNIX 系统上的 /dev/random 或 /dev/urandom。

session.entropy_length
配置 session 从高熵值资源读取的位组数。默认值为 0。

session.use_cookies
配置是否要将 session 变成 cookie 存在用户端。默认值为 1,表是打开本功能。

Cookie及其使用

Written By: dch1 - May• 01•08
Cookie技术是一个非常有争议的技术,自经诞生它就成了广大网络用户和Web开发人员的一个争论焦点。有一些网络用户,甚至包括一些资深的Web专家也对它的产生和推广感到不满,这倒不是因为Cookie技术的功能太弱或别的技术性能上的原因,而仅仅是因为他们觉得Cookie的使用,对网络用户的隐私构成了危害。因为Cookie是由Web服务器保存在用户浏览器上的小文本文件,它包含有关用户的信息(如身份识别号码、密码、用户在Web站点上购物的方式或用户访问该站点的次数)。

那么Cookie技术究竟怎样呢?是否真的给网络用户带来了个人隐私的危害呢?还是让我们看了下面的内容,再做回答吧。

(1)Cookie技术简介

在WEB技术发展史上,Cookie技术的出现是一个重大的变革。最先是Netscape在它的Netscape Navigator 浏览器中引入了Cookie技术,从那时起,World Wide Web 协会就开始支持Cookie标准。以后又经过微软的大力推广(因为微软的IIS Web服务器所采用的ASP技术很大程度的使用了Cookier技术),即在微软的Internet Explorer浏览器中完全支持Cookie技术。到现在,绝大多数的浏览器都支持Cookie技术,或者至少兼容Cookie技术的使用。

1)什么是Cookie?

按照Netscape官方文档中的定义,Cookie是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie是由Web服务器保存在用户浏览器上的小广西文件,它可以包含有关用户的信息(如身份识别号码、密码、用户在Web站点购物的方式或用户访问该站点的次数)。无论何时用户链接到服务器,Web站点都可以访问Cookie信息。

通俗地讲,浏览器用一个或多个限定的文件来支持Cookie。这些文件在使用Windows操作系统的机器上叫做Cookie文件,在Macintosh机器上叫做magic Cookie 文件,这些文件被网站用来在上面存储Cookie数据。网站可以在这些Cookie文件中插入信息,这样对有些网络用户就有些副作用。有些用户认为这造成了对个人隐私的侵犯,更糟的是,有些人认为Cookie是对个人空间的侵占,而且会对用户的计算机带来安全性的危害。

目前有些Cookie是临时的,另一些则是持续的。临时的Cookie只在浏览器上保存一段规定的时间,一旦超过规定的时间该Cookie就会被系统清除。例如在PHP中Cookie被用来跟踪用户进程直到用户离开网站。持续的Cookie则保存在用户的Cookie文件中,下一次用户返回时,仍然可以对它进行调用。

在Cookie文件中保存Cookie,一些用户会过分地认为这将带来很大的问题。主要是有些用户担心Cookie会跟踪用户网上冲浪的习惯,譬如用户喜爱到那些类型的站点、爱从事些什么活动等。害怕这种个人信息一旦落入一些别有用心的家伙手中,那么个人也就可能成为一大堆广告垃圾的对象,甚至遭到意外的损害。不过,这种担心压根儿不会发生,因为网站以外的用户是无法跨过网站来获得Cookie信息的。所以想以这种目的来应用Cookie是不可能的。不过,由于一些用户错误的理解以及“以讹传讹”,一些浏览器开发商别无选择,只好作出相识的响应(例如Netscape Navigator4.0和Internet Explorer3.0都提供了屏蔽Cookie的选项)。

对Cookie技术期待了这么久的结果是,迫使许多浏览器开发商在它们的浏览器中提供了对Cookie的灵活性控制功能。例如,目前的两大主流浏览器Netscape Navigator 和 Internet Explorer是这样处理Cookie的:Netscape Navigator4.0不但可以接受Cookie进行警告,而且还可以屏蔽掉Cookie;InternetExplorer3.0也可以屏蔽Cookie,但在Internet Explorer4.0中就只能进行接受警告而没有提供屏蔽选项,不过在Internet Explorer4.0之后的更新版本中又加入了屏蔽Cookie的功能选项。

此外,很多最新的技术甚至已经可以在不能屏蔽Cookie的浏览器上进行Cookie的屏蔽了。例如,可以通过将Cookie文件设置成不同的类型来限制Cookie的使用。但是,非常不幸地是,要是你想完全屏蔽Cookie的话,肯定会因此拒绝许多的站点页面。因为当今已经有许多Web站点开发人员爱上了Cookie技术的强大功能,例如Session对象的使用就离不开Cookie的支持。

尽管今天仍有一些网络用户对于Cookie的争论乐此不倦,但是对于绝大多数的网络用户来说还是倾向于接受Cookie的。因此,我们尽可以放心地使用Cookie技术来开发我们的WEB页面。

2)Cookie是怎样工作的?

要了解Cookie,必不可少地要知道它的工作原理。一般来说,Cookie通过HTTP Headers从服务器端返回到浏览器上。首先,服务器端在响应中利用Set-Cookie header来创建一个Cookie,然后,浏览器在它的请求中通过Cookie header包含这个已经创建的Cookie,并且反它返回至服务器,从而完成浏览器的论证。

例如,我们创建了一个名字为login的Cookie来包含访问者的信息,创建Cookie时,服务器端的Header如下面所示,这里假设访问者的注册名是“Michael Jordan”,同时还对所创建的Cookie的属性如path、domain、expires等进行了指定。

Set-Cookie:login=Michael Jordan;path=/;domain=msn.com;
expires=Monday,01-Mar-99 00:00:01 GMT

上面这个Header会自动在浏览器端计算机的Cookie文件中添加一条记录。浏览器将变量名为“login”的Cookie赋值为“Michael Jordon”。注意,在实际传递过程中这个Cookie的值是经过了URLEncode方法的URL编码操作的。
这个含有Cookie值的HTTP Header被保存到浏览器的Cookie文件后,Header就通知浏览器将Cookie通过请求以忽略路径的方式返回到服务器,完成浏览器的认证操作。

此外,我们使用了Cookie的一些属性来限定该Cookie的使用。例如Domain属性能够在浏览器端对Cookie发送进行限定,具体到上面的例子,该Cookie只能传达室到指定的服务器上,而决不会跑到其他的如www.hp.com的Web站点上去。Expires属性则指定了该Cookie保存的时间期限,例如上面的Cookie在浏览器上只保存到1999年3月1日1秒。当然,如果浏览器上Cookie太多,超过了系统所允许的范围,浏览器将自动对它进行删除。至于属性Path,用来指定Cookie将被发送到服务器的哪一个目录路径下。

说明:浏览器创建了一个Cookie后,对于每一个针对该网站的请求,都会在Header中带着这个Cookie;不过,对于其他网站的请求Cookie是绝对不会跟着发送的。而且浏览器会这样一直发送,直到Cookie过期为止。

上一部分讲了有关Cookie的技术背景,这部分来说说在PHP里如何设置、使用、删除Cookie,及Cookie的一些限制。PHP对Cookie支持是透明的,用起来非常方便。

1、设置Cookie

PHP用SetCookie函数来设置Cookie。必须注意的一点是:Cookie是HTTP协议头的一部分,用于浏览器和服务器之间传递信息,所以必须在任何属于HTML文件本身的内容输出之前调用Cookie函数。
SetCookie函数定义了一个Cookie,并且把它附加在HTTP头的后面,SetCookie函数的原型如下:
int SetCookie(string name, string value, int expire, string path, string domain, int secure);
除了name之外所有的参数都是可选的。value,path,domain三个参数可以用空字符串代换,表示没有设置;expire 和 secure两个参数是数值型的,可以用0表示。expire参数是一个标准的Unix时间标记,可以用time()或mktime()函数取得,以秒为单位。secure参数表示这个Cookie是否通过加密的HTTPS协议在网络上传输。
当前设置的Cookie不是立即生效的,而是要等到下一个页面时才能看到.这是由于在设置的这个页面里Cookie由服务器传递给客户浏览器,在下一个页面浏览器才能把Cookie从客户的机器里取出传回服务器的原因。
在同一个页面设置Cookie,实际是从后往前,所以如果要在插入一个新的Cookie之前删掉一个,你必须先写插入的语句,再写删除的语句,否则可能会出现不希望的结果。
来看几个例子:
简单的:
SetCookie(“MyCookie”, “Value of MyCookie”);
带失效时间的:
SetCookie(“WithExpire”, “Expire in 1 hour”, time() 3600);//3600秒=1小时
什么都有的:
SetCookie(“FullCookie”, “Full cookie value”, time() 3600, “/forum”, “.phpuser.com”, 1);

这里还有一点要说明的,比如你的站点有几个不同的目录,那么如果只用不带路径的Cookie的话,在一个目录下的页面里设的Cookie在另一个目录的页面里是看不到的,也就是说,Cookie是面向路径的。实际上,即使没有指定路径,WEB服务器会自动传递当前的路径给浏览器的,指定路径会强制服务器使用设置的路径。解决这个问题的办法是在调用SetCookie时加上路径和域名,域名的格式可以是“www.phpuser.com”,也可是“.phpuser.com”。
SetCookie函数里表示value的部分,在传递时会自动被encode,也就是说,如果value的值是“test value”在传递时就变成了“test value”,跟URL的方法一样。当然,对于程序来说这是透明的,因为在PHP接收Cookie的值时会自动将其decode。
如果要设置同名的多个Cookie,要用数组,方法是:
SetCookie(“CookieArray[]”, “Value 1”);
SetCookie(“CookieArray[]”, “Value 2”);

SetCookie(“CookieArray[0]”, “Value 1”);
SetCookie(“CookieArray[1]”, “Value 2”);

2、接收和处理Cookie

PHP对Cookie的接收和处理的支持非常好,是完全自动的,跟FORM变量的原则一样,特别简单。
比如设置一个名为MyCookier的Cookie,PHP会自动从WEB服务器接收的HTTP头里把它分析出来,并形成一个与普通变量一样的变量,名为$myCookie,这个变量的值就是Cookie的值。数组同样适用。另外一个办法是引用PHP的全局变量$HTTP_COOKIE_VARS数组。
分别举例如下:(假设这些都在以前的页面里设置过了,并且仍然有效)
echo $MyCookie;
echo $CookieArray[0];
echo count($CookieArray);
echo $HTTP_COOKIE_VARS[“MyCookie”];
就这么简单。

3、删除Cookie

要删除一个已经存在的Cookie,有两个办法:
一是调用只带有name参数的SetCookie,那么名为这个name的Cookie将被从关系户机上删掉;另一个办法是设置Cookie的失效时间为time()或time()-1,那么这个Cookie在这个页面的浏览完之后就被删除了(其实是失效了)。
要注意的是,当一个Cookie被删除时,它的值在当前页在仍然有效的。

4、使用Cookie的限制

首先是必须在HTML文件的内容输出之前设置;
其次不同的浏览器对Cookie的处理不一致辞,且有时会出现错误的结果。比如:MS IE SERVICE PACK 1不能正确处理带域名和路径的Cookie,Netscape Communicator 4.05和MS IE 3.0不能正确处理不带路径和时间的Cookie。至于MS IE 5 好象不能处理带域名、路径和时间的Cookie。这是我在设计本站的页面时发现的。
第三个限制是在客户端的。一个浏览器能创建的Cookie数量最多为30个,并且每个不能超过4KB,每个WEB站点能设置的Cookie总数不能超过20个。

关于Cookie的话题,就说到这儿了。