CopyrightIBMCorporation2006TrademarksBuildingPHP-basedUIsforIBMLotusDominoPage1of14BuildingPHP-basedUIsforIBMLotusDominoAndreiKouvchinnikovMay09,2006DiscoverhowyoucaninteractwithLotusDominodatabasesfromWebapplicationscreatedinthePHPprogramminglanguage.
LearnhowtoaccessDominoapplicationsfromPHPpagesusingaCOMobject,theLotusNotesAPI,andXML.
Inthisarticle,youlearnhowtointeractwithIBMLotusDominodatabasesfromWebapplicationscreatedwiththePHPprogramminglanguage.
YoualsolearnhowtoaccessDominoapplicationsfromPHPpagesusingaCOMobject,theIBMLotusNotesapplicationprogramminginterface(API),andXML.
CodeexamplesforeachmethodareincludedintheDownloadssection.
TheXMLmethodalsohasadownloadableexampleapplicationwithasimpleWebinterfacetoanIBMLotusDominomaildatabase(seefigure1).
Figure1.
ExampleofaPHPuserinterfacetoamaildatabasePHPisapowerfulembeddedscriptinglanguage.
ItisfreetouseandpopularfordevelopingdynamicWebapplications.
PHPcodeisn'tcompiled;rather,it'sinterpretedatruntime.
MuchofitssyntaxisborrowedfromtheC,Java,andPerlprogramminglanguages.
YoucanaddPHPasaCommonGatewayInterface(CGI)enginetomostWebservers.
ItevenworksintheMicrosoftWindowsandLinuxoperatingsystems.
Inaddition,morethan50percentofWebhostingcompanieshavePHP-enabledservers.
WithsuchwidespreadPHPtechnology,yousimplycannotaffordtoremainunfamiliarwithit.
WorkingwithPHPYouincludePHPcodeinWebpageswiththehelpofspecialtags.
AllPHPcodebeginswiththetag:developerWorksibm.
com/developerWorks/BuildingPHP-basedUIsforIBMLotusDominoPage2of14TheWebserverinterpretsthissimpleexampleandtranslatesittofollowingHTMLoutput:HelloWorld!
PHPWebpagescaninteractwithDominodatabasesinseveralways.
ThechoiceofintegrationmethoddependsonwhichoperatingsystemyouusetorunPHP,thesecurityrestrictionsinplacebetweenPHPandyourDominoservers,andwhatyouareallowedtoinstallonthePHPserver.
Themethodsdescribedinthisarticleare:COMobjectsTheNotesAPIXMLthroughtheWebRunningPHPcodeofflineAlthoughPHPisprimarilyintendedtorunonaWebserverandisnotforstandaloneapplications,youcanrunitfromthecommandlineasashellscriptingtoolsimilartoMicrosoftVisualBasicScriptingEdition(VBScript).
ThisfeaturecanbeusefulforofflinetestingbeforeputtingthefilesontheWebserver.
AccessingLotusDominoThreemethodsareavailableforaccessingaDominodatabase:throughCOMobjects,throughtheNotesAPI,andthroughXML.
AccessLotusDominousingDominoCOMobjectsTheeasiestandmostfast-forwardmethodofaccessinginformationstoredinDominodatabasesisthroughDominoCOMobjects.
UsingCOMfromPHPisn'tmuchmoredifficultthandoingsofromLotusScript.
Thefollowingcodeexampleshowshowtoprintthefieldvaluesofallthedocumentsinaview.
Initialize();//ShowthenameofthecurrentNotesuserprint"Currentuser:".
$session->CommonUserName.
"\n\n";//Getdatabasehandle$db=$session->getDatabase("","mailtest.
nsf");//Getviewhandleusingpreviouslyreceiveddatabasehandle.
//Notethatthereservedcharacterintheviewnamemustbe\-escaped$view=$db->getView("(\$Drafts)");ibm.
com/developerWorks/developerWorksBuildingPHP-basedUIsforIBMLotusDominoPage3of14//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;>Figure2showstheoutputfromrunningthisCOMobjectfromthecommandline.
Figure2.
ResultofrunningCOMobjectcodeatacommandpromptUsingCOMobjectsiseasy,buttherearesomedisadvantagesthatmakeCOMratherlimited.
ThemaindisadvantageisthatyoumusthaveLotusNotesclientsoftwareinstalledonthePHPserver.
Ifyou'reusingaWebhostingcompanyforyourPHPapplications,thereisn'tmuchyoucandotoconvincethehostingcompanytoinstallaNotesclientjustforpurposesofyourPHPWebsite.
IfyouhaveyourownPHPserverorperhapsPHPandDominoserversonthesamecomputer,youshouldhavenoproblemssettingupCOMaccesstotheDominoserver.
AnotherissuethatlimitsCOMuseisthatCOMobjectsaresupportedonlyontheWindowsplatform.
ConsideringthatmostPHPserversrunontheLinuxplatform,thisrequirementconsiderablyreducesthenumberofavailableserversthatcanhostyourCOMsolution,evenifyouhavefulladministrativecontrolforthoseservers.
AccessLotusDominothroughanAPIAnalternativetoCOMaccessistousetheLotusNotes/DominoCAPI.
Theoretically,youcanusethissolutiononoperatingsystemsotherthanWindows.
WerecommendthatonlydeveloperswhohavealotofexperienceinC/C++programminguseit(ifyouhaveareasonfornotusingaCOMinterfaceorXML).
ThefunctionalityprovidedinthesampleAPIsolutionislimited,andyoumustbasicallywriteyourowncodeintheCprogramminglanguagetoaccomplishmosttasks.
developerWorksibm.
com/developerWorks/BuildingPHP-basedUIsforIBMLotusDominoPage4of14ThesamplelibraryprovidesagoodexampleforcreatingPHPextensions.
Itcomesonlyassourcecode,andyoumusthavetheVisualCcompilerandtheDominoCAPItoolkittocompilethecode.
Foryourconvenience,we'vecompiledthesourcecodeintoaDLLfileandincludeditintheDownloadssection.
YoucanactivatetheNotesextensionbyaddingthefollowinglinetothephp.
iniconfigurationfile:extension=php5_notes.
dllThefollowingcodeexampleshowshowtousethistechniqueafteryouproducetherequiredDLL.
Figure3showstheoutputfromrunningtheAPIcodefromthecommandline.
Figure3.
OutputoftheAPIcodeAccessLotusDominousingXMLUsingXMLtointeractwithDominodatabasesisthemostcompatiblesolution.
Itdoesn'trequireanyspecialadjustmentsorinstallationsonthePHPWebserver,anditworksonalloperatingsystems.
Inouropinion,it'sthebestapproachinmostcases.
IntheXMLsolutioninthisarticle,youusetechniquesthataremostlikelytoworkinthemajorityofconfigurations.
Asanexample,youcreateaPHPinterfacetoastandardDominomaildatabase.
TheonlymodificationmadeintheDominoenvironmentisaLotusScriptagentusedtoviewfieldsfromthemaildocuments.
YouusethesameagenttoparsetheXMLandtocreateandsendmail.
ibm.
com/developerWorks/developerWorksBuildingPHP-basedUIsforIBMLotusDominoPage5of14ToviewtheInboxfolderfromthemaildatabase,completethesesteps:1.
AsktheuserforhisorherNotesusernameandpassword.
2.
SendaloginrequesttotheDominodatabaseusingtheusernameandpasswordprovided(seefigure4).
Figure4.
LoginscreeninthePHPsampleapplication3.
Fromtheloginresponse,getasessioncookie.
(YouneedthiscookieforsubsequentrequeststotheDominodatabase.
)4.
MakearequesttotheDominoserverfortheXMLsourceoftheInboxfolder,usingtheReadViewEntriesURLcommand.
ThiscommandreturnsthecontentoftheviewpresentedinXMLforminsteadofreturningHTML.
YoutellDominoyouridentitybyappendingasessioncookietotherequestheaders.
5.
OnthereceivedXML-formattedviewcontent,usePHP'sXMLparsertofinddocumentsandfields.
6.
WhentheXMLparserhasprocessedthewholedocument,constructtheHTMLcode,andprinttothebrowser.
Tomakeamailmessageaclickablelink,usetheUNIDattributeofeachdocumentnode.
ToaccessDominodatabases,youneedfunctionalitybothtogetaWebpagefromtheDominoserverandtoparsetheXML.
Youmustalsoassumethefollowingforpurposesofthedemoapplication:TheDominoserverisversion6orlater;otherwise,youcan'tuseLotusScript'sXML-parsingfunctionality.
(ThisLotusScriptagentisdiscussedinmoredetaillater.
)ThePHPWebserverallowsoutgoingWebrequests.
TheDominoserverisaccessiblefromthePHPWebserverbyeithertheInternetoranintranet.
Note:Ifyoucan'taccesstheDominoserverfromtheInternet,youmayneedtoadjustyourfirewallconfigurationtoallowtrafficfromthePHPserver.
PHPfunctionsforreadingWeb-basedDominofilesPHPhasseveralfunctionsforretrievingWeb-basedcontent.
ThesefunctionswereincludedinPHPfromtheinception,butadministratorshaven'talwaysactivatedthem.
ThefollowingfunctionscanretrieveafilefromtheWeb:developerWorksibm.
com/developerWorks/BuildingPHP-basedUIsforIBMLotusDominoPage6of14file_get_contents().
Thisfunctioniseasytouse,anditsupportsboththeGETandPOSTrequesttypes.
Withfile_get_contents(),yougetthewholeWebfileatonceasastring.
fopen().
ThismethodreadstheWebfileinchunks.
file().
ThismethodreadsthewholeWebfileandseparatesthefile'scontentlinebyline.
It'sakindofcross-overbetweenfile_get_contents()andfopen().
fsockopen().
ThisfunctionhasthegreatestchanceofbeingactivatedonthehostingWebserver.
Themaindifferencebetweenthisandotherfunctionsisthatwithfsockopen(),youmustcreatethewholeWebrequestbyyourselfinsteadofsettingdifferentparameters.
CURL.
TheClientURLLibrary(CURL)hasthemostadvancedfunctionality.
UsingCURL,youcanconnecttoandcommunicatewithmanydifferenttypesofserverswithmanydifferenttypesofprotocols.
CURLcurrentlysupportsHTTP,HTTPS,FTP,Gopher,Telnet,DICT,File,andLDAP.
Italsosupportsproxies,cookies,andauthentication.
Unfortunately,CURLisoftendisabledbyWebhostingcompanies.
Note:Intheexampleapplicationinthisarticle,youusethefile_get_contents()functionexclusively.
ObtainingtheDominosessioncookieisanimportantpartoftheprocess,andyoucanusethesamecodeinotherDomino-relatedapplications.
Forexample,youcanretrieveacookieforloggingintotheIBMLotusSametimeserverusingSTLinks.
YougetthesessioncookiebysendingaPOSTrequesttotheDominoserver.
Inthatrequest,youincludeyourusernameandpassword.
TheresponsefromtheservercontainsacookiethatyouuseinsubsequentrequeststotheDominoserver.
Byincludingasessioncookie,theDominoserverthinksthatyourscriptisactuallyahumanuserwhorecentlyloggedinandisnowaccessingthedatabase.
YouusethePOSTmethodinsteadoftheGETmethodbecauseURLsoftheGETmethodareloggedintheDominolog,andanyonewhoaccessesthelogcanseetheusernameandpasswordinplaintext.
WiththePOSTmethod,usernamesandpasswordsaren'tpartoftheURL;therefore,theyaren'tvisibleinregularlogs.
YoucanfindtheDominosessioncookieintheSet-Cookieresponseheader.
ThesessioncookieiscalledeitherDomAuthSessIdorLtpaToken.
YouusethenameLtpaTokenwhentheDominoserverisconfiguredforsinglesign-on(SSO).
Youdon'tactuallycarewhatthecookienameis;yousimplysavethewholecookiestring.
Thefollowingcodeexampleshowshowtoretrievethecookie.
$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.
nsflogin","r",false,$context))){ibm.
com/developerWorks/developerWorksBuildingPHP-basedUIsforIBMLotusDominoPage7of14die("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;Inthecodeline$req="username=john+doe&password=john123",youprovideavalidusernameandpasswordtobeusedforloggingintotheDominoserver.
Then,yousetupadditionaloptions,suchasthePOSTmethodtypeandotherheaders.
Afterthat,youapplyyouradditionaloptionstotheoutgoingHTTPrequest:fopen("http://server.
com/mydb.
nsflogin","r",false,$context)FromtheresponseyoureceivefromtheDominoserver,yougetalltheheadersusingthestream_get_meta_data($fp)functionandloopthroughtheheadersuntilyoufindtheonethatcontainstheSet-Cookiestring.
Afterthat,yousavethecookiebystoringitinsideasessionvariable:$_SESSION["DominoCookie"]=$cookie$_SESSIONholdsthecookievalueuntilyouclosetheWebbrowser.
Now,youapplythecookietoyournextrequest,whichretrievestheInboxview/folderfromaDominomaildatabase.
$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);Thistime,youusetheGETmethodtodownloadaWebpageinsteadofthePOSTmethod.
Thismethodisspecifiedwiththe'method'=>"GET"lineintheHTTPoptionsarray.
Insteadofreadingonlyheaders,youreadthewholeresponseusingthefile_get_contents(URL,false,context)function.
TheresultofthisoperationisalongXMLstringcontainingallthecolumnsfromtheInboxview.
Youappendthesessioncookietotheheaderwith:"Cookie:".
$_SESSION["DominoCookie"].
"\r\n"developerWorksibm.
com/developerWorks/BuildingPHP-basedUIsforIBMLotusDominoPage8of14AfteryoureceivetheXMLdata,youcanprocessitinthePHPXMLparser.
Then,youcreateyourownuserinterfacefortheInboxview.
PHPfunctionsforprocessingXMLInPHP,justasintheLotusScriptandJavaprogramminglanguages,therearetwowaysofprocessingXMLcode:theSimpleAPIforXML(SAX)andtheDocumentObjectModel(DOM).
SAXisanevent-basedprogrammingmodel,andit'sincludedandenabledbydefaultinmostPHPWebservers.
TheDOMextensionmustbeactivatedbytheWebserver'sadministrator.
AlthoughDOMismucheasiertoprogramwith,intheseexamples,youusetheSAXparserbecauseyouwanttoachievemaximumcompatibilitywithmostPHPconfigurations.
TechniquessimilartoprocessingDominoviewscan--withsmallmodifications--beusedforprocessingotherXMLsources,suchasRSSfeedsandevenWebservices.
ThefollowingcodeexampleshowstheXMLsourceoftheInboxviewcontainingonedocument.
00DonaldDuck17820060402T205929,52+0220060402T205929,52+028230seenMickeyAsyoucansee,documentsintheXMLsourcearepresentedwiththetag,andcolumns(fields)arepresentedwithtags.
Thedocument'sUniversalIDisavailableasanattributeofthenode.
ibm.
com/developerWorks/developerWorksBuildingPHP-basedUIsforIBMLotusDominoPage9of14Allyouneedtodoisdetermineawaytoprogrammaticallyfindthevaluesbetweenthosetagstogetallthedatayouneed.
Soundseasy,anditiseasytoaccomplish,too.
First,initiatetheXMLparserobjectusingthexml_parser_createfunction:$xml_parser=xml_parser_create();Then,setcallbackfunctions,whichareresponsibleforhandlingthestartandendofXMLelements.
Thesefunctionsareidentifiedtotheprocessorthroughtheuseofthexml_set_element_handlerandxml_set_character_data_handlerfunctions.
Eachfunctionacceptstheparserhandleandthenamesofthecallbackfunctions:xml_set_element_handler($xml_parser,"startElement","endElement");xml_set_character_data_handler($xml_parser,"textData");YoumustaddthestartElement,endElement,andtextDatafunctionstoyourPHPcode: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";developerWorksibm.
com/developerWorks/BuildingPHP-basedUIsforIBMLotusDominoPage10of14}break;case"VIEWENTRY":break;}}So,let'sseehowitworks.
WhentheXMLparsergoesthroughtheXMLsourceandfindsthatanewelementisstarted,ittriggersthestartElementfunction,whichyouspecifiedasacallbackfunction.
Inthiscase,suchastartingelementnameis.
Nowyouknowthatthecurrentelementbeingprocessedisanewcolumn,soyoucansetthe$current_columnvariabletothenumberofthecolumn.
Inthiscase,columnsrepresentfields:case"ENTRYDATA":$main="ENTRYDATA";if($attributes["COLUMNNUMBER"]!
=""){$current_column=$attributes["COLUMNNUMBER"];}break;Afterthat,theparserfindsthetextinsidethenodeandsendsittothetextDatafunctionthatyouspecifiedasacallbackfunction.
Thepurposeofthisfunctionistoallowyoutopopulateanarraywithvaluesinsidethenode: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;UsingtheXMLsourceexample,the$doc_coll[$current_doc][$main][$current_column]="$data"codelineis:$doc_coll["38B16601EC8B42BAC12571440068335C"]["ENTRYDATA"]["8"]="seenMickey"ThismeansthattheeighthcolumnintheInboxviewforthedocumentwithUniversalID38B16601EC8B42BAC12571440068335Cis"seenMickey",whichhappenstobethesubjectofthemailmessage.
TheXMLparseris"smart"andknowsthatifanelementisstarted,itmustbefinishedsomewhere.
So,whenitfindstheendoftheelement,itsignalsyoubytriggeringtheendElementfunction(that'sright:thesamefunctionnameyouspecifiedasyoursecondcallbackfunction).
Inthatfunction,youresetthecolumnnumberbecauseitisn'tneededanymore.
Youalsocheckwhetherthedocumentcountermustbeincreased.
Youusethe$doc_countervariableasacounterforthearraythatstoresUniversalIDs.
YoumuststoreUniversalIDsmainlyforthepurposeofaddinglinkstothemaildocuments.
WhenyouknowthattheVIEWENTRYelementhasended,itmeansthatanewUniversalIDiscomingnext,andibm.
com/developerWorks/developerWorksBuildingPHP-basedUIsforIBMLotusDominoPage11of14youhadbetterincreasethecurrentarraynumberby1tokeepthe$doc_colland$unidsarraysintact:if($name=="VIEWENTRY"){$doc_counter++;}$current_column="";Ifyoudownloadthesampleapplicationandrunitonyourownserver,yourversionoftheDominomaildatabasemayhavedifferentplacementofcolumnsinthemailviews.
Ifso,youmustadjustthecolumnnumbersinthePHPcode(docfunctions.
php).
ThesamplePHPapplicationandtheLotusScriptagentThissectionisaboutaDominoagentcalledProcessDocWebAction,whichisincludedaspartofthesampleapplicationyoucandownloadwiththisarticle.
TheagentisprogrammedinLotusScriptandusestheDOMtoparseincomingXMLrequests.
BecauseitusesthenewXMLscriptclasses,youcanusetheapplicationonDominorelease6andrelease7servers,butnotonrelease5servers.
TherequeststhatthisagenthandlesareinitiatedfromthesamplePHPapplicationandcanbeofthefollowingtypes:CreateandsendamailmessageSaveanexistingmaildocumentSaveanewmaildocumentasdraftRequestinformationaboutthelocationofauser'sfileAdummyPingrequesttomakesurethatauserisstillloggedinTodeploytheagent,completethesesteps:1.
Copyallthetextfromthexmlagent.
lssfile.
2.
Createanewagentinadatabaseofyourchoice.
3.
Setthepropertiesoftheagentto"RunasWebuser"andthetargettoNone.
4.
Pastethecopiedcodeintothisnewagent.
5.
NametheagentProcessDocWebAction,andthensaveit.
6.
InthePHPfile(dominomail.
php),pointtotheURLlocationofthedatabaseinwhichtheagentresides.
OneofourmainprioritiesduringthecreationofthePHPsampleapplicationwastoensurethatitworkedonallstandardmaildatabaseswithoutdesignmodifications.
That'swhythisapplicationdoesn'trequireanychangestothemaildatabasedesign.
YoucanplacetheagentforprocessingtheXMLoutsidetheuser'smaildatabase,andthesameagentcanbeusedforservingallusers.
Whenauserauthenticatesforthefirsttime,thePHPapplication,afterretrievingthesessioncookie,asksthisagentforthelocationoftheuser'smailfile.
Theagentknowswhotheinvokeroftheagentisbecausetheagentisrunningwiththe"RunasWebuser"propertyactivated.
AfterdeveloperWorksibm.
com/developerWorks/BuildingPHP-basedUIsforIBMLotusDominoPage12of14thisinitialrequest,thepathtotheuser'smaildatabaseissavedforre-useuntiltheuserclosestheWebbrowserorthesessionexpires.
AuserisalwaysauthenticatedusingrealDominoauthentication.
TheusercannotaccessanyresourcesheorshecannotaccessusingaWebbrowserclient,eveniftheusercouldmodifythePHPsourcecodeontheWebserver.
ConclusionIfyou'reaDominodeveloperoradministratorandyourDominoserverisn'taccessiblefromtheInternet,youcanstillgiveusersawaytoaccessdatastoredinDominodatabasesandallowthemtoreadandwriteemailmessages.
UsingtheXMLtechniquesdescribedinthisarticleandappliedinthesampleapplication,youcaneasilyimplementDominoauthenticationinyourownPHPapplicationstoverifyloginsagainsttheDominoDirectory.
Thereisnooverridingofauser'saccessrightsintheWeb-basedXMLsolution;theuserisusinghisorherowncredentialsineachoperation.
Thisensuresthatuserscannotaccessunauthorizeddata.
Tofurtherincreasesecurity,youcanimplementloggingoffailedloginattempts.
ibm.
com/developerWorks/developerWorksBuildingPHP-basedUIsforIBMLotusDominoPage13of14DownloadableresourcesDescriptionNameSizeSourcecodeofPHPapplicationphp_app_sample.
zip10KBLotusScriptagentusedforprocessingXMLxmlagent.
zip2KBCompiledversionofNotesAPIextensionphp_notes_dll.
zip21KBdeveloperWorksibm.
com/developerWorks/BuildingPHP-basedUIsforIBMLotusDominoPage14of14RelatedtopicsdeveloperWorksarticle,"ReadingandwritingtheXMLDOMwithPHP"PHPWebsitePHP:XMLParserFunctionsTryalivedemoofthePHPinterfacedemotoaDominomaildatabase.
DownloadatrialversionofLotusNotes7fromdeveloperWorks.
DownloadatrialversionofLotusDomino7fromdeveloperWorks.
DownloadthesourcecodeoftheNotesAPIextensionforPHPfromthePHPExtensionCommunityLibrary(PECL)site.
CopyrightIBMCorporation2006(www.
ibm.
com/legal/copytrade.
shtml)Trademarks(www.
ibm.
com/developerworks/ibm/trademarks/)
使用此源码可以生成QQ自动跳转到浏览器的短链接,无视QQ报毒,任意网址均可生成。新版特色:全新界面,网站背景图采用Bing随机壁纸支持生成多种短链接兼容电脑和手机页面生成网址记录功能,域名黑名单功能网站后台可管理数据安装说明:由于此版本增加了记录和黑名单功能,所以用到了数据库。安装方法为修改config.php里面的数据库信息,导入install.sql到数据库。...
小白云是一家国人自营的企业IDC,主营国内外VPS,致力于让每一个用户都能轻松、快速、经济地享受高端的服务,成立于2019年,拥有国内大带宽高防御的特点,专注于DDoS/CC等攻击的防护;海外线路精选纯CN2线路,以确保用户体验的首选线路,商家线上多名客服一对一解决处理用户的问题,提供7*24无人全自动化服务。商家承诺绝不超开,以用户体验为中心为用提供服务,一直坚持主打以产品质量用户体验性以及高效...
rfchost怎么样?rfchost是一家开办了近六年的国人主机商,一般能挺过三年的国人商家,还是值得入手的,商家主要销售VPS,机房有美国洛杉矶/堪萨斯、中国香港,三年前本站分享过他家堪萨斯机房的套餐。目前rfchost商家的洛杉矶机房还是非常不错的,采用CN2优化线路,电信双程CN2 GIA,联通去程CN2 GIA,回程AS4837,移动走自己的直连线路,目前季付套餐还是比较划算的,有需要的可...
file_get_contents为你推荐
支持ipad孩子applecolumnios5eacceleratoreaccelerator.shm_size设置多少合适呢?win10关闭445端口win10怎么关闭445的最新相关信息itunes备份itunes就是备份不了怎么办啊127.0.0.1为什么输入127.0.0.1无法打开页面win7telnet怎样开启Windows7系统中的Telnet服务ms17-010win1038度古贝春珍藏10价格?联通版iphone4s怎么区分iphone4s电信版和联通版
服务器配置技术网 stablehost softbank官网 sub-process win8.1企业版升级win10 免费博客空间 512m内存 免费全能空间 中国电信测网速 qq对话框 服务器监测 免费私人服务器 彩虹云 阿里云官方网站 smtp服务器地址 英雄联盟台服官网 全能空间 服务器防火墙 阿里云邮箱个人版 阿里云个人邮箱 更多