29.4 了解脚本架构
正如我们前面提到的,该应用程序使用一个脚本控制所有操作。该脚本叫做index.php,如程序清单29-2所示。该脚本比较长,我们逐段详细介绍。
程序清单29-2 index.php——Warm Mail系统的框架
<?php
//This file is the main body of the Warm Mail application.
//It works basically as a state machine and shows users the
//output for the action they have chosen.
//*
//Stage 1:pre-processing
//Do any required processing before page header is sent
//and decide what details to show on page headers
//*
include('include_fns.php');
session_start();
//create short variable names
$username=$_POST['username'];
$passwd=$_POST['passwd'];
$action=$_REQUEST['action'];
$account=$_REQUEST['account'];
$messageid=$_GET['messageid'];
$to=$_POST['to'];
$cc=$_POST['cc'];
$subject=$_POST['subject'];
$message=$_POST['message'];
$buttons=array();
//append to this string if anything processed before header has output
$status='';
//need to process log in or out requests before anything else
if($username||$password){
if(login($username,$passwd)){
$status.="<p style=\"padding-bottom:100px\">Logged in
successfully.</p>";
$_SESSION['auth_user']=$username;
if(number_of_accounts($_SESSION['auth_user'])==1){
$accounts=get_account_list($_SESSION['auth_user']);
$_SESSION['selected_account']=$accounts[0];
}
}else{
$status.="<p style=\"padding-bottom:100px\">Sorry,we could
not log you in with that username and password.</p>";
}
}
if($action=='log-out'){
session_destroy();
unset($action);
$_SESSION=array();
}
//need to process choose,delete or store account before drawing header
switch($action){
case'delete-account':
delete_account($_SESSION['auth_user'],$account);
break;
case'store-settings':
store_account_settings($_SESSION['auth_user'],$_POST);
break;
case'select-account':
//if have chosen a valid account,store it as a session variable
if(($account)&&(account_exists($_SESSION['auth_user'],$account))){
$_SESSION['selected_account']=$account;
}
break;
}
//set the buttons that will be on the tool bar
$buttons[0]='view-mailbox';
$buttons[1]='new-message';
$buttons[2]='account-setup';
//only offer a log out button if logged in
if(check_auth_user()){
$buttons[4]='log-out';
}
//*
//Stage 2:headers
//Send the HTML headers and menu bar appropriate to current action
//*
if($action){
//display header with application name and description of page or action
do_html_header($_SESSION['auth_user'],"Warm Mail-".
format_action($action),
$_SESSION['selected_account']);
}else{
//display header with just application name
do_html_header($_SESSION['auth_user'],"Warm Mail",
$_SESSION['selected_account']);
}
display_toolbar($buttons);
//*
//Stage 3:body
//Depending on action,show appropriate main body content
//*
//display any text generated by functions called before header
echo$status;
if(!check_auth_user()){
echo"<p>You need to log in";
if(($action)&&($action!='log-out')){
echo"to go to".format_action($action);
}
echo".</p>";
display_login_form($action);
}else{
switch($action){
//if we have chosen to setup a new account,or have just added or
//deleted an account,show account setup page
case'store-settings':
case'account-setup':
case'delete-account':
display_account_setup($_SESSION['auth_user']);
break;
case'send-message':
if(send_message($to,$cc,$subject,$message)){
echo"<p style=\"padding-bottom:100px\">Message sent.</p>";
}else{
echo"<p style=\"padding-bottom:100px\">Could not send message.</p>";
}
break;
case'delete':
delete_message($_SESSION['auth_user'],
$_SESSION['selected_account'],$messageid);
//note deliberately no'break'-we will continue to the next case
case'select-account':
case'view-mailbox':
//if mailbox just chosen,or view mailbox chosen,show mailbox
display_list($_SESSION['auth_user'],
$_SESSION['selected_account']);
break;
case'show-headers':
case'hide-headers':
case'view-message':
//if we have just picked a message from the list,or were looking at
//a message and chose to hide or view headers,load a message
$fullheaders=($action=='show-headers');
display_message($_SESSION['auth_user'],
$_SESSION['selected_account'],
$messageid,$fullheaders);
break;
case'reply-all':
//set cc as old cc line
if(!$imap){
$imap=open_mailbox($_SESSION['auth_user'],
$_SESSION['selected_account']);
}
if($imap){
$header=imap_header($imap,$messageid);
if($header->reply_toaddress){
$to=$header->reply_toaddress;
}else{
$to=$header->fromaddress;
}
$cc=$header->ccaddress;
$subject="Re:".$header->subject;
$body=add_quoting(stripslashes(imap_body($imap,$messageid)));
imap_close($imap);
display_new_message_form($_SESSION['auth_user'],
$to,$cc,$subject,$body);
}
break;
case'reply':
//set to address as reply-to or from of the current message
if(!$imap){
$imap=open_mailbox($_SESSION['auth_user'],
$_SESSION['selected_account']);
}
if($imap){
$header=imap_header($imap,$messageid);
if($header->reply_toaddress){
$to=$header->reply_toaddress;
}else{
$to=$header->fromaddress;
}
$subject="Re:".$header->subject;
$body=add_quoting(stripslashes(imap_body($imap,$messageid)));
imap_close($imap);
display_new_message_form($_SESSION['auth_user'],
$to,$cc,$subject,$body);
}
break;
case'forward':
//set message as quoted body of current message
if(!$imap){
$imap=open_mailbox($_SESSION['auth_user'],
$_SESSION['selected_account']);
}
if($imap){
$header=imap_header($imap,$messageid);
$body=add_quoting(stripslashes(imap_body($imap,$messageid)));
$subject="Fwd:".$header->subject;
imap_close($imap);
display_new_message_form($_SESSION['auth_user'],
$to,$cc,$subject,$body);
}
break;
case'new-message':
display_new_message_form($_SESSION['auth_user'],
$to,$cc,$subject,$body);
break;
}
}
//*
//Stage 4:footer
//*
do_html_footer();
?>
这个脚本使用一个事件处理的方法。它包含对于每个事件应该调用哪个函数的知识或逻辑。在这种情况下,事件是由用户点击站点内不同的按钮触发的,每一个按钮对应一种动作。大多数按钮都是由display_button()函数产生的,但是如果用户点击的按钮是提交按钮时,则是调用display_form_button()函数。这些函数都在output_fns.php中。这些都转至表单的URL:
index.php?action=log-out
当调用index.php时,action变量值决定哪一个事件处理程序被触发。
该脚本由如下所示的4个主要部分组成:
1)在将页面标题发送到浏览器之前要做一些必要的处理,例如,开始一个会话,执行用户选择的动作所必须的预处理操作,并确定页面标题的内容。
2)为用户选择的动作处理和发送适当的标题和菜单条。
3)选择要执行哪一块代码,取决于用户所选的动作。不同的动作将触发不同的函数调用。
4)发送页面的页脚。
如果粗略地看一下代码,会发现这四个部分都用注释作了标记。
为了完全理解脚本程序,让我们来真正使用这个站点。