個人檔案aimee部落格網路 工具 說明

部落格


10月24日

LAMPP 使用文档

About XAMPP
XAMPP一个很好的WEB服务器安装包,使用方便功能强大。这里介绍一下它,还有安装配置的心得。
到这里首先要介绍的就是XAMPP,因为我很多LINUX的工作和文档都基于XAMPP的.下载和介绍的网址: http://sourceforge.net/projects/xampp/
现在XAMPP Linux的最新版本是1.5 .使用了几个月觉得挺不错,比较方面,功能比较强.官方的介绍是这样的:XAMPP is a very easy to install Apache Distribution for Linux, Solaris, Windows and MacOS X. The package includes the Apache web server, MySQL, PHP, Perl, a FTP server and phpMyAdmin.
有多种平台版本,集成Apache , MySQL, PHP,安装方便,解压缩就可以用.下面介绍一下安装和配置
1.先把xampp-linux-1.5.0.tar.gz下载到/opt/,如果本来已经安装了apache,mysql需要先关闭,并设置不启动
service httpd stop
service mysqld stop
chkconfig httpd off
chkconfig mysqld off
2.解压缩并运行
cd /opt/
tar xvfz xampp-linux-1.5.0.tar.gz -C /opt
3.启动
/opt/lampp/lampp start
4.安全配置,设置XAMPP页面和MYSQL等密码,按照提示设置就可以了.
/opt/lampp/lampp security
5.设置随系统自动启动,系统重启XAMPP是不会自动启动的,需要设置
ln -s /opt/lampp/lampp /etc/rc.d/rc3.d/S99lampp
ln -s /opt/lampp/lampp /etc/rc.d/rc4.d/S99lampp
ln -s /opt/lampp/lampp /etc/rc.d/rc5.d/S99lampp
6.修改apache,php等配置文件,配置文件都在/opt/lampp/etc里面
#修改httpd.conf设置,修改用户和用户组为apache,设置默认编码
vi /opt/lampp/etc/httpd.conf
User apache
Group apache
AddDefaultCharset GB2312
php.ini的配置方法可以上网找找,这里不作讨论
因为修改了用户和组,需要设置目录权限.
chown -R apache.apache /opt/lampp/htdocs/
chown -R apache.apache /opt/lampp/phpmyadmin/
如果没有apache用户和组要先添加
groupadd apache
useradd -g apache apache
配置完毕需要重启xampp
/opt/lampp/lampp restart

web授权Ip访问

做一套商业程序,如只充许客户只能用于一台服务器,授权验证就很重要了。以下是我的一个想法,把服务器的php环境配置也应用在程序里面,生成一个许可字串,然后将字串写入到许可的文件代码中。就算是将程序原本不动地移到其它服务器上,程序都不能运行了。希望大家多多讨论……
[php]
/**
*授权字串
*/
function authorization ($seed = '') {
$encode = $_SERVER['SERVER_SOFTWARE'] . $_SERVER['SERVER_NAME'] . $_SERVER['DOCUMENT_ROOT'] .
$_SERVER['SERVER_ADMIN'] . $_SERVER['SERVER_ADDR'] . PHP_VERSION . PHP_OS . __FILE__;
return md5 ($encode);
}

$authorization_key = 'qh8.net';
echo authorization($authorization_key);//这里是生成字符串验证
$authorization_check = array('dd670852938815f3892d3c511cc8fceb','ddc976cc02bce5c3c22c4d7d201c0cae' );//授权字串,把生成的字符验证复制到这里来

if (!in_array(authorization ($authorization_key), $authorization_check)) {
die('对不起,你的程序未经过授权!!');
}
[/php]

session全教程(二)

二、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:a/pache,并将phplib下的pages 目录下的文件和目录一起拷贝到 d:/apache/htdocs下,注意不带目录本身。phplib的类库需要根据系统进行初始化,你可以修改local.inc文件,其中包含着一些基本参数,你可以根据自己机器的实际情况来进行修改。 将d:/apache/php/prepend.php3文件中的一段程序改为如下样子:

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

然后将d:/apache/php/local.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, dele 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 don't 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
* don't 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>Can't 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 don't 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
* don't 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;

dbmdele($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概述

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多的唯一的优点了。

变量的变量,PHP和你

在我最近做的一个项目中,我发现了一个新的概念,关于在PHP中使用变量的变量。在我的程序中,我需要在一个页面同时更新多个记录,在我经?嗟背な奔涞耐纯嗨妓髦?螅?院V信既坏厣料殖隽吮淞康谋淞浚?ariable variable)这一概念,所有的困惑就一扫而光了。

介绍

什么叫作变量的变量?根据PHP手册,变量的变量是指取得一个变量的值并把它作为另一个变量的变量名。这表述显得相当的直接,容易和那些在一个句子中使用“变量”这个词弄混淆。给一个简单的例子,你定义一个变量 --- x 等于 this --- 然后定义一个变量的变量,意味着你把 x 的值作为新变量的名,在这个例子中,这个新变量的值是 is cake。用PHP来表示如下:

<?php

$x = "this";
$$x = "is cake";

?>

这个符号$$是在PHP中对变量的变量的表示方法。现在我们可以用两种不同的方式来引用这两个变量 $x 和 $$x 了。

<?php

echo "$x ${$x}";

?>

<?php

echo "$x $this";

?>

上面两段程序都将输出 this is cake。注意,在echo语句中$$x被写成${$x},这是让PHP知道你要输出的是变量的变量而不是一个$字符与$x变量。

你是不是仍很迷惑?哦,也许吧,你想要一些更深入更有用的例子?下一节,我将向你展示怎样用变量的变量在一个页面编辑多条记录的。


例子

假设你已有一个MySQL数据库,保存了对一些感兴趣的站点的链接,库中有一个表submissions,字段如下:

SubmissionID
PostedBy
Link
Description
Approved

现在你想显示在表中所有的已创建但没有被认可的链接,这个编辑的页面应可以更正一些输入时的错误,并用适当的单选按钮来为每一个记录设置是否允许(Approved),然后一次把更新后的记录都提交到表中。

首先,当你从数据库出提取所有的记录并显示出来时,你必须为每一个记录设置一个唯一的名字,这将让我们在提交时可以循环地辩别出各个记录的值。代码如下:

<?php

//初始化变量的记数器

$index = 0;
$index_count = 0;

echo "<form method=post action=$PHP_SELF>n";
echo "<table>n";
echo "<tr><td><b>Posted By</b></td><td><b>Link</b></td>".
"<td><b>Description</b></td><td><b>Approved</b></td></tr>n";


/*********
假定我们已从数据库中检索出记录到一个数组中 
$myrow = mysql_fetch_array().
下面的 do...while 循环根据名字为每一个$xstr变量分配了一个值并且连接了$index 的值到结尾,以0为开始。
这样,这个循环的第一次时,$SubmissionIDStr 的值就是 SubmissionID0 ,第二次就是 SubmissionID1 ,以此类推。
***********/

do {

$SubmissionIDStr = SubmissionID.$index;
$PostedByStr = PostedBy.$index;
$LinkStr = Link.$index;
$DescriptionStr = Description.$index;
$ApprovedStr = Aprroved.$index;


//这一段将在屏幕上显示值,以每行一条记录。

printf("<tr><td><input type=hidden name=%s value=%s><input type=text name=%s value=%s></td>
<td><input type=text name=%s value=%s></td><td><input type=text name=%s value=%s></td>
<td><input type=radio name=%s value=-1>Yes<input type=radio name=%s value=0 checked>No</td></tr>n",
$SubmissionIDStr, $myrow["SubmissionID"], $PostedByStr, $myrow["PostedBy"], $LinkStr, $myrow["Link"],
$DescriptionStr, $myrow["Description"], $ApprovedStr, $ApprovedStr);


//每个循环记数器加1

$index ;
$index_count ;

} while ($myrow = mysql_fetch_array($result));

// 创建一个索引记数器index_count来跟踪所有的记录数

echo "<INPUT TYPE=hidden NAME=counter VALUE=$index_count>n";

echo "<INPUT TYPE=submit></form>n";

?>

提交以后,我们利用$index_count变量再一次循环遍历页面上所有的变量,然后,分配这些变量给另一些变量,这就用到了变量的变量。

<?php

//这个循环遍历所有页面上显示的记录

for ($index = 0; $index <= $counter; $index ) {


/*****
这部分用我们在前面创建的名字设置了新的变量
从0开始,直到$index_count
*****/

$varSubmissionID = 'SubmissionID'.$index;
$varPostedBy = 'PostedBy'.$index;
$varLink = 'Link'.$index;
$varDescription = 'Description'.$index;
$varApproved = 'Approved'.$index;


/******
这是变量的变量部分,把每个值分配给每个新变量的名。
例如,第一次循环时,分配给记录 SubmissionID0 是从前面得来的值,我们用变量的变量来了取到它。
*******/

$SubmissionIDvalue = $$varSubmissionID;
$PostedByvalue = $$varPostedBy;
$Linkvalue = $$varLink;
$Descriptionvalue = $$varDescription;
$Approvedvalue = $$varApproved;


//更新数据库

$sql = "UPDATE submissions SET PostedBy='$PostedByvalue',Link='$Linkvalue',".
"Description='$Descriptionvalue' WHERE SubmissionID=$SubmissionIDvalue'";
$result = mysql_query($sql);


//如果本记录被设置为approved,更新相应的字段 Approved。

if ($Approvedvalue == '-1') {
$sql = "UPDATE submissions SET Approved='-1' WHERE SubmissionID=$SubmissionIDvalue";
$result = mysql_query($sql);
}

}

?>

我希望这有助于你明白这个变量的变量的基本用法,并且在你将来的工作中使用它们提供一些思路。变量的变量这一概念,最初也是让我头痛的东西,但是一旦你知道了它们工作的基本原理时,它们就变成了一块美味的比萨饼。

初学入门 PHP 和 MySQL

我想要使用PHP和MySQL,但是如何安装和运行呢?什么是最基本的事情我应该知道的,以便让一个简单
的PHP - MySQL应用程序工作?

  这是一个基本的教程。没有怪异的代码,只是一些基础。

  多说一句,现在有大量的教程是基于UNIX机器的,这个教程将集中在基于Windows平台上。然而,除了
安装部分,有或多或少的针对于Windows的说明外,其它部分对所有的平台都是一样的。

  在这个教程中,我们将一步一步地建立一个小的网站,使用了PHP和MySQL的下面特性:

  1. 查看数据库;
  2. 编辑数据库的记录;
  3. 修改数据库的记录;
  4. 删除数据库的记录。

  我们将同时学习MySQL和PHP,一起去感觉它们。

第一节 - 收集和建立必要的项目

  好,开始工作。为了开始PHP-MySQL我们需要一些准备:

  1. 运行web服务器;
  2. 增加PHP扩展;
  3. 运行MySQL。

  第一步,得到和安装Web服务器

  让我们假设一下在你的机器上已经有一个运行着的web服务器。在Windows下有几个好用的web服务器应
用程序。要注意一件事,为了运行php/mysql你所选的web服务器应当可以支持扩展。

  一个在Windows上最容易安装的服务器是OmniHTTPd(http://www.omnicron.ab.ca/httpd/,它是一个非
常好的自由web服务器。

  一旦你从站点上得到了安装文件,双击它并且安装web服务器。如果你在安装时全部选择了使用缺省值,
那么你将会把它安装在c:\httpd下。一旦安装成功,安装程序将启动web服务器,带有一个欢迎窗口,在
windows的系统托盘中可以看到一个新的图标。

  好了,第一步做完了。

  第二步,下载和安装PHP发行版

  得到PHP Win32发行版很容易:只要去http://www.php.net/download-php.php3,并且选择一个最好的
位置就可以了。

  在OmniHTTPd上安装PHP非常简单。

  最先Unzip安装文件到你的硬盘上,比如展开在c:\php。

  拷贝文件'php3.ini-dist'到你的'%WINDOWS'目录下去,并改名'php3.ini'(在Win95/98为c:\windows,在
WinNT/Win2k为c:\winnt)。

  按下面编辑php3.ini文件:

  改变'extension_dir'设置为你的PHP安装目录(c:\php),或存放'php3_*.dll'的目录。

  选择想在PHP启动时装入的模块。你应该将'extension=php3_*.dll'行的注释去掉来装入这些模块(一定
要确认去掉了extension=php3_mysql.dll的注释)。一些模块要求有额外的库安装在你的系统上才能正常工作。

  PHP问答集(http://www.php.net/FAQ.php3)有更多关于如何得到支持库的信息。你可以通过使用:
dl("php_*.dll")动态地装入一个模块。

  PHP扩展库以'php3_'为前缀。这个可以防止在PHP扩展与它们的支持库之间发生混淆。

  现在跟着简单的步骤配置OmniHTTPd:

  在系统托盘中右击蓝色的OmniHTTPd图标,选项属性(Properties)项;

  点击Web Server Global Settings项;

  点中'External'tab标签。现在,在"Virtual"域中输入".php3",在"actual"域中输入"c:\php\php.exe",
然后单击"Add"。

  选择Mime tab标签并且在"Vritual"中输入"wwwserver/stdcgi",在"Actual"中输入".php3",并单
击"Add"。

  单击 OK。

  在同一个窗体中选择Default Virtual Settings;

  现在单击Server tab标签;

  在"Default Index"域中输入"Index.php3"(用逗号分隔)。这将告诉web服务器也可以识别index.php3文件。

  单击 OK。

  好,足够了。让我们测试一下PHP是否在工作:

  创建一个名为index.php3的文本文件,写入下面的文本:

<?
echo "I made it!";
?>

  启动你的浏览器,并指到localhost。你应该在屏幕上得到"I made it!"。

  下面,得到和安装MySQL:

  去http://www.mysql.com/download_win.html,下载MySQL-Win32发行版,将zip文件解压到一个临时目
录并且运行安装程序(setup.exe)。

  如果你选择了缺省的典型安装,所有的MySQL文件将会安装到c:\mysql目录下。

  现在,跟着以下步骤,每一步都要执行正确。

  进行一些测试:

  首先,你要先运行mysqld-shareware.exe守护程序,它位于c:\mysql\bin下。你可以看到一个dos窗口,
并在几秒钟后关闭。如果没有显示错误信息,MySQLd就已经运行了。

  如果想检查一下MySQL,只要运行c:\mysql\bin\mysql。你将会看到有"mysql>"提示符的终端窗口。很
好,我们可以同MySQL服务器进行对话了。

第二部分 -- 创建和操纵一个MySQL数据库:

  首先我们需要创建要使用的数据库和表。数据库起名为"example",表名为"tbl",有以下字段:识别号,
名,姓和信息。要通过mysql终端完成建库和定义表的工作,只要双击或运行c:\mysql\bin\mysql.exe。

  如果要看在MySQL中已经定义了哪些表,可以使用(注意mysql>是终端提示符):

Mysql> show databases; <回车>

  这个命令可能显示如下信息:

 

----------
| Database |
----------
| mysql |
| test |
----------
2 rows in set (0.01 sec)

  为了定义一个新的数据库(example),键入:

Mysql> create database example; <回车>

  你将会看到一个回答,如:

Query OK, 1 row affected (0.17 sec)

  很发,我们现在有了一个新数据库了。现在我们可以在库中建立一个新表,但首先我们需要先选中新的
数据库:

Mysql> use example; <回车>

  回答应该是:

Database changed

  现在我们可以建表了,有如下字段:

  索引号 - 整数
  用户名 - 最大长度为30的字符串
  用户姓 - 最大长度为50的字符串
  自由信息 - 最大长度为100的字符串

  在MySQL提示符下键入下面的命令来创建表:

MySQL> create table tbl (idx integer(3), UserName varchar(30), LastName varchar(50), FreeText varchar(100));<回车>

  回答应该是:

Query OK, 0 rows affected (0.01 sec)

  好,让我们看一下从MySQL提示符下看表是什么样子的,键入命令:

MySQL> show columns from tbl; <回车>

  我们将得到下面的结果:


---------- -------------- ------ ----- --------- -------
| Field | Type | Null | Key | Default | Extra |
---------- -------------- ------ ----- --------- -------
| idx | int(3) | YES | | NULL | |
| UserName | varchar(30) | YES | | NULL | |
| LastName | varchar(50) | YES | | NULL | |
| FreeText | varchar(100) | YES | | NULL | |
---------- -------------- ------ ----- --------- -------
4 rows in set (0.00 sec)


  在这里,我们可以看到刚创建的表"tbl"的内容。

  现在让我们看一下表中有什么内容。键入下面的命令:

MySQL> select * from tbl;<回车>

  这个命令是用来显示表"tbl"中的所有数据的。输出可能是:

Empty set (0.07 sec)

  之所以得到这个结果,是因为我们还没有在表中插入任何数据。让我们往表中插入一些数据,键入:

MySQL> insert into tbl values (1,'Rafi','Ton','Just a test');<回车>
Query OK, 1 row affected (0.04 sec)

  如上所见,我们插入到表中的值是按照前面我们定义表的顺序,因为使用的是缺省的顺序。我们可以设
定数据的顺序,语法如下:

MySQL> insert into tbl (idx,UserName,LastName,FreeText) values (1,'Rafi','Ton','Just a test');<回车>

  好,现在我们可以再看一下表中的内容:

MySQL> select * from tbl;<回车>

  这次的结果是:


------ ---------- ---------- -------------
| idx | UserName | LastName | FreeText |
------ ---------- ---------- -------------
| 1 | Rafi | Ton | Just a test |
------ ---------- ---------- -------------
1 row in set (0.00 sec)

  现在我们可以看到表的结构和每一个单元格的内容。

  现在我们想删除数据。为了实现我们应该键入:

MySQL> delete from tbl where idx=1 limit 1;<回车> Query OK, 1 row affected (0.00 sec)

   好,给出一些解释。我们正在告诉MySQL从"tbl"表中删除记录,删除那些idx字段值为1的记录,并且
只限制删除一条记录。如果我们不限制删除记录数为1,那么所有idx为1的记录都将被删除(在这个例子中
我们只有一条记录,但是虽然如此,我只是想让这一点更加清楚)。

  不幸的是,我们又一次得到了一个空表,所以让我们再输进去:

MySQL> insert into tbl values (1,'Rafi','Ton','Just a test');<回车>
Query OK, 1 row affected (0.04 sec)

  另一件可以做的事是,修改指定字段的内容,使用"update"命令:

MySQL>update tbl set UserName='Berber' where UserName='Rafi';<回车>
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

  这个命令将搜索所有UserName为"Rafi"的记录,并将它改为"Berber"。注意,set部分和where部分不一
定要一样。我们可以索搜一个字段但是改变另一个字段。而且,我们可以执行两个或更多条件的搜索。

MySQL>update tbl set UserName='Rafi' where UserName='Berber' and LastName='Ton';<回车>
Query OK, 1 row affected (0.04 sec)

  这个查询搜索了两个字段,改变了UserName的值。

第三部分 - 组合PHP与MySQL

  在这个部分里,我们将建立一个建单的基于PHP的web站点,用来控制前面所建的MySQL的表。

  我们将建立下面的站点结构(假设你已经知道一些基本的HTML的知识):

  1. index.php3 用于前端查看表
  2. add.php3 用于往表中插入数据
  3. Modify.php3 用于修改表中的记录
  4. del.php3 用于删除表中的记录

  首先,我们想查看一下数据库:

  看一下下面的脚本。

--------------------------------------------------------------------------------
Index.php3:

<html>
<head><title>Web Database Sample Index</title>
</head>
<body bgcolor=#ffffff>
<h2>Data from tbl</h2>

<?
mysql_connect() or die ("Problem connecting to DataBase");
$query = "select * from tbl";
$result = mysql_db_query("example", $query);

if ($result) {
echo "Found these entries in the database:<br><p></p>";
echo "<table width=90% align=center border=1><tr>
<td align=center bgcolor=#00FFFF>User Name</td>
<td align=center bgcolor=#00FFFF>Last Name</td>
<td align=center bgcolor=#00FFFF>Domain Name</td>
<td align=center bgcolor=#00FFFF>Request Date</td>
</tr>";

while ($r = mysql_fetch_array($result)) <BR>{
$idx = $r["idx"];
$user = $r["UserName"];
$last = $r["LastName"];
$text = $r["FreeText"];

 

echo "<tr>
<td>$idx</td>
<td>$user</td>
<td>$last</td>
<td>$text</td>
</tr>";
}
echo "</table>";
}
else
{
echo "No data.";
}

mysql_free_result($result);
include ('links.x');
?>

</body>
</html>--------------------------------------------------------------------------------
  好,下面给出一些说明:

  我们先用正常的html标签创建thml文档。当我们想从html中出来转入PHP中时,我们用<?来打开PHP部分,
这个告诉web服务器将后面的文本看成是PHP语法而不是一般的html。使用?>来结束PHP部分。

  mysql_connect() 命令告诉PHP建立一个与MySQL服务器的连接。如果连接建立成功,脚本将继续,如果
不成功,则打印出die命令的信息“Problem connecting to Database”(如果要看关于mysql_connect的更
多的信息和其它的PHP函数,可以去http://www.php.net下的文档中查找)。

  现在,如果MySQL是按照我们上面所讨论的那样安装的,就足够了。但是如果你使用的是预装的MySQL(象
ISP),你应该使用下面的命令:

mysql_connect (localhost, username, password);

  我们可以将$query设成我们想在MySQL中执行的查询,然后使用mysql_db_query命令来执行它:

$result = mysql_db_query("example", $query);

  这时,"example"表示数据库的名字并且$query是要进行的查询。

  我们使用MySQL命令select(象上面所描述的)来从表中取得所有的数据:

$query = "select * from tbl";

  简单地解释一下$result的作用,如果执行成功,函数将返回一个查询结果的一个MySQL结果标识符,如
果出错则返回false。返回的不是结果而是一个标识符,可以在后面将它转换成我们所需的信息。

  现在,我们想检查一下在数据库中是否存在有记录,并且如果有则将结果按照html的表格结构打印出来。

  为了检查是否存在数据,我们使用if命令和下面的语法:

if (argument) {
"do something;"
} else {
"do something different;"
}

  这时"do something"当argument=true时你所要执行的命令,"do something different"为当argument =
false时所要执行的命令。

  注意我们使用echo命令来输出一些html标签来建立html的表格结构。只有从PHP命令输出的文本才会被
看成html内容 - PHP命令本身是不会看成html内容的。

  我们使用的另一个命令是while指令,使用格式如下:

while (argument)) {
"something to do";
}

  while循环在argument=true时会不停地重复,执行在{}中的指令集。

  这里我们组合了while循环和PHP函数$r=mysql_fetch_array($result)。这个函数根据相应的结果标识
符取回一条记录,并且将结果放在一个相关数组(associative array)$r中,它使用字段的名字作为数组的
键值。在我们的脚本中,我们将得到一个数组:$r['idx'],$r['UserName'],$r['LastName']和
$r['FreeText']。

  我们也可以使用mysql_fetch_row函数,它会将结果放在一个有序的数组中,我们可以使用$r[0],$r[1],
$r[2]和$r[3]来得到相应的值。

  要了解关于这些函数的更深入的信息请访问http://www.php.net。

  现在,我们有了所有的信息,我们可以把它在html表格中打印出来:

 

echo "<tr>
<td>$idx</td>
<td>$user</td>
<td>$last</td>
<td>$text</td>
</tr>";

  现在我们可以释放MySQL连接,并且释放一些资源,通过使用mysql_free_result($result)函数。

  PHP另一个有用的特性是在脚本中包括文本文件的功能。让我们假设你有一些可重用的代码(例如到其
它页面的链接),我们可以使用include函数,这样可以节省一些代码和时间。而且,如果想改变这些代码,
我们只需要改变包含文件的内容,它将会在所有包括它的文件中生效。

  这里我们创建一个名为Links.x的文本文件,它将存放我们想用在每一个页面中的全部链接菜单。


<p></p>
<ul>
<li><a href="index.php3">Home</a>
<li><a href="add.php3">Add a new entry to the DataBase</a>
<li><a href="edit.php3">Edit an entry</a>
<li><a href="del.php3">Delete an entry from the DataBase</a>
</ul>

  include的语法是:

Include ('included_text_file');

  现在我们可以用?>来关闭PHP部分,并且用</body></html>来结束html页面。

  使用表单增加数据

  让我们看一下下面的代码:

--------------------------------------------------------------------------------
<html>
<head><title>Add an entry to the database</title>
</head>
<body bgcolor=#ffffff>

<h1>Add an entry</h1>

<form method="post" action="add2tbl.php3">
<table width=90% align=center>

<tr><td>Index:</td><td><input type=text name="idx" size=3 maxlength=3></td></tr>

<tr><td>UserName:</td><td><input type=text name="UserName" size=40
maxlength=100></td></tr>

<tr><td>LastName:</td><td><input type=text name="LastName" size=40
maxlength=100></td></tr>

<tr><td>FreeText:</td><td><input type=text name="FreeText" s=40 maxlength=100></td></tr>

<tr><td></td><td><input type=submit value=add></td></tr>

</form>
</table>

<?php include ('links.x');?>

</body>
</html>
--------------------------------------------------------------------------------
  假设你对表单很熟悉,这是一个相当简单的脚本。我们根据html页面设计了一个表单,它在提交后调用
add2tbl.php3脚本。现在,表单与MySQL表相对应由4个字段组成:index number,FirstName,LastName和
FreeText。注意在这个表单中字段名字与MySQL表中字段名一样,但这只是为了方便起见而不是必须。

  我们再一次使用了include命令<? include ('links.x');?>(象在前面所解释的)来增加链接。

  让我们看一下add2tbl.php3脚本:

--------------------------------------------------------------------------------
<html>
<body>

<?
if ($UserName)
{
mysql_connect() or die ("Problem connecting to DataBase");
$query = "insert into tbl values ('$idx','$UserName','$LastName','$FreeText')";
$result = mysql_db_query("example", $query);

echo "Data inserted. new table:<br><p></p>";
$query = "SELECT * FROM tbl";
$result = mysql_db_query("example", $query);

if ($result)
{
echo "<table width=90% align=center border=1><tr>
<td align=center bgcolor=#00FFFF>idx</td>
<td align=center bgcolor=#00FFFF>User Name</td>
<td align=center bgcolor=#00FFFF>Last Name</td>
<td align=center bgcolor=#00FFFF>Free Text</td>
</tr>";

while ($r = mysql_fetch_array($result))
{
$idx = $r["idx"];
$user = $r["UserName"];
$last = $r["LastName"];
$free = $r["FreeText"];

echo "<tr>
<td>$idx</td>
<td>$user</td>
<td>$last</td>
<td>$free</td>
</tr>";

} // while循环结束
echo "</table>";
}
else
{
echo "No data.";
} // if结束($result)
}
else
{
echo "No UserName Entered. Please go back and reenter UserName";
} // if结束($UserName)

echo "<p></p>";

include ('links.x');

?>

</body>
</html>--------------------------------------------------------------------------------
解释:

  这一部分包含两个主要部分。第一部分从前一个表单中得到数据,并将它们插入到数据库中。第二部分
从数据库中打印出表的内容。第二部分同我在查看数据库部分中所演示的一样。

  第一部分:

  首先我们象通常一样使用mysql_connect()来同数据库连接。

  然后我们使用下面查询:

$query = "insert into tbl values ('$idx','$','$LastName','$FreeText')";

  这个查询使用从前面表单传递过来的$idx,$UserName,$LastName和$FreeTExt变量,并将它们插入到
tbl表中。

  注意,我在脚本中所作的注释。使用一个注释可以用"//",服务器将忽略此行的后面部分。

  简单,不是吗?

  从数据库中编辑一条记录:

  让我们假设一下,我们想修改数据库中存在的记录。在前面,我们看到有一个叫set的SQL命令用来设置
数据库中存在字段的值。我们将使用这个命令来修改数据库中的整条记录。

  考虑下面的脚本:
--------------------------------------------------------------------------------
edit.php3:

<html>
<head><title>Editing an entry from the database</title>
</head>

<body bgcolor=#ffffff>
<h1>Edit an entry</h1

<?

mysql_connect() or die ("Problem connecting to DataBase");
$query = "select * from tbl";
$result = mysql_db_query("example", $query);

if ($result)
{
echo "Found these entries in the database:<br>";
echo "<table width=90% align=center border=1><tr>
<td align=center bgcolor=#00ffff>idx</td>
<td align=center bgcolor=#00FFFF>User Name</td>
<td align=center bgcolor=#00FFFF>Last Name</td>
<td align=center bgcolor=#00FFFF>Free Text</td>
</tr>";

while ($r = mysql_fetch_array($result))
{
$idx = $r["idx"];
$user = $r["UserName"];
$last = $r["LastName"];
$text = $r["FreeText"];

echo "<tr>
<td align=center>
<a href=\"editing.php3?idx=$idx&user=$user&last=$last&text=$text\">$idx</a></td>
<td>$user</td>
<td>$last</td>
<td>$text</td>
</tr>";

}
echo "</table>";
}
else
{
echo "No data.";
}

mysql_free_result($result);
include ('links.x');

?>

</body>
</html>--------------------------------------------------------------------------------
  如你所见,这里的代码有些熟悉。第一部分只是打印出数据库中表的内容。注意,有一行不太一样:

<a href=\"editing.php3?idx=$idx&user=$user&last=$last&text=$text\">$idx</a>

  这一行建立了一个到editing.php3的一个链接,并且给新的脚本传递了一些变量。同表单方式很象,只
是使用的是链接。我们将信息转换成:变量和值。注意,为了打印出 " 符号,我们需要使用 \"否则服务器
将把它看成PHP脚本的一部分并且作为被打印的信息。

  我们想将数据库中的记录全部转换到过,这样我们就可以得到表中的确切的数据,以便我们修改它容易
一些。

--------------------------------------------------------------------------------
Editing.php3:

<html>
<head><title>Editing an entry</title>
</head>

<body bgcolor=#ffffff>
<h1>Editing an entry</h1>
<form method="post" action="editdb.php3">

<table width=90% align=center>

<tr><td>idx:</td><td><?php echo "$idx";?></td></tr>

<tr><td>UserName:</td><td><input type=text name=UserName size=40 maxlength=100
value="<?php echo "$user";?>"></td></tr>

<tr><td>LastName:</td><td><input type=text name=LastName size=40 maxlength=100
value="<?php echo "$last";?>"></td></tr>

<tr><td>Free Text:</td><td><input type=text name=FreeText size=40 maxlength=100
value="<?php echo "$text";?>"></td></tr>

<tr><td></td><td><input type=submit value="Edit it!"></td></tr></table>

<input type=hidden name=idx value="<?php echo "$idx";?>">

</form>

<?php include ('links.x');?>
</body>
</html>--------------------------------------------------------------------------------
  好,这个脚本很简单。我们要关心的是,当表单打印出来时,它记录了当前记录的数据,通过在 <input
type= > 命令中的value属性。这些数据是从前一个页面传递过来的。

  现在,如果我们不改变记录的信息,它将传回当前值,即缺省值。如果我们改变了字段的值,字段的值
将变成新的值。接着我们可以将新值传给另一个脚本,它将会改变MySQL表中的值。

--------------------------------------------------------------------------------
editdb.php3:

<?php

mysql_connect() or die ("Problem connecting to DataBase");

$query = "update tbl set
idx='$idx',UserName='$UserName',LastName='$LastName',FreeText='$FreeText' where
idx='$idx'";

$result = mysql_db_query("example", $query);
$query = "SELECT * FROM tbl";
$result = mysql_db_query("example", $query);

if ($result)
{
echo "Found these entries in the database:<br><p></p>";
echo "<table width=90% align=center border=1><tr>
<td align=center bgcolor=#00FFFF>idx</td>
<td align=center bgcolor=#00FFFF>User Name</td>
<td align=center bgcolor=#00FFFF>Last Name</td>
<td align=center bgcolor=#00FFFF>Free Text</td>
</tr>";

while ($r = mysql_fetch_array($result))
{
$idx = $r["idx"];
$user = $r["UserName"];
$last = $r["LastName"];
$text = $r["FreeText"];

echo "<tr>
<td>$idx</td>
<td>$user</td>
<td>$last</td>
<td>$text</td>
</tr>";

}
echo "</table>";
}
else
{
echo "No data.";
}

mysql_free_result($result);

include ('links.x');

?>--------------------------------------------------------------------------------
  基本上要关心的一件事情是下面一行:

$query = "update tbl set idx='$idx',UserName='$UserName',LastName='$LastName',FreeText='$FreeText' where idx='$idx'";

  注意,它与我们在前面MySQL部分解释的语法相同。另一件事,注意这个脚本改变的是idx=$idx的记录,
如果表中有多条idx等于$idx的记录,所以这些记录都将被改变。如果我们想更严格一些,我们可以象下面
改动一下where子句:

$query = "update tbl set idx='$idx',UserName='$UserName', LastName='$LastName',FreeText='$FreeText' where idx='$idx' and UserName='$UserName' and LastName='$LastName' and FreeText='$FreeText'";

  这个语法将检查所有的字段,而不仅仅是检查idx。

  从数据库中删除一条记录:

  好,删除很容易。我们仍然需要两个脚本:一个用来选择要删除的记录(基本上同上面选择要编辑的记
录一样),一个用来真正地进行删除和打印新的表格。

--------------------------------------------------------------------------------
del.php3:

<html>
<head><title>Deleting an entry from the database</title>
</head>

<body bgcolor=#ffffff>
<h1>Del an entry</h1>

<?

mysql_connect() or die ("Problem connecting to DataBase");
$query = "select * from tbl";
$result = mysql_db_query("example", $query);

if ($result)
{
echo "Found these entries in the database:<br><p></p>";
echo "<table width=90% align=center border=1><tr>
<td align=center bgcolor=#00ffff>idx</td>
<td align=center bgcolor=#00FFFF>User Name</td>
<td align=center bgcolor=#00FFFF>Last Name</td>
<td align=center bgcolor=#00FFFF>Free Text</td>
</tr>";

while ($r = mysql_fetch_array($result))
{
$idx = $r["idx"];
$user = $r["UserName"];
$last = $r["LastName"];
$text = $r["FreeText"];

echo "<tr>
<td align=center>
<a href=\"dele.php3?
idx=$idx&UserName=$user&LastName=$last&FreeText=$text\">$idx</a></td>
<td>$user</td>
<td>$last</td>
<td>$dtext</td>
</tr>";

}
echo "</table>";
}
else
{
echo "No data.";
}

mysql_free_result($result);
include ('links.x');

?>

</body>
</html>
--------------------------------------------------------------------------------
  这个脚本与我们用过的编辑脚本很象,所以可以看一下那里的说明。

--------------------------------------------------------------------------------
dele.php3:

<?php

mysql_connect() or die ("Problem connecting to DataBase");
$query = "delete from tbl where idx='$idx' and UserName='$UserName' and
LastName='$LastName' and FreeText='$FreeText'";

$result = mysql_db_query("example", $query);
$query = "SELECT * FROM tbl";
$result = mysql_db_query("example", $query);

if ($result)
{
echo "Found these entries in the database:<br><p></p>";
echo "<table width=90% align=center border=1><tr>
<td align=center bgcolor=#00FFFF>idx</td>
<td align=center bgcolor=#00FFFF>User Name</td>
<td align=center bgcolor=#00FFFF>Last Name</td>
<td align=center bgcolor=#00FFFF>Free Text</td>
</tr>";

while ($r = mysql_fetch_array($result))
{
$idx = $r["idx"];
$user = $r["UserName"];
$last = $r["LastName"];
$text = $r["FreeText"];

echo "<tr>
<td>$idx</td>
<td>$user</td>
<td>$last</td>
<td>$text</td>
</tr>";

}
echo "</table>";
}
else
{
echo "No data.";
}

mysql_free_result($result);

include ('links.x');

?>--------------------------------------------------------------------------------
  这个脚本看上去很熟悉,唯一不同的就是删除查询的语法:

$query = "delete from tbl where idx='$idx' and UserName='$UserName' and LastName='$LastName' and FreeText='$FreeText'";

  这个查询将会删除所有与前面的脚本传递来的信息相配匹的记录。容易吧。

  好了,这就是全部内容了。

PHP新手上路(十三)PHP资源

PHP资源

 

12. PHP资源

  你可以通过web上的众多资源更多的了解PHP3。许多邮件列表和书籍对你都非常有用。

12.1 站点

  PHP的爆炸性流行使得一夜之间出现了很多基于PHP的站点,其中不少站点有在线教程、范例代码、技巧和提示等内容。

国内

http://www.phpchina.cn - PHP CHINA
http://www.phpuser.com/ - PHP中文用户,也就是这里了
http://www.phpx.com/ - 中国PHP联盟
http://www.phpsite.net/ - PHP专门站
http://www.cpcw.com/netschool/homepage/cgi/ - 电脑报网页陶吧
国外
http://www.php.net/ - PHP官方站点
http://www.devshed.com/ - 极好的教程
http:// px.sklar.com/ - 代码交换
http://phpuser.com/get_started/ http://www.phpbuilder.com/ - 教程、专栏和邮件列表档案
http://phpuser.com/get_started/ http://www.weberdev.com/ - 文章和代码
http://phpuser.com/get_started/ http://www.phpwizard.net/ - 提示与技巧
http:// www.iometrics.com/php/phplist.php3/ - IOMetrics scripts的档案
http://www.e-gineer.com/phpkb/ - PHP知识库


12.2 邮件列表

  你可以在PHP官方站点的"支持"栏目内登记获得以下的邮件列表。值得注意的是这些都是高流量流表,一般每天会有100份e-mail。

php3@lists.php.net - 主要的列表
php-dev@lists.php.net - 主要针对开发者
mailto:php-list-subscribe@exp.com.cn - 本站的邮件列表,与论坛相通


12.3 引人注目的工程

  一些基于PHP的工程已经发展得比较完善。其中一些更出色更引人注目的是:

http://phplib.netuse.de/ - PHPLib,一整套PHP函数库
http://www.phorum.org/ - Phorum是一个很完善的BBS系统
http://www.fishcartsql.org/ - FishCartSQL是一个电子商务解决方案
http://www.midgard-project.org/ - Midgard是一个网络应用开发平台

PHP新手上路(十二)使用PHP来操作Oracle数据库

使用PHP来操作Oracle数据库

 

11. 数据库连接

  在上一节里,我们已经介绍了PHP与MySQL数据库的一些基本操作知识,在互联网中有关PHP与MySQL的教程也最多。MySQL是免费的,这一点也许就吸引了不少人。由于其广泛应用,我就不想在这里赘述MySQL的使用方法了。Oracle被大量在企业应用中采用,因此我们就利用Oracle来进一步介绍PHP与数据库的连接。我们当然不会提及Oracle数据库的设计原理,原因是这已经超出了我们的讨论范围。

  PHP提供了两套函数与Oracle连接,分别是ORA_和OCI函数。其中ORA_函数略显陈旧。OCI函数更新据说更好一些。两者的使用语法几乎相差无几。如前所述,你的PHP安装选项应该可以支持两者的使用。
  想获得更多有关在Microsoft Windows平台上安装支持PHP3的Apache服务器的知识以及更多有关Oracle数据库的知识,请查阅以下URL:www.csoft.net/~vsbabu/articles/oraphp.html。

11.1 连接

<?
if ($conn=Ora_Logon("user@TNSNAME","password"))
{
echo "<B>SUCCESS ! Connected to database<B>n";
}
else
{
echo "<B>Failed :-( Could not connect to database<B>n";
}
Ora_Logoff($conn);
phpinfo();
?>
以上代码使用TNSNAME(在你的tnsnames.ora文件中指明)定义的Oracle数据库名称、用户名称和密码连接数据库。在成功连接的基础上,ora_logon函数返回一个非零的连接ID并储存在变量$conn中。

11.2 查询

假设与数据库已经连接就绪,下面我们就来实际的应用对数据库的查询。下面的代码演示了一个连接并查询的典型例子:
<?
/*
* 连接数据库并执行查询
*/
function printoraerr($in_cur)
{
// 检查Oracle是否出错
// 如果存在错误则显示
// 当指针被激活时每次请求Oracle后调用该函数
if(ora_errorcode($in_cur))
echo "Oracle code - ".ora_error($in_cur)."n";
return;
}
/** 主程序 */
if (!($conn=ora_logon("user@TNSNAME","password")))
{
echo "Connection to database failedn";
exit;
}
echo "Connected as connection - <b>$conn</b><br>n";
echo "Opening cursor ...<br>n";
$cursor=ora_open($conn); printoraerr($cursor);
echo "Opened cursor - <b>$cursor</b><br>n";
$qry="select user,sysdate from dual";
echo "Parsing the query <b>$qry</b> ...<br>n";
ora_parse($cursor,$qry,0); printoraerr($cursor);
echo "Query parsed <br>n";
echo "Executing cursor ...<br>n";
ora_exec($cursor); printoraerr($cursor);
echo "Executed cursor<br>n";
echo "Fetching cursor ...<br>n";
while(ora_fetch($cursor))
{
$user=ora_getcolumn($cursor,0); printoraerr($cursor);
$sysdate=ora_getcolumn($cursor,1); printoraerr($cursor);
echo " row = <B>$user, $sysdate </B><br>n";
}
echo "Fetched all records<br>n";
echo "Closing cursor ...<br>n";
ora_close($cursor);
echo "Closed cursor<br>n";
echo "Logging off from oracle... <br>n";
ora_logoff($conn);
echo "Logged off from oracle <br>n";
?>
(译者注:以上代码段缺少注释,请读者参考PHP Manual的Oracle数据库函数部分)

11.3 显示结果

以下代码演示了怎样查询数据库并将结果输出:
<?
function printoraerr($in_cur, $conn)
{
// 检查Oracle是否出错
// 如果存在错误则显示
// 当指针被激活时每次请求Oracle后调用该函数
// If it encountered an error, we exit immediately
if(ora_errorcode($in_cur))
{
echo "Oracle code - ".ora_error($in_cur)."<br>n";
ora_logoff($conn);
exit;
}
return;
}

function exequery($w_qry,$conn)
{
$cursor=ora_open($conn); printoraerr($cursor,$conn);
ora_parse($cursor,$w_qry,0); printoraerr($cursor,$conn);
ora_exec($cursor); printoraerr($cursor,$conn);
$numrows=0;
$w_numcols=ora_numcols($cursor);
// 显示头部
echo "
<TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="2">
<TR>n";
for ($i=0;$i<$w_numcols;$i )
{
$align=(ora_columntype($cursor,$i)=="NUMBER")?"RIGHT":"LEFT";
echo "t<TH VALIGN=TOP ALIGN=$align>".ora_columnname($cursor,$i)."</TH>n";
}
echo "</TR>n";
while(ora_fetch($cursor))
{
echo "<TR>n";
for ($i=0;$i<$w_numcols;$i )
{
$align=(ora_columntype($cursor,$i)=="NUMBER")?"RIGHT":"LEFT";
if(ora_columntype($cursor,$i)=="LONG")
echo "<TD VALIGN=TOP ALIGN=$align><PRE>".
ora_getcolumn($cursor,$i)."</PRE></TD>n";
else
echo "<TD VALIGN=TOP ALIGN=$align>".ora_getcolumn($cursor,$i)."</TD>n";
printoraerr($cursor,$conn);
}
$numrows ;
echo "</TR>n";
}
if ($numrows==0)
echo "<TR><TD COLSPAN="$w_numcols"><B>Query returned no records
</B></TD></TR>n";
else
{
echo "<TR>n";
echo "<TH COLSPAN="".($w_numcols-1)."" ALIGN=RIGHT>Count</TH>n";
echo "<TH ALIGN=RIGHT>$numrows</TH>n";
echo "</TR>n";
}
echo "</TABLE>n";
ora_close($cursor);
return;
}

// 主程序
if(!($conn=ora_logon("user@SID","password")))
{
echo "Error: Cannot connect to databasen";
exit;
}
$qry="SELECT
deptno "Dept"
,empno "Emp"
,empnm "Name"
,salary "Salary"
FROM
employee
ORDER BY 1,2";
exequery($qry);
ora_logoff($conn);
?>
(译者注:以上代码段缺少注释,请读者参考PHP Manual的Oracle数据库函数部分)

11.4 基于HTTP的Oracle登录

将以下代码加在PHP页面代码之前以确认Oracle登录。注意你必须正确设定$ SID。
<?
if(!isset($PHP_AUTH_USER))
{
Header("WWW-authenticate: basic realm="$SID"");
Header("HTTP/1.0 401 Unauthorized");
$title="Login Instructions";
echo "<blockquote>
You are not authorized to enter the site
</blockquote> n";
exit;
}
else
{
if (!($conn=ora_logon("$PHP_AUTH_USER@$SID",$PHP_AUTH_PW)))
{
Header("WWW-authenticate: basic realm="$SID"");
Header("HTTP/1.0 401 Unauthorized");
$title="Login Instructions";
echo "<blockquote>
You are not authorised to enter the site
</blockquote> n";
exit;
}
}
?>

PHP新手上路(十一) 数据库链接

数据库链接

 

10. PHP最大的特色就是操作数据库的能力特别的强大,PHP提供对多种数据库的支持。

  通过PHP你可以轻松的连接到数据库,请求数据并将其显示在你的web站点中,甚至修改数据库中的数据。在这一节里我们主要以在互联网上跟PHP一起使用得最多的MySQL数据库为例,介绍一下相关的MySQL数据库的操作函数以及数据库的基本操作等方面的知识。

在MySQL数据库中,我们用来连接数据库的函数有两个,它们分别为:
integer mysql_connect(string host,string user,string password);
integer mysql_pconnect(string host,string user,string password);
mysql_connect函数和mysql_pconnect函数都是对指定主机上MySQL数据库的连接,如果该数据库位于一个不同的端口,则可以在主机名后加上冒号和端口号。函数的参数也可以缺省不填,如果不填参数,默认的主机名是“localhost”,用户名为数据库管理员,默认值为“root”,密码为空。与数据库连接成功之后,这两个函数都可以返回一个连接号,如果连接失败,则返回一个false值。让我们来看看下面几句语句:
<?
$db=mysql_connect("localhost","user","password");
mysql_select_db("mydb",$db);
?>
注释:
$db=mysql_connect("localhost","user","password"); 我们将mysql的链接参数,包括主机名、用户名和密码作为mysql_connect()的参数,同时得到返回值为$db,这样,在下面的语句中,我们就可以将变量$db作为一个连接mysql数据库的连接号来使用。
mysql_select_db("mydb",$db); 将PHP程序链接到mydb数据库中,这样程序与数据库的链接就完成了。

10.1 一个简易的数据库留言簿

  在完成数据库的链接之后,我们就可以对数据库进行一系列的操作。下面是一个简易的数据库留言簿程序(guestbook.php3):

  我假设你机子上的MySQL数据库以及管理MYSQL数据库的工具 Phpmyadmin_2. 0.5都已经安装完成,并且可以正常工作。

我们要做的第一件事情是创建一个留言数据库,假定名字为: mydb。

1、启动浏览器,打开Phpmyadmin_2. 0.5 的管理WEB界面。

2、在“Create new database”文本框内输入数据库名称mydb,然后按create按键。

  下一步,我们要在该留言数据库下创建一个数据表,假定名字为: guestbook。

创建该数据表的命令如下所示:

CREATE TABLE guestbook (ID INT NOT NULL AUTO_INCREMENT, name CHAR(250), email CHAR(250), job CHAR(250), comments BLOB, PRIMARY KEY(ID));

最后,将下面的留言簿程序挎贝到你机子的可写目录下面,并保存成guestbook.php3文件。就这么简单,你已经有了自己的留言簿了。

10.2 留言簿程序(guestbook.php3):

<?php
/* $host : your MySQL-host, usually 'localhost' */
/* $user : your MYSQL-username */
/* $password : your MySQL-password */
/* $database : your MySQL-database */
/* $table : your MySQL-table */
/* $page_title : the title of your guestbook-pages */
/* $admin_mail : email-address of the administrator to send the new entries to */
/* $admin_name : the name of the administrator */
/* $html_mail : say yes if your mail-agent can handle HTML-mail, else say no */

$host = "localhost";
$user = "";
$password = "";
$database = "mydb";
$table = "guestbook";
$page_title = "pert guestbook";
$admin_mail = "pert@21cn.com";
$admin_name = "Webmaster";
$html_mail = "no";

?>
<HTML>
<HEAD>
<TITLE><?php echo $page_title; ?></TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000000">
<FONT FACE="Verdana" SIZE="-2">
<?

/* connect to the database */
mysql_pconnect("$host","$user","$password") or die("Can't connect to the SQL-server");
mysql_select_db("$database");

/* action=view : retrieve data from the database and show it to the user */
if($action == "view") {

/* function for showing the data */
function search_it($name) {

/* some vars */
global $offset,$total,$lpp,$dir;
global $table,$html_mail,$admin_name,$admin_mail;

/* select the data to get out of the database */
$query = "SELECT name, email, job, comments FROM $table";
$result = mysql_query($query);
$total= mysql_numrows($result);

print "<CENTER><FONT FACE="Verdana" SIZE="-2"><A HREF="guestbook.php3?action=add" onMouseOver="window.status='Add your name';return true" onMouseOut="window.status='';return true" TITLE="Add your name">加入留言</A></FONT></CENTER><br><br>";

if ($total== 0) {
print "<CENTER>此刻没人留言</CENTER><br><br>"; }

elseif ($total> 0) {

/* default */
$counter=0;
if ($dir=="") $dir="Next";
$lpp=5;
if ($offset==0) $offset=0;

if ($dir=="Next") {

if ($total > $lpp) {

$counter=$offset;
$offset =$lpp;
$num=$offset;

if ($num > $total) {
$num=$total; } }

else {
$num=$total; } }

elseif ($dir=="Previous") {

if ($total > $lpp) {
$offset-=$lpp;

if ($offset < 0) {
$offset=0; }

$counter=$offset-$lpp;

if ($counter < 0)
$counter=0;
$num=$counter $lpp; }

else {
$num=$total; } }

while ($counter < $num) {
$j=0;
$j=$counter 1;

/* now really grab the data */
$i1=mysql_result($result,$counter,"name");
$i2=mysql_result($result,$counter,"email");
$i3=mysql_result($result,$counter,"job");
$i4=mysql_result($result,$counter,"comments");

$i4 = stripslashes ("$i4");

/* print it in a nice layout */
print "<CENTER>n";
print "<TABLE WIDTH=400 BORDER=0 ALIGN=CENTER VALIGN=TOP><TR><TD><FONT FACE="Verdana" SIZE="-2">n";
print "<HR>n";
print "<BR><B>Name:</B> $i1n";
print "<BR><B>email:</B><A HREF="mailto:$i2" onMouseOver="window.status='Email $i2';return true" onMouseOut="window.status='';return true" TITLE="Email $i2">$i2</A>n";
print "<BR><B>Job:</B> $i3n";
print "<BR><B>Comment:</B>n";
print "<BR>$i4n";
print "</FONT></TD></TR></TABLE>n";
print "</CENTER>n";
$counter ;
}
}
mysql_close();
}

/* execute the function */
search_it($name);

/* See if we need to put on the NEXT or PREVIOUS buttons */
if ($total > $lpp) {
echo("<form action="$PHP_SCRIPT" method="POST">n");

/* See if we need a PREVIOUS button */
if ($offset > $lpp) {
echo("<input type="submit" value="Previous" name=dir>n"); }

/* See if we need a NEXT button */
if ($offset < $total) {
echo("<input type="submit" value="Next" name=dir>n"); }

echo("<input type=hidden name="offset" value="$offset">n");
echo("<input type=hidden name="name" value="$name">n");
echo("</form>");
}
}

/* action=add : show a form where the user can enter data to add to the database */
elseif($action == "add") { ?>

<TABLE WIDTH="460" ALIGN="CENTER" VALIGN="TOP">
<TH COLSPAN="2"><P>请您填写留言</TH>
<FORM NAME="guestbook" ACTION="guestbook.php3?action=send" METHOD="POST">
<TR>
<TD ALIGN="RIGHT" VALIGN="TOP">
您的大名:</TD>
<TD><INPUT TYPE=text NAME=name></TD>
</TR>
<TR>
<TD ALIGN="RIGHT" VALIGN="TOP">
您的E-mail:</TD>
<TD>
<INPUT TYPE=text NAME=email></TD>
</TR>
<TR>
<TD ALIGN="RIGHT" VALIGN="TOP">
您的工作:</TD>
<TD>
<INPUT TYPE=text NAME=job></TD>
</TR>
<TR>
<TD ALIGN="RIGHT" VALIGN="TOP">
您的留言:</TD>
<TD>
<TEXTAREA NAME=comments COLS=40 ROWS=6></TEXTAREA>
<P>
<INPUT TYPE=submit VALUE=Submit> <INPUT TYPE=Reset VALUE=Reset>
<A ALIGN="RIGHT" HREF="guestbook.php3?action=view" onMouseOver="window.status='Read all comments first';return true" onMouseOut="window.status='';return true" TITLE="Read all comments first"><FONT SIZE="-2">先观看所有的留言</FONT></A>
</TD>
</TR>
</FORM>
</TABLE>
</CENTER>

<?
}

/* action=send : add the data from the user into the database */
elseif($action == "send") {

/* check if a HTML-mail should be send or a plain/text mail */
if($html_mail == "yes") {
mail("$admin_name <$admin_mail>","PHP3 Guestbook Addition","<HTML><BODY><FONT FACE="Century Gothic"><TABLE BORDER="0" WIDTH="100%" CELLSPACING="4"><TR>$name ($email) schreef het volgende bericht in het gastenboek :</TR><TR><TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT" NOWRAP> </TD></TR><TR><TD ALIGN="LEFT">$comments</TD><TD ALIGN="LEFT" NOWRAP> </TD></TR><TR><TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT" NOWRAP> </TD></TR><TR><TD ALIGN="LEFT">您的留言:</TD><TD ALIGN="LEFT" NOWRAP>$name</TD></TR><TR><TD ALIGN="LEFT">您的大名:</TD><TD ALIGN="LEFT" NOWRAP>$email</TD></TR><TR><TD ALIGN="LEFT">您的email:</TD><TD ALIGN="LEFT" NOWRAP>$job</TD></TR><TR><TD ALIGN="LEFT">您的工作:</TD></TR></TABLE></BODY></FONT></HTML>", "From: $name <$email>nReply-To: $name <$email>nContent-type: text/htmlnX-Mailer: PHP/" . phpversion());
}


/* MySQL really hates it when you try to put things with ' or " characters into a database, so strip these...*/
$comments = addslashes ("$comments");
$query = "INSERT INTO guestbook VALUES('','$name', '$email', '$job', '$comments')";
$result = MYSQL_QUERY($query);

?>
<BR><P ALIGN = CENTER>感谢, <?php echo $name; ?>, 您的留言.
<BR><P ALIGN = CENTER><A HREF="guestbook.php3?action=view" onMouseOver="window.status='View your comment now';return true" onMouseOut="window.status='';return true" TITLE="View your comment now">观看留言</A><BR><BR>
<?

 

}

/* if there's no action given, then we must show the main page */
else {

/* get the number of entries written into the guestbook*/
$query = "SELECT name from guestbook";
$result = MYSQL_QUERY($query);
$number = MYSQL_NUMROWS($result);

if ($number == "") {
$entry = "还没有人留过言"; }

elseif ($number == "1") {
$entry = "目前留言人数1人"; }

else {
$entry = "目前留言人数 $number 人"; }

echo "<CENTER><BR>";
echo "<P>$entry<BR>";
echo "<H4><FONT FACE="Verdana" SIZE="3"><A HREF="guestbook.php3?action=add" onMouseOver="window.status='请您留言';return true" onMouseOut="window.status='';return true" TITLE="Add your name to our guestbook">请您留言</A></FONT></H4>";

if ($number > "") {
echo "<H4><FONT FACE="Verdana" SIZE="3"><A HREF="guestbook.php3?action=view" onMouseOver="window.status='观看留言';return true" onMouseOut="window.status='';return true" TITLE="View the names in our guestbook">观看留言</A></FONT></H4>"; }
echo "</P></CENTER>";
}
?>
<BR><SMALL><CENTER>版权所有:<A HREF="http://personal.668.cc/haitang/index.htm" onMouseOver="window.status='pert';return true" onMouseOut="window.status='';return true" TITLE="pert">无边天际</A></CENTER></SMALL>
</FONT>
</BODY>
</HTML>

PHP新手上路(十) 简易banner动态更替

建设一个简单交互的网站(六)

 

9. 简易banner动态更替

  不知大家有没有发现各大站点上的标头广告banner,我们每次访问这些站点时,都会看到不同的广告图标,或者如果你每次刷新页面时,这些广告banner就会不断地随机更替变换。要实现这种效果虽然用javascript也可以达到(象天极网站的动态变换广告banner就是通过调用javascript来实现的),但是如果我们用PHP的话,我们还可以结合数据库来做数据量很大,如每日一题之类的功能。费话少说,让我们立即来看看如何用PHP来实现banner的动态更替功能。

简易banner动态更替PHP文件(banner.php3):
<?
//产生随机数
srand((double)microtime()*1000000);
//在0和4之间取一个数字
$randval = rand(0,5);
// 显示结果
echo "<a href=//gophp.heha.net/index.html><img alt=进入php的世界 border=0 src=$randval.gif></a>";
?>

  我们可以发现,实现的程序非常简单:主要是先利用srand这一初始化随机数产生器产生随机数,再调用rand函数在定义的有效范围内来获取其中一个随机值,最后显示$randval.gif各图片banner,即0.gif、1.gif、2.gif、3.gif或4.gif。为了便于大家理解,我将rand函数的语法及相关说明罗列如下:
rand
语法:int rand([int min], [int max]);
返回值:整数
函数种类:数学运算
内容说明:本函数用来取得随机值。若没有指定随机数的最大及最小范围,本函数会自动地从0到RAND_MAX中取一个随机数。若有指定min及max的参数,则从指定参数中取一数字。例如rand(38,49)则会从38到49之间取得一个随机值。其中UNIX系统包含49,Win32系统不包含49。值得注意的是为了使随机数的随机率最大,每次在取随机数前最好使用srand()来设定新的随机数。在本例中在用srand()来产生新的随机数时加入了时间因素,执行时以百万分之一的随机率来产生随机数

9.1 我们更改head.inc文件以应用该简易banner动态更替功能,同时还得为不同的广告banner链接到它们对应的网址。

  当然,首先我们必须先准备好用于更换交换的banner图标,同时也给我们的页面标头加上自己网站的徽标(01DC.gif)。

新的标头文件(header.inc):
<?
// 定义通用页面头部
?>
<HTML>
<HEAD>
<TITLE> <? echo "$MySiteName - $title"; ?> </TITLE>
<style type="text/css">
<!--
.text { font-family: "宋体"; font-size: 12pt; color: #006633; text-decoration: none}
-->
</style>
</HEAD>
<body topmargin=2>
<table width="100%" border="0">
<tr>
<td rowspan="3" width="19%"><img src="http://gophp.heha.net/test/images/01dc.gif" width="140" height="60"></td>
<td rowspan="3" width="29%">
<?
//取得乱数种子
srand((double)microtime()*1000000);
//在0和4之间取一个数字
$randval = rand(0,5);
// 显示结果
switch($randval)
{
case "0";
echo "<a href=//gophp.heha.net/index.html><img border=0 src=$randval.gif></a>";
break;
case "1";
echo "<a href=//personal.668.cc/haitang/index.htm><img border=0 src=$randval.gif></a>";
break;
case "2";
echo "<a href=//gophp.heha.net/index.html><img border=0 src=$randval.gif></a>";
break;
case "3";
echo "<a href=//gophp.heha.net/index.html><img border=0 src=$randval.gif></a>";
break;
case "4";
echo "<a href=//personal.668.cc/haitang/index.htm><img border=0 src=$randval.gif></a>";
break;
}
?>
</td>
<td width="52%">
<div align="center"><a href="../test/form.php3" class="text">自动发送邮件测试</a></div>
</td>
</tr>
<tr>
<td width="52%">
<div align="center"><a href="../test/php/php1.php3" class="text">简易轮回广告更替</a></div>
</td>
</tr>
<tr>
<td width="52%">
<div align="center"><a href="../password/password.php3" class="text">简易密码验证实例</a></div>
</td>
</tr>
</table>
<hr color="#ff9900" size="4">
</body>
</html>

PHP新手上路(九) 投票系统

建设一个简单交互的网站(五)

 

8. 投票系统

  在许多时候,我们需要收集上网者和网友们的意见。例如:新版页面与旧版页面的比较;对某一事情的看法;对体育比赛结果的预测等等。这时候,你需要一个非常有效的网上调查系统。使用PHP就可以非常方便地实帜愕恼庖还瓜搿?

8.1 投票系统(mypolls.php3):

<?
$status=0;
if(isset($polled)&&($polled=="c-e")){
$status=1;
}
#echo "$status";
if(isset($poll)&&($status==0)){
setcookie("polled","c-e",time() 86400,"/");#time=24h
}
?>
<html>
<head>
<title>新版页面调查</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
<!--
.tb { border="1" bordercolor="#009933" cellspacing="0" font-size: 9pt; color: #000000}
.head { font-family: "宋体"; font-size: 12pt; font-weight: bold; color: #009933; text-decoration: none}
.pt9 { font-size: 9pt}
a.p9:link { font-size: 9pt; color: #000000; text-decoration: none}
a.p9:visited { font-size: 9pt; color: #000000; text-decoration: none }
a.p9:hover { font-size: 9pt; color: #FF0000; text-decoration: underline}
a.p9:active { font-size: 9pt; color: #FF0000; text-decoration: underline }
-->
</style>
</head>
<body bgcolor="#FFFFFF">
<div class="head">与旧版页面相比较您觉得新版页面:</div><br>
<?
if(!isset($submit)){
?>
<form action="myPolls.php3" method="get">
<input type="radio" name="poll_voteNr" value="1" checked >
<span class="pt9">信息量更大</span> <br>
<input type="radio" name="poll_voteNr" value="2" >
<span class="pt9">网页更精美</span> <br>
<input type="radio" name="poll_voteNr" value="3" >
<span class="pt9">没什么改进</span> <br>
<input type="radio" name="poll_voteNr" value="4" >
<span class="pt9">其它</span> <br>
<input type="submit" name="submit" value="OK">
<input type="hidden" name="poll" value="vote">
<A HREF="myPolls.php3?submit=OK" class="p9">查看调查结果</A>
</form>
<?
/*
如果想增加其它的选项可直接加上即可
*/
}else{
$descArray=array(1=>"信息量更大",
2=>"网页更精美",
3=>"没什么改进",
4=>"其它"
);
$poll_resultBarHeight = 9; // height in pixels of percentage bar in result table
$poll_resultBarScale = 1; // scale of result bar (in multiples of 100 pixels)
$poll_tableHeader="<table border=1 class="tb">";
$poll_rowHeader="<tr>";
$poll_dataHeader="<td align=center>";
$poll_dataFooter="</td>";
$poll_rowFooter="</tr>";
$poll_tableFooter="</table>";
$coutfile="data.pol";
$poll_sum=0;

// read counter-file
if (file_exists( $coutfile))
{
$fp = fopen( $coutfile, "rt");
while ($Line = fgets($fp, 10))
{
// split lines into identifier/counter
if (ereg( "([^ ]*) *([0-9]*)", $Line, $tmp))
{
$curArray[(int)$tmp[1]] = (int)$tmp[2];
$poll_sum =(int)$tmp[2];
}
}
// close file
fclose($fp);
}else{//
for ($i=1;$i<=count($descArray);$i ){
$curArray[$i]=0;
}
}
if(isset($poll)){
$curArray[$poll_voteNr] ;
$poll_sum ;
}
echo $poll_tableHeader;

// cycle through all options编历数组
reset($curArray);
while (list($K, $V) = each($curArray))
{
$poll_optionText = $descArray[$K];
$poll_optionCount = $V;
echo $poll_rowHeader;

if($poll_optionText != "")
{
echo $poll_dataHeader;
echo $poll_optionText;
echo $poll_dataFooter;

if($poll_sum)
$poll_percent = 100 * $poll_optionCount / $poll_sum;
else
$poll_percent = 0;
echo $poll_dataHeader;

if ($poll_percent > 0)
{
$poll_percentScale = (int)($poll_percent * $poll_resultBarScale);
}

printf(" %.2f %% (%d)", $poll_percent, $poll_optionCount);

echo $poll_dataFooter;
}

echo $poll_rowFooter;
}

echo "总共投票次数:<font color=red> $poll_sum</font>";
echo $poll_tableFooter;
echo "<br>";
echo "<input type="submit" name="Submit1" value="返回主页" onClick="javascript:location='http://gophp.heha.net/index.html'">";
echo " <input type="submit" name="Submit2" value="重新投票" onClick="javascript:location='http://gophp.heha.net/mypolls.php3'">";
if(isset($poll)){
// write counter file
$fp = fopen($coutfile, "wt");
reset($curArray);
while (list($Key, $Value) = each($curArray))
{
$tmp = sprintf( "%s %dn", $Key, $Value);
fwrite($fp, $tmp);
}
// close file
fclose($fp);
}
}
?>
</body>
</html>

注释:从上面我们可以看出该投票系统的基本过程:
1、打开文件取得数据到数组$curArray(文件不存在则初始化数组$curArray)
2、编历数组,处理数据得到所需值
3、计算百分比,控制统计bar图像宽度
4、将数据保存到"data.pol"中

   这里有一点是需要注意:这里的data.pol文本文件需要有写权限。

PHP新手上路(七)

建设一个简单交互的网站(三)

 

6. 密码验证

  也许你想在自己的网站放上你的照片集,而且只想给自己知心的朋友看,这时你需要一个密码验证的程序。

6.1 基于HTTP验证

  如何用PHP来实现密码验证的功能呢?我们可以使用简短的PHP代码,使用函数header()发送HTTP标头强制验证,客户端浏览器则弹出供输入用户名和密码的对话框。在PHP中,客户端用户输入的信息传送到服务端之后自动保存在$PHP_AUTH_USER, $PHP_AUTH_PW, 以及 $PHP_AUTH_TYPE这三个全局变量中。利用这些变量,我们就可以根据实现保存在数据文件或数据库中的用户帐号信息验证用户身份。

  不过在这里需要提醒使用者注意的一点是:只有在Apache模块方式运行的时候,PHP脚本才能使用$PHP_AUTH_USER, $PHP_AUTH_PW, 以及 $PHP_AUTH_TYPE这三个变量。如果用户使用的是CGI模式的PHP则无法实现基于HTTP的验证功能。

6.2 下面,我们就来详细介绍一下如何使用PHP对用户身份进行验证。

  在下例中,我们是使用$PHP_AUTH_USER和$PHP_AUTH_PW这两个变量来验证进入者是否合法并允许进入。在本例中被允许登录的用户名称和密码对分别为tnc和nature:
<?
if(!isset($PHP_AUTH_USER))
{
Header("WWW-Authenticate: Basic realm="My Realm"");
Header("HTTP/1.0 401 Unauthorized");
echo "Text to send if user hits Cancel buttonn";
exit;
}
else
{
if ( !($PHP_AUTH_USER=="tnc" && $PHP_AUTH_PW=="nature") )
{
// 如果是错误的用户名称/密码对,强制再验证
Header("WWW-Authenticate: Basic realm="My Realm"");
Header("HTTP/1.0 401 Unauthorized");
echo "ERROR : $PHP_AUTH_USER/$PHP_AUTH_PW is invalid.";
exit;
}
else
{
echo "Welcome tnc!";
}
?>

  事实上再实际引用中不大可能如上面使用代码段明显的用户名称/密码对,而是利用数据库或者加密的密码文件存取它们。

6.3 根据指定的验证信息核实用户身份

  首先,我们可以使用以下代码确定用户是否已经输入了用户名和密码,并显示出用户输入的信息。

<?php

if (!isset($PHP_AUTH_USER)) {

header('WWW-Authenticate: Basic realm="My Private Stuff"');

header('HTTP/1.0 401 Unauthorized');

echo 'Authorization Required.';

exit;

}

else {

echo "<P>You have entered this username: $PHP_AUTH_USER<br>

You have entered this password: $PHP_AUTH_PW<br>

The authorization type is: $PHP_AUTH_TYPE</p>";

}

?>

说明:
isset()函数用于确定某个变量是否已被赋值。根据变量值是否存在,返回true或false。
header()函数用于发送特定的HTTP标头。注意,使用header()函数时,一定要在任何产生实际输出的HTML或PHP代码前面调用该函数。

  虽然上述代码相当简单,没有根据任何实际值对用户输入的用户名和密码进行有效验证,但是至少我们了解了如何使用PHP在客户端产生输入对话框。

  下面,我们就来了解一下如何根据指定的验证信息核实用户身份。代码如下:

<?php

if (!isset($PHP_AUTH_USER)) {

header('WWW-Authenticate: Basic realm="My Private Stuff"');

header('HTTP/1.0 401 Unauthorized');

echo 'Authorization Required.';

exit;

}

else if (isset($PHP_AUTH_USER)) {

if (($PHP_AUTH_USER != "admin") || ($PHP_AUTH_PW != "123")) {

header('WWW-Authenticate: Basic realm="My Private Stuff"');

header('HTTP/1.0 401 Unauthorized');

echo 'Authorization Required.';

exit;

} else {

echo "<P>You're authorized!</p>";

}

}

?>

  在这里,我们首先检查用户是否已经输入了用户名称和密码,如果没有则弹出相应对话框要求用户输入身份信息。随后,我们通过判断用户输入的信息是否符合admin/123这一指定用户帐号来授予用户访问权限或提示用户再次输入正确的信息。这种方法适用于所有用户都使用同一登录帐号的网站。

6.4 另一种简易的密码验证

  如果你是在windows98下面编写和运行着你的PHP脚本,或者是你在Linux下面按默认设置,将PHP安装成一个CGI程序的话,你将无法使用上面的PHP程序来实现验证功能。为此,无边给大家提供了另外一种简易的密码验证的方法。虽然实用性不大,但是拿来学习还是挺好的。
<?php
$password = "123";

// check password
if($pass != $password)
{
echo "<html><head><title>管理密码</title></head><body>";
echo "<form method="post" action=$PHP_SELF>";
echo "请输入你的管理密码:<br>";
echo "<input type="password" name="pass">";
echo "<input type="submit" value="continue">";
echo "</form></body></html>";
}
else
{
echo "<html><head><title>恭喜你,你已经通过了密码验证</title></head>";
echo "<script>";
echo 'window.location="http://gophp.heha.net/test/index.php3"';
# 通过密码验证后转入的页面
echo "</script>";

}
?>

PHP新手上路(八) 文件上传

7. 文件上传

 

  你可以利用PHP实现文件的上传功能,注意客户端的浏览器应该是Netscape3以上或者IE3以上的版本。同时,因为本程序与你的PHP配置文件(PHP3为php3.ini,PHP4为php.in)设置有关。在执行该程序之前请先检查您的PHP配置文件有没有做好如下的设置:

  将;upload_tmp_dir该行的注释符,即前面的分号“;”去掉,使该行在php.ini文档中起作用。upload_tmp_dir是用来定义上传文件存放的临时路径,在这里你还可以给其定义一个绝对路径,例如:upload_tmp_dir = d:upload  当然,此时你的d:upload目录必须有读写权限。

  如果你在你的.php3程序里已经定义了上传的路径,此时上传文件的路径以.php3程序里定义的路径为基准。在下例中,receiver.php3文件就指定了用于存放上传文件的目录是:d:upload。

upload_max_filesize 是用来限制PHP处理的上载文件大小的最大值,以字节计算,缺省值为2097152= 2*1024*1024字节(2兆),你可以通过修改该缺省值来定义最大的上载文件大小。

  修改后不要忘了重启Apache,IIS或PWS服务哦。
  
  ?痹?HP中,文件上载还有几点是值得注意的:
1. 在form表单中要将method属性设为post,enctype属性设为multipart/form-data;

2. 在form表单中可以加一个hidden类型的input框,其中名字为 MAX_FILE_SIZE的隐藏值域,通过设置其VALUE可以限制上载文件的大小。当然,这个值不可能超过PHP的配置文件(PHP3为php3.ini,PHP4为php.ini)中的upload_max_filesize,注意这个input框一定要放在所有file类型的input框前面,否则也是无效的哦;

3. 在PHP程序运行完后,上传文件被放在了临时目录下。如果上传文件没有被改名或移动,那么在请求的最后该文件将自动被从临时文件夹中删除,所以我们最好立即将新的上传文件上传移到一个永久目录下或更改其文件名。


首先我们需要一个上载文件的表单网页(upload.htm):
<HTML>
<HEAD>
<TITLE>Upload Your File</TITLE>
</HEAD>
<BODY>
<FORM ACTION="receiver.php3"
ENCTYPE="multipart/form-data" METHOD=POST>
<INPUT TYPE="HIDDEN"
NAME="MAX_FILE_SIZE" VALUE="2000000">
<INPUT TYPE="FILE"
NAME="uploadfile" SIZE="24" MAXLENGTH="80">
<BR><BR>
<INPUT TYPE="SUBMIT" VALUE="Upload File!"
NAME="sendit">
<INPUT TYPE="SUBMIT" VALUE="Cancel"
NAME="cancelit"><BR>
</FORM>
</BODY>
</HTML>

处理上载文件的PHP文件(receiver.php3)
<?
function do_upload ()
{
global $uploadfile, $uploadfile_size;
global $local_file, $error_msg;
if ( $uploadfile == "none" )
{
$error_msg = "对不起,你没有选定任何文件上传!";
return;
}
if ( $uploadfile_size > 2000000 )
{
$error_msg = "对不起,你要上传的文件太大了!";
return;
}
$the_time = time ();

// 在这里指定你用来存放上传文件的目录,你需要对以下目录有写权限
// 同时,我们也可以给上传文件指定另外的目录,如:$upload_dir = "/local/uploads";

$upload_dir = "d:/upload";
$local_file = "$upload_dir/$the_time";
if ( file_exists ( '$local_file' ) )
{
$seq = 1;
while ( file_exists ( "$upload_dir/$the_time$seq" ) ) { $seq ; }
$local_file = "$upload_dir/$the_time$seq";
};
rename ( $uploadfile, $local_file );
display_page ();
}
function display_page ()
{
// 这里是你的页面内容
}
?>
<HTML>
<HEAD>
<TITLE>php3 Receiving Script</TITLE>
</HEAD>
<BODY>
<?
if ( $error_msg ) { echo "<B>$error_msg</B><BR><BR>"; }
if ( $sendit )
{
do_upload ();
echo "文件上载成功!";
}
elseif ( $cancelit )
{
header ( "Location: $some_other_script" );
echo "文件上载失败!";
exit;
}
else
{
some_other_func ();
}
?>
</BODY>
</HTML>

PHP新手上路(六)

建设一个简单交互的网站(二)

 

5.5 计数器

  让我们在首页上加上一个计数器。这个例子已经被讲过多次了,但是还是有利于演示怎样读写文件以及创建自己的函数。counter.inc包含以下代码:

<?
/*
|| 一个简单的计数器
*/
function get_hitcount($counter_file)
{
/* 将计数器归零
这样如果计数器还未被使用,初始值将是1
你当然也可以把初始值设成20000来骗人咯
*/
$count=0;
// 如果存放计数器文件已经存在,读取其中的内容
if ( file_exists($counter_file) )
{
$fp=fopen($counter_file,"r");
// 我们只取了前20位,希望你的站点不要太受欢迎啊
$count=0 fgets($fp,20);
// 由于函数fgets()返回字符串,我们可以通过加0的方法将其自动转换为整数
fclose($fp);
// 对文件操作完毕
}
// 增加一次计数值
$count ;
// 将新的计数值写入文件
$fp=fopen($counter_file,"w");
fputs($fp,$count);
fclose($fp);
# 返回计数值
return ($count);
}
?>

然后我们更改front.php3文件以显示这个计数器:
<?
include("include/counter.inc");
// 我把计数值放在文件counter.txt中,读出并输出
printf ("<CENTER><B>d</B></CENTER> <BR> n",
get_hitcount("counter.txt"));
include("include/footer.inc");
?>
看看我们的新front.php3

5.6 反馈表单

  让我们再添加一个反馈表单以便你的浏览者填写并e-mail给你。举例来说我们用一种很简单的方法实现它,我们只需要两个页面:一个为浏览者提供输入表单;一个获得表单数据并处理、mail给你。

  PHP中获取表单数据是很简单的。当一个表单被发送后,表单中所包含的各个元素被赋上了相应的值,而这样就可以像引用一般变量一样使用了。
<FORM name="myform" ACTION="process_form.php3" METHOD="POST">
<INPUT TYPE="TEXT" NAME="mytext" VALUE="Some Value">
</FORM>

  在process_form.php3中,变量$mytext就被赋予了输入的值--非常简单!同样的,你可以从列表框、多选框、单选框、按钮等表单元素中取得变量值。你唯一要做的就是为表单中的每一个元素取名以便将来可以引用。

  根据这个方法,我们可以生成一个简单的包含三个元素的表单:姓名、e-mail地址和留言。当浏览者发送表单后,处理该表单的PHP页面(sendfdbk.php3)读取数据,检查姓名是否为空,最后将数据mail给你。

表单:form.php3
<?
include("include/common.inc");
$title = "Feedback";
include("include/header.inc");
?>
<P>
<FORM ACTION="sendfdbk.php3" METHOD="POST">
<INPUT TYPE="text" NAME="name" value="Your name" SIZE="20" MAXLENGTH="30">
<INPUT TYPE="text" MAXLENGTH="40" WIDTH="20" value="Your Email" NAME="email">
<BR>
<TEXTAREA ROWS="7" COLS="40" NAME="comment">
Your feedback on my home page.
</TEXTAREA>
<BR>
<INPUT TYPE="submit" VALUE="Send Feedback!">
</FORM>
</P>
<?
include("include/footer.inc");
?>

处理表单:sendfdbk.php3
<?
include("include/common.inc");
$title = "Feedback";
include("include/header.inc");
if ( $name == "" )
{
// 现在我很讨厌匿名的留言!
echo "Duh ? How come you are anonymous?";
}
elseif ($name == "Your name")
{
// 这个浏览者真是不想透露姓名啊!
echo "Hello ? <B>Your name</B> is supposed to be replaced with
your actual name!</B>";
}
else
{
// 输出一段礼貌的感谢语
echo "
Hello, $name.
<BR>
Thank you for your feedback. It is greatly appreciated.
<BR>
Thanking you
<BR>
$MyName <BR>
$MyEmailLink
";
// 最后mail出去
mail($MyEmail, "Feedback.","
Name : $name
E-mail : $email
Comment : $comment
");
}
include("include/footer.inc");
?>

  注意:如果在你的测试过程中,该程序末能正常工作,请查看你的PHP配置文件(PHP3为php3.ini,PHP4为php.in)有没有设置好。因为本程序需要您的PHP配置文件作如下的设置:

  首先,用NotePad打开你的php3.ini或是php.ini文件,查看一下[mail function]有没有设置好,默认的情况如下所示:
SMTP = localhost
sendmail_from = me@localhost.com
给SMTP设置SMTP服务器,最好是你当地的SMTP服务器,我这里以21cn的SMTP服务器作为例子,然后,在sendmail_from处填上你的E-MAIL地址,例如可以改成这样:
SMTP = smtp.21cn.com
sendmail_from = pert@21cn.com
修改后不要忘了重启Apache,IIS或PWS服务哦.


5.7 简单的站内搜索引擎

  PHP可以调用外部程序。在Unix环境下我们可以利用程序grep实现一个简单的搜索引擎。我们可以做的稍微复杂一些:使用一个页面既输出一个表单供用户输入搜索字串又输出查询结果。

<?
include("include/common.inc");
$title = "Search";
include("include/header.inc");
?>
<P>
<FORM ACTION="<? echo "$PHP_SELF"; ?>" METHOD="POST">
<INPUT TYPE="text" NAME="searchstr" value="<? echo "$searchstr"; ?>"
SIZE="20" MAXLENGTH="30">
<INPUT TYPE="submit" VALUE="Search!">
</FORM>
</P>
<?
if ( ! empty($searchstr) )
{
// empty()用来检查查询字串是否为空
// 如果不为空,调用grep查询
echo "<HR>n";
// 调用grep对所有文件进行大小写非敏感模式的查询
$cmdstr = "grep -i $searchstr *";
$fp = popen( $cmdstr, "r" ); // 执行命令并输出管道
$myresult = array(); // 存储查询结果
while( $buffer = fgetss ($fp, 4096))
{
// grep返回这样格式: 文件名:匹配字串出现行数
// 因此我们利用函数split()分离处理数据
list($fname, $fline) = split(":",$buffer, 2);
// 我们只输出第一次匹配的结果
if ( !defined($myresult[$fname]))
$myresult[$fname] = $fline;
}
// 现在我们将结果存储在数组中,下面就可以处理并输出了
if ( count($myresult) )
{
echo "<OL>n";
while(list($fname,$fline) = each($myresult))
echo "<LI>
<A HREF="$fname">$fname</A> : $fline </LI>n";
echo "</OL>n";
}
else
{
// 如果没有查询结果
echo "Sorry. Search on <B>$searchstr</B>
returned no results.<BR>n";
}
pclose($fp);
}
?>
<?
include("include/footer.inc");
?>


注释:

PHP_SELF是PHP内建的变量。包含当前文件名。
fgets()按行读取文件,最多4096(指定)字符长度。
fgetss()与fgets()相似,只是解析输出的HTML标记。
split()有一个参数是2,因为我们只需要把输出分成两部分。另外需要省略":"。
each()是一个数组操作函数,用来更方便的遍历整个数组。
popen()、pclose()与fopen()、fclose()的功能很相似,只是增加了管道处理。
请注意以上的代码并不是实现一个搜索引擎的好办法。这只是有助于我们更好学习PHP而举出的一个例子而已。理想的情况是你应该建立一个包含关键字的数据库然后进行搜索。

PHP新手上路(五)

建设一个简单交互的网站(一)

 

  PHP的许多特点与其他软件或者工具有关。利用迄今为止我们所学到的PHP知识,我们可以试着建立一个简单交互的网站。利用这一过程我们又可以学到不少东西。好吧,我们现在开始专注于一个典型个人网站的建设。

5.1 计划一个站点

  一般一个个人站点包括一个欢迎页面、一个留言本页面、一个书签链接页面、一个计数器、联系信息,甚至还有照片集和一些音乐文件等等。

5.2 用include和require进行模块化

  我们看一些用PHP构架的网站,几乎网站每一个页面的PHP文件里都会有include和require嵌入其间。这是因为使用include和require不但可增强代码的可读性,而且可将站点分成模块来管理。一般来说,对于一个网站上的每个页面肯定会有重复的内容。例如:页面头部的导航条、广告图标、或边部导航等。可能还在每页的页脚即页面的底部有著作权或一些基于文本的导航条。如果我们要修改一个包含成千上百个页面的大网站上的导航条或是徽标之类的内容,用我们以往的方法,我们只能遂一对每一页面进行更改。不用我说,大家也能想像到这是一件多么艰巨而痛苦的差事。那么,我们到底有没有更好的解决方法呢?答案是肯定的。我们可以将重复的内容都放到一个文件中,然后在每一个需要这些内容的页面上用PHP的include和require函数动态地调用该文件。这样,以后如果我们想对所有页面上的这些复用内容做修改时,就只需要更改包含了这些重复内容的文件。

  为了便于大家理解,让我们先来看看include和require的一个简单应用:

HTML的页面开始,也许你会在站点的每页的头部包含它(head.htm)。
<HTML>
<HEAD>
<TITLE> 我的个人主页 </TITLE>
</HEAD>
<BODY>

页面内容(content.htm)。
<H1>
欢迎来我的寒舍,虽然这里现在暂时还没有什么。
</H1>

HTML的页面的结束(trail.htm)
</BODY>
</HTML>

用include和require函数把HTML从PHP中分离出来,将HTML和PHP分成模块:
<?
/*
调用HTML页面的头部
*/
require(\"head.htm\");
/*
调用HTML页面的内容
*/
require(\"centent.htm\");
/*
调用HTML页面的尾部
*/
require(\"trail.htm\");
?>

5.3 让我们从一个标题页面、一个联系信息页面和一个简历页面开始。我们同样需要标准的、通用的页面头部和底部。

标题页面--front.htm
这里我们有一个非常简单的html文件:
<HTML>
<HEAD>
<TITLE>
我的个人主页--欢迎
</TITLE>
</HEAD>
<BODY>
<H1>
我的个人主页
</H1>
<H2>
欢迎
</H2>
<HR>
<P>
欢迎来我的寒舍,虽然这里现在暂时还没有什么。
</P>
<P>
不过我希望马上就可以多起来。
</P>
<HR>
<P ALIGN=\"CENTER\">
<SMALL> <I>
Copyright ? 我自己,1999
</I> </SMALL>
</P>
</BODY>
</HTML>

联系信息页面--count.htm
同样我们又有了一个简单页面:
<HTML>
<HEAD>
<TITLE>
我的个人主页--联系信息
</TITLE>
</HEAD>
<BODY>
<H1>
我的个人主页
</H1>
<H2>
联系信息
</H2>
<HR>
<P>
你可以通过1-800-PHP-INFO联系我
</P>
<HR>
<P ALIGN=\"CENTER\">
<SMALL> <I>
Copyright ? 我自己,1999
</I> </SMALL>
</P>
</BODY>
</HTML>


5.4 从HTML到PHP

  从上面你可以看出,每个页面有相同的头部和底部。像上面那样每个页面都写入相同的信息在工作量少的时候还可以,但是想象一下当有100多页面且你需要全部更改其头部或底部时你要花费多大精力?一页一页的手工更改是一件多么冗长无趣的事情啊!所以我们应该为这些页面编写PHP的头部和底部文件,之后我们只要在每个HTML页面中引用它们就行了。在include和require函数中都包含一个PHP代码的文件,不管该文件的扩展名是什么,它都被当作是PHP文件。我们将把这些include文件放在一个叫include的子目录下,并取成以.inc为后缀的文件。下面我们就把这些站点的通用内容写进文件中。

全站通用变量设定:common.inc
<?
// 全站通用变量
$MyEmail = \"phptalk@tnc.org\";
$MyEmailLink = \"<a href=\'mailto:$MyEmail\'>$MyEmail</a>\";
$MyName = \"PHP Talk\";
$MySiteName = $MyName.\"\'s Home Page\";
?>

通用页面头部:header.inc
<?
// 定义通用页面头部
?>
<HTML>
<HEAD>
<TITLE>
<? echo \"$MySiteName - $title\"; ?>
</TITLE>
</HEAD>
<BODY>
<H1>
<? echo \"$MySiteName\"; ?>
</H1>
<H2>
<? echo \"$title\"; ?>
</H2>
<HR>

通用页面底部:footer.inc
<?
// 通用页面底部
?>
<HR>
<P ALIGN=\"CENTER\">
<SMALL> <I>
Copyright ? by
<? echo \"$MyName ($MyEmailLink)\"; ?>
, 1999
</I> </SMALL>
</P>
</BODY>
</HTML>

新的页面front.php3:
<?
include(\"include/common.inc\");
$title = \"Welcome\";
include(\"include/header.inc\");
?>
<P>
欢迎来我的寒舍,虽然这里现在暂时还没有什么。
</P>
<P>
不过我希望马上就可以多起来。
</P>
<?
include(\"include/footer.inc\");
?>

新的count.php3:
<?
include(\"include/common.inc\");
$title = \"Contact Information\";
include(\"include/header.inc\");
?>
<P>
你可以通过1-800-PHP-INFO联系我
</P>
<?
include(\"include/footer.inc\");
?>

  现在你可以体会一下这样安排的好处了。如果你想改动页面的头部或者底部,你只需要改动相应的文件就可以了。如果你要修改你的e-mail地址甚至你的名字,只要修改common.inc文件就行了。另外值得注意的是你可以把具有任何文件名或者文件扩展名的文件包含进你的文件中,你甚至可以包含其他站点上的文件。

PHP新手上路(四)

PHP入门

 

4.1 数据类型

  PHP支持整数、浮点数、字符串、数组和对象。变量类型通常不由程序员决定而由PHP运行过程决定(真是好的解脱!)。当然,如果你喜欢的话,你也可以使用cast或者函数settype()将某种类型的变量转换成指定的类型。

数值

  数值类型可以是整数或是浮点数。你可以用以下的语句来为一个数值赋值:
$a = 1234; # 十进制数
$a = -123; # 负数
$a = 0123; # 八进制数 (等于十进制数的83)
$a = 0x12; # 十六进制数(等于十进制数的18)
$a = 1.234; # 浮点数"双精度数"
$a = 1.2e3; # 双精度数的指数形式

字符串

  字符串可以由单引号或双引号引出的字段定义。注意不同的是被单引号引出的字符串是以字面定义的,而双引号引出的字符串可以被扩展。而且,在双引号字符串中可以使用反斜杠()在字符串中加入转义序列和转换字符。举例如下:

$first = 'Hello';
$second = "World";
$full1 = "$first $second"; # 产生 Hello World
$full2 = '$first $second';# 产生 $first $second
$full3="01DC studio,." 2000 copyright." " ;

  请注意最后一行,如果需要在字符串中使用双引号,可以使用反斜杠字符,象该行语句所示。这里的的反斜杠用来使双引号的功能改变。

  可以将字符和数字利用运算符号连接起来。字符被转化成数字,利用其最初位置。在PHP手册中有详细的例子。

数组与哈希表

  数组与哈希表以同样的方法被支持。怎样运用取决于你怎样定义它们。你可以用list()或者array()来定义它们,也可以直接为数组赋值。数组的索引从0开始。虽然我在这里没有说明,但是你一样可以轻易的使用多维数组。

// 一个包含两个元素的数组
$a[0] = "first";
$a[1] = "second";
$a[] = "third"; // 添加数组元素的简单方法
// 现在$a[2]被赋值为"third"
echo count($a); // 打印出3,因为该数组有3个元素
// 用一个语句定义一个数组并赋值
$myphonebook = array (
"sbabu" => "5348",
"keith" => "4829",
"carole" => "4533"
);
// 噢,忘了教长吧,让我们添加一个元素
$myphonebook["dean"] = "5397";
// 你定义的carale元素错了,让我们更正它
$myphonebook["carole"] => "4522"
// 我还没有告诉你怎样使用数组的相似支持方式吗?让我们看一看
echo "$myphonebook[0]"; // sbabu
echo "$myphonebook[1]"; // 5348

其他一些对数组或哈希表有用的函数包括sort(),next(),prev()和each()。

对象

  使用new语句产生一个对象:
class foo
{
function do_foo ()
{
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo();

改变变量类型

  在PHP手册中提到:"PHP不支持(也不需要)直接在声明变量时定义变量类型;变量类型将根据其被应用的情况决定。如果你为变量var赋值为一个字符串,那么它变成了一个字符串。如果你又为它赋了整数值,那么它就变成了整数。"

$foo = "0"; // $foo是字符串(ASCII 48)
$foo ; // $foo是字符串"1" (ASCII 49)
$foo = 1; // $foo现在是整数(2)
$foo = $foo 1.3; // $foo是一个双精度数(3.3)
$foo = 5 "10 Little Piggies"; // $foo是一个整数(15)
$foo = 5 "10 Small Pigs"; // $foo是一个整数(15)

如果想要强行转换变量类型,可以使用与C语言相同的函数settype()。

4.2 变量与常量

  可能你已经注意到,变量都有一个美元符号($)的前缀。所有变量都是局部变量,为了使得定义的函数中可以使用外部变量,使用global语句。而你要将该变量的作用范围限制在该函数之内,使用static语句。
$g_var = 1 ; // 全局范围
function test()
{
global $g_var; // 这样就可以声明全局变量了
}

  更先进一些的是变量的变量表示。请参考PHP手册。这在有时会显得很有用。

  PHP内置了许多已定义的变量。你也可以用define函数定义你自己的常量,比如define("CONSTANT","value")。

4.3 运算符

  PHP具有C,C 和Java中的通常见到的运算符。这些运算符的优先权也是一致的。赋值同样使用"="。

算术和字符

  以下只有一种运算符是有关字符的:
$a $b :加
$a - $b :减
$a * $b :乘
$a / $b :除
$a % $b :取模(余数)
$a . $b :字符串连接

逻辑和比较

逻辑运算符有:
$a || $b :或
$a or $b :或
$a && $b :与
$a and $b :与
$a xor $b :异或 (当$a或$b为true时为true,两者一样时为false)
! $a :非
比较运算符有:
$a == $b :相等
$a != $b :不等
$a < $b :小于
$a <= $b :小于等于
$a > $b :大于
$a >= $b :大于等于
与C一样PHP也有三重运算符(?:)。位操作符在PHP同样存在。

优先权

就和C以及Java一样!

4.4 控制流程结构

  PHP有着与C一样的流程控制。我将在下面大概介绍。

if, else, elseif, if(): endif

if (表达式一)
{
. . .
}
elseif (表达式二)
{
. . .
}
else
{
. . .
}
// 或者像Python一样
if (表达式一) :
. . .
. . .
elseif (表达式二) :
. . .
else :
. . .
endif ;

Loops. while, do..while, for

while (表达式)
{
. . .
}
do
{
. . .
}
while (表达式);
for (表达式一; 表达式二; 表达式三)
{
. . .
}
//或者像Python一样
while (expr) :
. . .
endwhile ;

switch

switch是对多重if-elseif-else结构的最好的替换:
switch ($i)
{
case 0:
print "i equals 0";
case 1:
print "i equals 1";
case 2:
print "i equals 2";
}

break, continue

break中断当前的循环控制结构。
continue被用来跳出剩下的当前循环并继续执行下一次循环。

require, include

  就像C中的#include预处理一样。你在require中指定的那个文件将替代其在主文件中的位置。在有条件的引用文件时,可以使用include()。这样就使得你可以将复杂的PHP文件分割成多个文件并且在不同需要时分别引用它们。

4.5 函数

  你可以像以下的例子一样定义自己的函数。函数的返回值可以是任何数据类型:
function foo (变量名一, 变量名二, . . . , 变量名n)
{
echo "Example function.n";
return $retval;
}

  所有PHP代码都可以出现在函数定义中,甚至包括对其他函数和类的定义。函数必须在引用之前定义。

4.6 类

  利用类模型建立类。可以参考PHP手册中对类的详细解释。
class Employee
{
var $empno; // 员工人数
var $empnm; // 员工姓名

function add_employee($in_num, $in_name)
{
$this->empno = $in_num;
$this->empnm = $in_name;
}

function show()
{
echo "$this->empno, $this->empnm";
return;
}

function changenm($in_name)
{
$this->empnm = $in_name;
}
}

$sbabu = new Employee;
$sbabu->add_employee(10,"sbabu");
$sbabu->changenm("babu");
$sbabu->show();

PHP新手上路(三)

从一个简单的程序来了解PHP

 

  PHP站点的在线教程已经很棒了。而本文的该部分将让你对PHP熟悉一点。我不可能做到没有任何遗漏,我的目的只在于能让你迅速开始你的PHP编程。

3.1 首要条件

  你首先必须要有一个正在工作着的支持PHP的web服务器。我假定在你的服务器上所有PHP文件的扩展名为.php3。

3.2 PHP的安装

  有关PHP的安装配置,可以查阅网页陶吧上的“PHP安装全攻略”专题文章。

3.3 语法

  从语法上看,PHP语言近似于C语言。可以说,PHP是借鉴C语言的语法特征,由C语言改进而来的。我们可以混合编写PHP代码和HTML代码,不仅可以将PHP脚本嵌入到 HTML 文件中,我们甚至还可以把 HTML 标签也嵌入在 PHP 脚本里。以下是你可以采用的几种方法。你可以选用其中一种你最适合的并且就这样坚持这种方法!

从HTML中分离

以下是可以使用的方法:
<? . . . ?>
<?php . . . ?>
<script language="php"> . . . </script>
<% . . . %>

  注:当你使用“<? . . . ?>”将PHP代码嵌入于HTML文件中时,可能会同XML发生冲突,同时,能否使用这一缩减形式还取决于PHP本身的设置。为了可适应XML和其它编辑器,你可以在开始的问号后面加上“php”使PHP代码适应于XML分析器。如:“<?php. . . ?>”。也可以像写其它脚本语言那样使用脚本标记,如:“<script language="php"> . . . </script>”。


语句

与Perl和C一样,在PHP中用“;”来分隔语句。那些从HTML中分离出来的标志也表示语句的结束。

注释

PHP支持C,C 和Unix风格的注释方式:

/* C,C 风格多行注释 */
// C 风格单行注释
# Unix风格单行注释

echo 和 print

  PHP 和 HTML 最简单的交互是通过 print 和 echo 语句来实现的,在实际使用中, print 和 echo 两者的功能几乎是完全一样。可以这么说,凡是有一个可以使用的地方,另一个也可以使用。但是,两者之间也还是一个非常重要的区别:在 echo 函数中,可以同时输出多个字符串,而在 print 函数中则只可以同时输出一个字符串。同时,echo函数并不需要圆括号,所以echo函数更像是语句而不像是函数。让我们来看看下面这一实例:

<?
$a="hello";
$b="world";
echo "a","b";
print "a","b";
?>

用浏览器观看这段代码的运行情况后,你会看到这样的运行结果:
aba
Parse error: parse error in d:adminmyphphometest.php3 on line 5
这说明这段代码并不能完全通过解释,发生错误的地方就在代码的第五行:“print "a","b";”。

3.4一个简单的实例

  通过我们已经学过的知识,你可以编写一个最简单的程序输出一个也许是程序世界中最有名的词语
<HTML>
<HEAD>
<TITLE>
<?
echo "Hello World!";
?>
</TITLE>
</HEAD>
<BODY>
<H1>
First PHP page
</H1>
<HR>
<?
// Single line C style comment
/*
printing the message
*/
echo "Hello World!";
# Unix style single line comment
?>
</BODY>
</HTML>

PHP新手上路(二)

为什么要选择PHP

 

2. 竞争对手:ASP,mod_perl,JSP

  用于实现交互式动态网页的技术有好多,其中CGI又称通用网关接口(Common Gateway Interface),是外部程序和WEB服务器之间的标准编程接口,但是CGI程序带来的缺点实在太多;而Perl很好地解决了CGI中的问题,被用来驱动复杂的WEB技术;微软的ASP(Active Server Pages)的出现,以它容易上手、轻松编写程序和微软件强有力的支持后盾使得ASP一下子成了许专业编程人员和非专业编程人员的宠儿;Middle ware和Allaire的Cold Fusion是另一种解决方法,并且Cold Fusion有一个已证实可靠的搜索引擎组件;JSP 是Sun公司推出的新一代站点开发语言等等。有这么多的动态WEB技术,也许你会问:“为什么我要选择PHP呢?”

  在回答这一问题之前,让我们先来看看ASP,PHP和JSP之间的优缺点。

2.1 关于ASP

  ASP 由于其简单功能实用等方面受到广大朋友的喜欢,再加上MS的强有力支持,可以说是时下作站点最为流行的语言之一,他借助MS的Com 技术,几乎可以实现在C/S 能够实现的所有功能,可以说确实具有相当的竞争力。ASP的代码实现也很简单,MS 提供的InterDev 在RAD 的基础上,使ASP 的开发一夜之间火遍了大江南北。但是他的缺点是,由于MS 长久以来的霸道作风,他只能运行在MS的平台上,因此在关键性的应用上使人难以轻易接受。

2.2 关于JSP

  JSP 是Sun公司推出的新一代站点开发语言,他完全解决了目前ASP,PHP的一个通病--脚本级执行(现在PHP4 也已经在Zend 的支持下,实现编译运行).Sun 公司借助自己在Java 上的不凡造诣,将Java 从Java 应用程序 和 Java Applet 之外,又有新的硕果,就是Jsp--Java Server Page。Jsp 可以在Serverlet和JavaBean的支持下,完成功能强大的站点程序。

  据我所知,JSP基于Java,因此Java程序员可以轻松开始编码。ASP只是一个一般的引擎,具有支持多种语言的能力,不过默认的并且是最常用的还是VBScript。mod_perl与Perl一样强大,只是更快一些。

  对于ASP、JSP、PHP等,到底哪种语言更好?不同的人有不同的看法。不过有一点我们必须要明确的:对于ASP、JSP等,你是否清楚购买它们会有多昂贵以及它们需要多么昂贵和强大的硬件。如果你有什么中立的观点(比如说没有被SUN和Microsoft的百万美金所影响),请顺便通知我。

2.3 关于PHP

  PHP 是秉承Linux 的GNU 风格,借助与源码公开,使他迅速成为世界上目前应用最为广泛的站点制作语言之一。借助与C 的形式,引用类的概念,使得代码的可重复性应用便的异常简单。加上他和Linux,Apache 和MySql 的紧密配合,关键性的应用也没有问题(有名的Sina就是采用Php)。同时,PHP第四代Zend(PHP4)的核心引擎正式版也已经发布了,整个程序的核心得到了大幅度的改进,让PHP程序的执行速度变得更快。PHP在最佳化之后的效率,已比传统CGI或者ASP等程序有了更好的表现。而且正因为PHP是免费的,因此任何人都可以访问PHP WEB站点,下载完整的源代码。更重要的是:用PHP编写的代码执行起来会更快,能实现同样功能的PHP代码,不用改变就可以在不同的WEB服务器上、不同的操作系统下运行。就凭这一点,你就已经有足够的理由选择PHP。

PHP新手上路(一)

简介

 

  PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的WEB站点。本教程并不想让你完全了解这种语言,只是能使你尽快加入开发动态web站点的行列。我假定你有一些HTML(或者HTML编辑器)的基本知识和一些编程思想。

1.简介

  PHP是能让你生成动态网页的工具之一。PHP代表:超文本预处理器(PHP: Hypertext Preprocessor)。PHP是完全免费的,不用花钱,你可以从PHP官方站点(http://www.php.net)自由下载。PHP遵守 GNU公共许可(GPL),在这一许可下诞生了许多流行的软件诸如Linux和Emacs。你可以不受限制的获得源码,甚至可以从中加进你自己需要的特色。PHP在大多数Unix平台,GUN/Linux和微软Windows平台上均可以运行。怎样在Windows环境的PC机器或Unix机器上安装 PHP的资料可以在PHP官方站点上找到,也可以查阅网页陶吧的“PHP安装全攻备”专题文章。安装过程很简单。

  如果你的机器解决了2000问题,那么PHP也一样没有千年虫问题!

1.1 历史

  三年前,Rasmus Lerdorf为了创建他的在线简历而创造了"个人主页工具"(Personal Home Page Tools)。这是一种非常简单的语言。其后越来越多的人们注意到了这种语言并对其扩展提出了各种建议。在许多人的无私奉献下以及这种语言本身的源代码自由性质,它演变成为一种特点丰富的语言,而且现在还在成长中。

  PHP虽然很容易学习,但是速度上比mod_perl(植入web服务器的perl模块)慢。现在有了可以与mod_perl速度想媲美的被称作Zend的新引擎,而PHP4就可以充分利用这个引擎。现在,PHP4正式版已经发布,大家可以到php的官方站点上去下载。Andy Gutmans和Zeev Suraki是Zend的主要作者。可以去Zend站点(http://www.zend.com)了解更多。

  PHP的应用在个人性质的web工程中增长显著。根据Netcraft在1999年10月的报告,有931122个域和321128个IP地址利用PHP技术。

1.2 PHP的先进之处

  应用PHP有许多好处。当然已知的不利之处在于PHP由于是开放源码项目,没有什么商业支持,并且由此而带来的执行速度缓慢(直到PHP4之前)。但是PHP的邮件列表很是有用而且除非你正在运行像Yahoo!或者Amazon.com这样的极受欢迎的站点,你不会感觉出PHP的速度与其他的有什么不同。最起码我就没有感觉出来!好了,让我们来看看PHP有那些优点:

- 学习过程

  我个人更喜欢PHP的非常简单的学习过程。与Java和Perl不同,你不必把头埋进100多页的文档中努力学习才可以写出一个象样的程序。只要了解一些基本的语法和语言特色,你就可以开始你的PHP编码之旅了。之后你在编码过程中如果遇到了什么麻烦,还可以再去翻阅相关文档。

  PHP的语法类似于C,Perl,ASP或者JSP。对于那些对上述之一的语言较熟悉的人来说,PHP太简单了。相反的,如果你对PHP了解较多,那么你对于其他几种语言的学习都很简单了。

  你只需要30分钟就可以将PHP的核心语言特点全部掌握,你可能已经非常了解HTML,甚至你已经知道怎样用编辑设计软件或者手工来制作好看的 WEB站点。由于PHP代码能够无障碍的添加进你的站点,在你设计和维护站点的同时,你可以很轻松的加入PHP使得你的站点更加具有动态特性。

- 数据库连接

  PHP可以编译成具有与许多数据库相连接的函数。PHP与MySQL是现在绝佳的组合。你还可以自己编写外围的函数取间接存取数据库。通过这样的途径当你更换使用的数据库时,可以轻松的更改编码以适应这样的变化。PHPLIB就是最常用的可以提供一般事务需要的一系列基库。

- 可扩展性

  就像前面说的那样,PHP已经进入了一个高速发展的时期。对于一个非程序员来说为PHP扩展附加功能可能会比较难,但是对于一个PHP程序员来说并不困难。

- 面向对象编程

  PHP提供了类和对象。基于web的编程工作非常需要面向对象编程能力。PHP支持构造器、提取类等。

- 可伸缩性

  传统上网页的交互作用是通过CGI来实现的。CGI程序的伸缩性不很理想,因为它为每一个正在运行的CGI程序开一个独立进程。解决方法就是将经常用来编写CGI程序的语言的解释器编译进你的web服务器(比如mod_perl,JSP)。PHP就可以以这种方式安装,虽然很少有人愿意这样以 CGI方式安装它。内嵌的PHP可以具有更高的可伸缩性。

- 更多特点

  PHP的开发者们为了更适合web编程,开发了许多外围的流行基库,这些库包含了更易用的层。你可以利用PHP连接包括Oracle,MS- Access,Mysql在内的大部分数据库。你可以在苍蝇上画图,编写程序下载或者显示e-mail。你甚至可以完成网络相关的功能。最好的是,你可以选择你的PHP安装版本需要哪些功能。引用Nissan的Xterra的话来说就是PHP可以做到你想让它做到的一切而且无所不能!

PHP初学者头疼问题总结

1】页面之间无法传递变量 get,post,session在最新的php版本中自动全局变量是关闭的,所以要从上一页面取得提交过来得变量要使用$_GET['foo'],$_POST['foo'],$_SESSION['foo']来得到
当然也可以修改自动全局变量为开(php.ini改为register_globals = On);考虑到兼容性,还是强迫自己熟悉新的写法比较好。
================================
PHP中的超全局变量
从PHP 4.2.0 开始,register_globals 的默认值为 off,这样一来,以前的很多可以直接使用的变量,如 $PHP_SELF 或者你设定的SESSION变量都不能用 “$变量名”的形式访问了,这可能会给你带来很多不变,但却有助于安全性的提高。访问这些变量,你需要使用PHP 超全局变量,如下:

$_SERVER
变量由 Web 服务器设定或者直接与当前脚本的执行环境相关联。类似于旧数组 $HTTP_SERVER_VARS 数组。以前的$PHP_SELF对应$_SERVER['PHP_SELF'],你可以使用phpinfo来查看你的$_SERVER变量。

$_GET
经由 HTTP GET 方法提交至脚本的变量。类似于旧数组 $HTTP_GET_VARS 数组。

$_POST
经由 HTTP POST 方法提交至脚本的变量。类似于旧数组 $HTTP_POST_VARS 数组。

$_COOKIE
经由 HTTP Cookies 方法提交至脚本的变量。类似于旧数组 $HTTP_COOKIE_VARS 数组。

$_SESSION
当前注册给脚本会话的变量。类似于旧数组 $HTTP_SESSION_VARS 数组。

$_FILES
经由 HTTP POST 文件上传而提交至脚本的变量。类似于旧数组 $HTTP_POST_FILES 数组。

$_ENV
执行环境提交至脚本的变量。类似于旧数组 $HTTP_ENV_VARS 数组。

====================================================================
对于$_FILES变量:(文件域字段为“myfile”)

$_FILES['myfile']['name']  
客户端机器文件的原名称(包括路径)。

$_FILES['myfile']['type']  
文件的 MIME 类型,需要浏览器提供该信息的支持,例如“image/gif”。

$_FILES['myfile']['size']  
已上传文件的大小,单位为字节。  

$_FILES['myfile']['tmp_name']  
文件被上传后在服务端储存的临时文件名(包括路径)。

$_FILES['myfile']['error']  
和该文件上传相关的错误代码。['error'] 是在 PHP 4.2.0 版本中增加的。  

当 php.ini 中的 register_globals 被设置为 on 时,$myfile_name 等价于 $_FILES['myfile']['name'],$myfile_type 等价于 $_FILES['myfile']['type']等。  




=========================================
【2】Win32下apache2 用get方法传递中文参数会出错
test.php?a=你好&b=你也好
传递参数是会导致一个内部错误
解决办法:"test.php?a=".urlencode(你好)."&b=".urlencode(你也好)

.............


【3】win32下的session不能正常工作
php.ini默认的session.save_path = /tmp
这显然是linux下的配置,win32下php无法读写session文件导致session无法使用
把它改成一个绝对路径就可以了,例如session.save_path = c:\windows\temp

【4】显示错误信息
当php.ini的display_errors = On并且error_reporting = E_ALL时,将显示所有的错误和提示,调试的时候最好打开以便纠错,如果你用以前php写法错误信息多半是关于未定义变量的。变量在赋值以前调用会有提示,解决办法是探测或者屏蔽
例如显示$foo,可以if(isset($foo)) echo $foo 或者echo @$foo

【5】Win32下mail()不能发送电子邮件
在linux下配置好的sendmail可以发送,在win32下需要调用smtp服务器来发送电子邮件
修改php.ini的SMTP = ip //ip是不带验证功能的smtp服务器(网上很难找到)
php发送邮件的最好解决方法是用socket直接发送到对方email服务器而不用转发服务器

【6】初装的mysql如果没有设置密码,应该使用
update mysql.user set password="yourpassword" where user="root"
修改密码

【7】header already sent
这个错误通常会在你使用HEADER的时候出现,他可能是几种原因:1,你在使用HEADER前PRING或者ECHO了2.你当前文件前面有空行3.你可能INCLUDE了一个文件,该文件尾部有空行或者输出也会出现这种错误。!

【8】更改php.ini后没有变化
重新启动web server,比如IIS,Apache等等,然后才会应用最新的设置

【9】php在2003上面安装(ISAPI的安装方法恳请高手指教)
PHP4的php4isapi.dll好像和2003有些冲突,只能用CGI模式安装
步骤一,先www.php.net下在一个安装程序,我是装的是:php-4.2.3-installer.exe,你也可以去找最新的版本,在安装php-4.2.3-installer.exe之前保证你的IIS6.0启动了,并能够访问。 安装好以后,在默认网站-->应用程序配置
步骤二:点击 web服务扩展 -->新建web服务扩展.
步骤三: 扩展名-->php,然后添加
步骤四:找到php.exe的路径添加上去。
步骤五: 确定就可以了!
步骤六: 选择php的服务扩展,然后点击允许。

【10】
有时候sql语句不起作用,对数据库操作失败
最简便的调试方法,echo那句sql,看看变量的值能得到不

【11】include和require的区别
两者没有太大的区别,如果要包含的文件不存在,include提示notice,然后继续执行下面的语句,require提示致命错误并且退出
据我测试,win32平台下它们都是先包含后执行,所以被包含文件里最好不要再有include或require语句,这样会造成目录混乱。或许*nux下情况不同,暂时还没测试
如果一个文件不想被包含多次可以使用include_once或require_once## 读取,写入文档数据
function r($file_name) {
$filenum=@fopen($file_name,"r");
@flock($filenum,LOCK_SH);
$file_data=@fread($filenum,filesize($file_name));
@fclose($filenum);
return $file_data;
}
function w($file_name,$data,$method="w"){
$filenum=@fopen($file_name,$method);
flock($filenum,LOCK_EX);
$file_data=fwrite($filenum,$data);
fclose($filenum);
return $file_data;
}

【12】isset()和empty()的区别
两者都是测试变量用的
但是isset()是测试变量是否被赋值,而empty()是测试一个已经被赋值的变量是否为空
如果一个变量没被赋值就引用在php里是被允许的,但会有notice提示
如果一个变量被赋空值,$foo=""或者$foo=0或者 $foo=false,那么empty($foo)返回真,isset($foo)也返回真,就是说赋空值不会注销一个变量。
要注销一个变量,可以用 unset($foo)或者$foo=NULL

【13】mysql查询语句包含有关键字
php查询mysql的时候,有时候mysql表名或者列名会有关键字
这时候查询会有错误。例如表名是order,查询时候会出错
简单的办法是sql语句里表名或者列名加上`[tab键上面]来加以区别
例如select * from `order`

【14】通过HTTP协议一次上传多个文件的方法
有两个思路,是同一个方法的两种实现。具体程序还需自己去设计
1,在form中设置多个文件输入框,用数组命名他们的名字,如下:
<form action="" method=post>
<input type=file name=usefile[]>
<input type=file name=usefile[]>
<input type=file name=usefile[]>
</form>
这样,在服务器端做以下测试
echo "<pre>";
print_r($_FILES);
echo "</pre>";

1,在form中设置多个文件输入框,但名字不同,如下:
<form action="" method=post>
<input type=file name=usefile_a>
<input type=file name=usefile_b>
<input type=file name=usefile_c>
</form>
在服务器端做同样测试:
echo "<pre>";
print_r($_FILES);
echo "</pre>";