首页专业论文技术应用政策标准解决方案常用资料经验交流教育培训企业技术专家访谈电力期刊
您现在的位置:北极星电力网 > 技术频道 > 常用资料 > 为IBMLotusDomino构建基于PHP的用户界面

为IBMLotusDomino构建基于PHP的用户界面

北极星电力网技术频道    作者:AndreiKouvchinnikov   2008/8/6 13:42:46   

 关键词:

了解如何通过用PHP编程语言创建的Web应用程序与LotusDomino交互。学习利用COM对象、LotusNotesAPI及XML通过PHP页面访问Domino应用程序的方法。

在本文中,您将了解如何通过用PHP编程语言创建的Web应用程序与IBMLotusDomino数据库交互。还将学习利用COM对象、IBMLotusNotes应用程序编程接口(API)及XML通过PHP页面访问Domino应用程序的方法。末尾处的下载部分中包含各方法的示例代码。对于XML方法,还将提供一个带有IBMLotusDomino邮件数据库简单Web界面的示例应用程序供下载(参见图1)。



图1.邮件数据库PHP用户界面示例


PHP是一种强大的嵌入式脚本语言,可免费使用,它是开发动态Web应用程序的流行工具。PHP代码不经过编译,而是在运行时加以解释。其语法大多借鉴自C、Java和Perl编程语言。可将PHP作为通用网关接口(CommonGatewayInterface,CGI)引擎添加到绝大多数Web服务器中。甚至在MicrosoftWindows和Linux操作系统中也可以正常工作。此外,超过50的Web托管公司都拥有启用了PHP的服务器。PHP技术的应用如此广泛,不熟悉这种技术显然损失不小。

使用PHP

借助特殊标签即可在Web页面中包含PHP代码。所有的PHP代码均以<php标签开头,以?>标签结束:

<html><body><?phpecho“HelloWorld!”;?></body></html>


Web服务器解释这一简单示例,并将其转换为以下HTML输出:

<html><body>HelloWorld!</body></html>


PHPWeb页面可通过多种方式与Domino数据库交互。集成方法的选择取决于运行PHP的操作系统、PHP与Domino服务器之间存在的安全性约束,以及允许在PHP服务器上安装的内容。本文介绍的方法为:

  • COM对象
  • NotesAPI
  • 利用XML通过Web交互

脱机运行PHP代码

尽管PHP主要用于在Web服务器而非单机应用程序上运行,但您可将其作为MicrosoftVisualBasicScriptingEdition(VBScript)那样的shell脚本工具,通过命令行运行PHP。将文件放置在Web服务器之前进行脱机测试时,这项特性可能非常有用。

访问LotusDomino

访问Domino数据库的方法有三种:通过COM对象、通过NotesAPI和通过XML。

使用COM对象访问LotusDomino

要访问存储于Domino数据库中的信息,最简便、最迅速的方法就是使用DominoCOM对象。在PHP中使用COM并不比在LotusScript中困难。以下代码示例展示了如何在一个视图中输出所有文档的字段值。

<?php//InitiateLotusNotessession$session=newCOM("Lotus.NotesSession");$session->Initialize();//ShowthenameofthecurrentNotesuserprint"Currentuser:".$session->CommonUserName."\n\n";//Getdatabasehandle$db=$session->getDatabase("","mailtest.nsf");//Getviewhandleusingpreviouslyreceiveddatabasehandle.//Notethatthereservedcharacterintheviewnamemustbe\-escaped$view=$db->getView("(\$Drafts)");//Getfirstdocumentinviewusingpreviouslyreceivedviewhandle$doc=$view->getFirstDocument();//Loopuntilalldocumentsinviewareprocessedwhile(is_object($doc)){//Gethandletoafieldcalled"Subject"$field=$doc->GetFirstItem("Subject");//Gettextvalueofthefield$fieldvalue=$field->text;//Showthevalueofthefieldprint"Subject:".$fieldvalue."\n";//Getnextdocumentintheview$doc=$view->getNextDocument($doc);}//Releasethesessionobject$session=null;?>

图2展示了通过命令行运行此COM对象的输出结果。



图2.在命令提示符中运行COM对象代码的结果


使用COM对象比较简单,但一些缺点使这种方法具有局限性。主要缺点就是PHP服务器上必须安装有LotusNotes客户机软件。如果您的PHP应用程序由Web托管公司托管,恐怕很难说服托管公司专门为您的PHPWeb站点安装Notes客户机。如果您拥有自己的PHP服务器或者PHP服务器和Domino服务器位于同一台计算机上,那么设置Domino服务器的COM访问就没有什么问题了。

限制COM使用的另一问题就是COM对象只在Windows平台上受支持。考虑到绝大多数PHP服务器都运行在Linux平台上,这一需求会大大减少可选择用于托管COM解决方案的服务器数量,即便您有着那些服务器的完全管理控制权限。

通过API访问LotusDomino

COM访问的替代方案之一就是使用LotusNotes/DominoCAPI。理论上,您可在Windows以外的操作系统上使用该解决方案。我们的建议是,只让具备大量C/C 编程经验的开发人员采纳这种方案(如果您有不使用COM接口或API的理由)。示例API解决方案提供的功能有限,基本上,您必须编写自己的C语言代码来完成大多数任务。

示例库提供了创建PHP扩展的出色例子。但其中仅包含源代码,您必须使用VisualC编译器和DominoCAPI工具包来编译代码。为方便起见,我们已将源代码编译成一个DLL文件,并将此文件包含于下载部分中。在php.ini配置文件中添加以下代码行即可激活Notes扩展:

extension=php5_notes.dll

以下代码示例展示了在获得所需DLL后使用此技术的方法。

<?php$dbpath="mailtest.nsf";$searchword="demo";//Performfulltextsearchinthespecifieddatabase.//TheresultisanarrayofNoteIDs$search=notes_search($dbpath,$searchword);If($search[0]==NULL){die("\nNoresultswerefoundforsearchword''$searchword''\n");}//Shownumberoffounddocumentsprint"\nFound".count($search)."resultsforsearchword''$searchword''\n";?>

图3展示了通过命令行运行API代码的输出结果。



图3.API代码输出


使用XML访问LotusDomino

使用XML与Domino数据库交互是最和谐的解决方案。无需作出任何特殊调整,也不需要在PHPWeb服务器上安装任何特殊工具,且在所有操作系统中均有效。我们认为,该解决方案在绝大多数情况下均为最佳方案。

本文的XML解决方案所使用的技术适用于多数配置。作为示例,您将创建一个标准Domino邮件数据库的PHP界面。在Domino环境中进行的惟一修改就是用来查看邮件文档字段的LotusScript代理。您将使用同一代理解析XML,以创建和发送邮件。

按以下步骤进行操作即可查看邮件数据库的Inbox文件夹:

  1. 询问用户的Notes用户名和口令。
  2. 使用所提供的用户名和口令向Domino数据库发送一条登录请求(参见图4)。


    图4.PHP示例应用程序的登录屏幕


  3. 从登录响应中获得会话cookie。(在向Domino数据库发出的后续请求中需要使用此cookie。)
  4. 使用ReadViewEntriesURL命令向Domino服务器请求Inbox文件夹的XML源。此命令返回XML格式的视图内容,而非HTML格式。您的会话cookie附于请求头上,以告知Domino您的身份。
  5. 在接收到的XML格式视图内容上,使用PHP的XML解析器查找文档和字段。
  6. XML解析器处理完整个文档后将构造HTML代码,并输出到浏览器。为使邮件消息显示为可单击的链接,请使用各文档节点的UNID属性。

要访问Domino数据库,您需要具备从Domino服务器中获取Web页面并解析XML的功能。为使演示应用程序能正常运行,还必须具备以下条件:

  • Domino服务器为版本6或更新版本,否则无法使用LotusScript的XML解析功能。(后文中将详细介绍此LotusScript代理。)
  • PHPWeb服务器允许外发Web请求。
  • 可通过Internet或内部网从PHPWeb服务器处访问Domino服务器。

注意:若您无法通过Internet访问Domino服务器,则可能需要调整防火墙配置,允许来自PHP服务器的数据流。





回页首


读取基于Web的Domino文件的PHP函数

PHP有一些检索基于Web的内容的函数。这些函数一开始就包含于PHP中,但管理员有时可能不会激活它们。以下函数可检索Web文件:

  • file_get_contents()。此函数易于使用,支持GET和POST请求类型。使用file_get_contents()函数,可将整个Web文件作为字符串而一次性地获得它。
  • fopen()。此方法成块读取Web文件。
  • file()。此方法读取整个Web文件,并逐行分隔文件内容。此方法是file_get_contents()与fopen()的一种交叉。
  • fsockopen()。此函数最有可能在宿主Web服务器上被激活。此函数与其他函数的主要差异在于,使用fsockopen()时,您必须自行创建整个Web请求,而不能只设置几个不同的参数。
  • CURL。ClientURLLibrary(CURL)具有最高级的功能性。使用CURL,您可以连接到使用多种不同协议的多种服务器。CURL目前支持HTTP、HTTPS、FTP、Gopher、Telnet、DICT、File和LDAP。它还支持代理、cookies及身份验证。遗憾的是,Web托管公司往往会禁用CURL。

注意:本文的示例应用程序仅使用file_get_contents()函数。

获得Domino会话cookie是此流程的重要部分,您可将相同的代码用于其他与Domino相关的应用程序中。例如,您可以使用STLinks检索cookie,以登录到IBMLotusSametime服务器。

通过向Domino服务器发送POST请求获取会话cookie。在该请求中,需要将您的用户名和口令包含在内。服务器的响应包括一个cookie,供您在后续向Domino服务器发送请求时使用。通过包含会话cookie,Domino服务器会将您的脚本视为最近登录过、现正访问数据库的实际人类用户。

之所以使用POST方法而不是GET方法,是因为GET方法的URL会被记录到Domino日志中,任何访问日志的用户都能看到您的用户名和口令——而且是明文。使用POST方法,用户名和口令不被作为URL的一部分,因此也不会显示在常规日志中。

您可在Set-Cookie响应头中找到Domino会话cookie。会话cookie名为DomAuthSessId或LtpaToken。当Domino服务器配置为单点登录(SSO)时使用LtpaToken作为名称。实际上,您不必在意cookie的名称,只需保存整个cookie字符串即可。

以下代码示例展示了如何检索cookie。

$req="username=john doe&password=john123";$opts=array("http"=>array("method"=>"POST","content"=>$req,"header"=>"Accept-language:en\r\n"."User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)\r\n"));$context=stream_context_create($opts);if(!($fp=fopen("http://server.com/maildb.nsf?login","r",false,$context))){die("CouldnotopenloginURL");}$meta=stream_get_meta_data($fp);for($j=0;isset($meta["wrapper_data"][$j]);$j ){if(strstr(strtolower($meta["wrapper_data"][$j]),''set-cookie'')){$cookie=substr($meta["wrapper_data"][$j],12);break;}}fclose($fp);$_SESSION["DominoCookie"]=$cookie;

在代码行$req="username=john doe&password=john123"中,您提供一个有效的用户名和口令,以登录到Domino服务器。随后设置附加选项,如POST方法类型和其他头。之后,将这些附加选项应用到外发HTTP请求:

fopen("http://server.com/mydb.nsf?login","r",false,$context)

使用stream_get_meta_data($fp)函数从Domino服务器返回的响应中获取所有头,遍历直至找到包含Set-Cookie字符串的头。随后,将cookie存储在会话变量中来保存:

$_SESSION["DominoCookie"]=$cookie

$_SESSION在您关闭Web浏览器之前一直保存cookie值。

现在,将cookie应用到您的下一个请求中,该请求从Domino邮件数据库中检索Inbox视图/文件夹。

$opts=array("http"=>array("method"=>"GET","header"=>"Accept-language:en\r\n".“User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)\r\n"."Cookie:".$_SESSION["DominoCookie"]."\r\n"));$context=stream_context_create($opts);$xml=file_get_contents("http://server.com/maildb.nsf/(\$Inbox)?ReadViewEntries",false,$context);

这次使用了GET方法而不是POST方法来下载Web页面。该方法在HTTP选项数组中的"method"=>"GET"代码行中指定。使用file_get_contents(URL,false,context)函数读取整个响应,而不仅仅是读取头。此操作的结果是一个XML长字符串,它包含Inbox视图中的所有列。通过以下代码将会话cookie附在头上:

"Cookie:".$_SESSION["DominoCookie"]."\r\n"

获取XML数据后,就可以在PHPXML解析器中处理这些数据了。接下来将为Inbox视图创建您自己的用户界面。





回页首


处理XML的PHP函数

与LotusScript和Java编程语言相同,在PHP中处理XML代码的方法有两种:SimpleAPIforXML(SAX)及DocumentObjectModel(DOM)。SAX是一种基于事件的编程模型,绝大多数PHPWeb服务器在默认情况下都包含并启用了SAX。Web服务器管理员必须激活DOM扩展。尽管DOM更易于编程,但在这些示例中,我们将使用SAX,以便最大化与大多数PHP配置的兼容性。

处理Domino视图的技术只需略加更改即可用于处理其他XML源,如RSSfeed(RSS提要)乃至Web服务。如下代码示例展示了包含一个文档的Inbox视图的XML源。

<?xmlversion="1.0"encoding="UTF-8"?><viewentriestoplevelentries="6"><viewentryposition="1"unid="38B16601EC8B42BAC12571440068335C"noteid="8FE"siblings="6"><entrydatacolumnnumber="0"name="$109"><text></text></entrydata><entrydatacolumnnumber="1"name="$86"><numberlist><number>0</number><number>0</number></numberlist></entrydata><entrydatacolumnnumber="2"name="$93"><text>DonaldDuck</text></entrydata><entrydatacolumnnumber="3"name="$102"><number>178</number></entrydata><entrydatacolumnnumber="4"name="$70"><datetimedst="true">20060402T205929,52 02</datetime></entrydata><entrydatacolumnnumber="5"name="$99"><datetimedst="true">20060402T205929,52 02</datetime></entrydata><entrydatacolumnnumber="6"name="$106"><number>823</number></entrydata><entrydatacolumnnumber="7"name="$97"><number>0</number></entrydata><entrydatacolumnnumber="8"name="$73"><text>seenMickey?</text></entrydata></viewentry></viewentries>

如您所见,XML源代码中的文档包含于<viewentry>标签中,列(字段)包含于<entrydata>标签中。文档的UniversalID作为<viewentry>节点的一项属性提供。

您只需要确定一种方法,编程查找那些标签之间的值来获得全部所需数据即可。听上去非常简单,实现起来也非常简单。首先,使用xml_parser_create函数启动XML解析器对象:

$xml_parser=xml_parser_create();

随后,设置负责处理XML元素开始和结束的回调函数。处理器通过xml_set_element_handler和xml_set_character_data_handler函数识别这些函数。各函数接受解析器句柄和回调函数的名称:

xml_set_element_handler($xml_parser,"startElement","endElement");
xml_set_character_data_handler($xml_parser,"textData");

您必须为PHP代码添加startElement、endElement和textData函数:

functionstartElement($parser,$name,$attributes){switch($name){case"VIEWENTRY":$main="VIEWENTRY";if($attributes["UNID"]!=""){$current_doc=$attributes["UNID"];$unids[$doc_counter]=$current_doc;}break;case"ENTRYDATA":$main="ENTRYDATA";if($attributes["COLUMNNUMBER"]!=""){$current_column=$attributes["COLUMNNUMBER"];}break;case"DATETIME":$main="DATETIME";break;default:break;}}functionendElement($parser,$name){if($name=="VIEWENTRY"){$doc_counter ;//increasedocumentcounterby1}$current_column="";}functiontextData($parser,$data){switch($main){case"ENTRYDATA":if(isset($doc_coll[$current_doc][$main])){$doc_coll[$current_doc][$main][$current_column].="$data";}else{$doc_coll[$current_doc][$main][$current_column]="$data";}break;case"DATETIME":if(isset($doc_coll[$current_doc][$main])){$doc_coll[$current_doc][$main].="$data";}else{$doc_coll[$current_doc][$main]="$data";}break;case"VIEWENTRY":break;}}

那么,让我们来看看它的工作原理。当XML解析器遍历XML源并发现开始了一个新元素时,它会触发指定为回调函数的startElement函数。在这里,新开始的这个元素名为<ENTRYDATA>。这样,您就知道当前所处理的元素是新列,因而可将$current_column变量设置为列编号。本例中的列表示字段:

case"ENTRYDATA":$main="ENTRYDATA";if($attributes["COLUMNNUMBER"]!=""){$current_column=$attributes["COLUMNNUMBER"];}break;

随后,解析器查找<ENTRYDATA>节点中的文本,将其发送给指定为回调函数的textData函数。此函数允许您使用<ENTRYDATA>节点的值填充数组:

switch($main){case"ENTRYDATA":if(isset($doc_coll[$current_doc][$main])){$doc_coll[$current_doc][$main][$current_column].="$data";}else{$doc_coll[$current_doc][$main][$current_column]="$data";}break;

使用XML源示例,$doc_coll[$current_doc][$main][$current_column]="$data"代码行为:

$doc_coll[“38B16601EC8B42BAC12571440068335C”][“ENTRYDATA”][“8”]="seenMickey?"

这意味着UniversalID为38B16601EC8B42BAC12571440068335C的文档的Inbox视图中的第8列为"seenMickey?",这恰好是邮件消息的主题。

XML解析器是“智能化”的,它知道若开始了一个元素,此元素必然会在某处终止。因此它会查找元素的结尾,并触发endElement函数(正是您指定为第二个回调函数的那个endElement函数)向您发出信号。由于不再需要列编号,故此函数将重置列编号。您还要检查是否必须增加文档计数器的值。

我们将$doc_counter变量作为存储UniversalID的数组的计数器。必须存储UniversalID,主要是为了向邮件文档添加链接。当您获知VIEWENTRY元素已终止时(也就是说接下来将出现一个新的UniversalID),最好将当前数组号加1,使$doc_coll和$unids数组保持原样:

if($name=="VIEWENTRY"){$doc_counter ;}$current_column="";

下载示例应用程序并在您自己的服务器上运行时,您所用版本的Domino邮件数据库的邮件视图内的列布局可能有所不同。如果出现这样的情况,则必须在PHP代码中调整列编号(docfunctions.php)。





回页首


示例PHP应用程序与LotusScript代理

本节介绍名为ProcessDocWebAction的Domino代理,在本文下载部分提供的示例应用程序中可找到此代理。ProcessDocWebAction以LotusScript编写,并使用DOM来解析进入的XML请求。此应用程序使用了全新的XML脚本类,因而无法在Domino5服务器上使用,但可在Domino6和Domino7服务器上使用。

此代理处理的请求是通过PHP示例应用程序启动的,可能为以下类型之一:

  • 创建并发送一个邮件消息
  • 保存一个现有邮件文档
  • 将一个新邮件文档保存为草稿
  • 请求关于用户文件位置的信息
  • 确定用户依然处于已登录状态的伪Ping请求

按以下步骤部署代理:

  1. 复制xmlagent.lss文件中的所有文本。
  2. 自选数据库,在其中创建新代理。
  3. 将代理的属性设置为“RunasWebuser”,将target设置为None。
  4. 将之前复制的代码粘贴到这个新代理中。
  5. 将代理保存为ProcessDocWebAction。
  6. 在PHP文件(dominomail.php)中,指向代理所在数据库的URL位置。

在PHP示例应用程序的创建过程中,我们的首要考虑事项之一就是确保此应用程序适用于所有标准邮件数据库,而无需修改设计。您可用此代理来处理用户邮件数据库之外的XML,可用同一代理为所有用户提供服务。

用户首次进行身份验证时,PHP应用程序首先检索会话cookie,随后要求此代理提供用户邮件文件的位置。代理知道代理调用者是谁,这是因为它是在设置了“RunasWebuser”属性的情况下运行的。在完成初始请求之后,用户邮件数据库的位置就会被保存下来,以便重用,一直保存到用户关闭Web浏览器或会话过期为止。

用户总是使用实际的Domino身份验证进行验证。用户不能访问那些使用Web浏览器客户机无法访问的资源,即便他(或她)能在Web服务器上修改PHP源代码。





回页首


结束语

如果您是一名Domino开发人员或管理员,并且您的Domino服务器不能通过Internet访问,您依然可以为用户提供一种访问存储于Domino数据库中的数据的方法,允许他们读写电子邮件消息。通过本文示例应用程序中介绍的XML技术,您可以轻而易举地在自己的PHP应用程序上实现Domino身份验证,根据DominoDirectory进行登录验证。

基于Web的XML解决方案未重写用户的访问权限,用户在每步操作中都要使用自己的凭证。这可确保用户无法访问未经授权的数据。为进一步增强安全性,您还可实现登录尝试失败的日志记录。






回页首


下载

大小
描述名字下载方法
SourcecodeofPHPapplicationphp_app_sample.zip10KBHTTP
LotusScriptagentusedforprocessingXMLxmlagent.zip2KBHTTP
CompiledversionofNotesAPIextensionphp_notes_dll.zip21KBHTTP

来源:IBM
友情链接
北极星工程招聘网北极星电气招聘网北极星火电招聘网北极星风电招聘网北极星水电招聘网北极星环保招聘网北极星光伏招聘网北极星节能招聘网招标信息分类电子资料百年建筑网PLC编程培训

广告直拨:   媒体合作/投稿:陈女士 13693626116

关于北极星 | 广告服务 | 会员服务 | 媒体报道 | 营销方案 | 成功案例 | 招聘服务 | 加入我们 | 网站地图 | 联系我们 | 排行

京ICP证080169号京ICP备09003304号-2京公网安备11010502034458号电子公告服务专项备案

网络文化经营许可证 [2019] 5229-579号广播电视节目制作经营许可证 (京) 字第13229号出版物经营许可证新出发京批字第直200384号人力资源服务许可证1101052014340号

Copyright © 2022 Bjx.com.cn All Rights Reserved. 北京火山动力网络技术有限公司 版权所有