- 論壇徽章:
- 0
|
本帖最后由 pi1ot 于 2012-06-05 12:33 編輯
發(fā)布一個(gè)比較老舊的Web開發(fā)C++類庫
代碼地址:
https://code.google.com/p/webapplib/
https://github.com/pi1ot/webapplib
簡(jiǎn)單說明:
WebAppLib是一系列主要用于類Unix操作系統(tǒng)環(huán)境下WEB開發(fā)的C++類庫。設(shè)計(jì)目的是通過提供使用簡(jiǎn)單方便、相對(duì)獨(dú)立的C++類和函數(shù)來簡(jiǎn)化CGI程序開發(fā)過程中的常見操作,提高開發(fā)效率。
背景介紹:
這個(gè)類庫已經(jīng)非常老舊了,是我03年到05年間開發(fā)維護(hù)的,05年之前曾應(yīng)用于多個(gè)新浪項(xiàng)目,包括當(dāng)時(shí)的論壇、聊天、用戶庫、CMS等,05年后隨著新浪前端應(yīng)用開發(fā)全面轉(zhuǎn)向PHP,逐漸沒人用了,現(xiàn)在大概只剩下少數(shù)歷史比較悠久的項(xiàng)目還在繼續(xù)使用吧。一開始是作為本人學(xué)習(xí)C++的練手項(xiàng)目開始的,后來用的人逐漸增多,其間陸陸續(xù)續(xù)升級(jí)了七八個(gè)版本,應(yīng)該說大部分代碼的穩(wěn)定性已經(jīng)經(jīng)歷過了考驗(yàn),考慮到一點(diǎn)點(diǎn)個(gè)人感情因素,現(xiàn)在簡(jiǎn)單整理一下發(fā)布出來,沒有任何使用上的限制,大概也不會(huì)有后續(xù)更新。這次發(fā)布之前做了一下整理,重構(gòu)了一些類庫和函數(shù)的命名,刪除了很多已經(jīng)證明并不需要的冗余接口。
建議:
現(xiàn)在Web開發(fā)的主流顯然不是C++,不過如果你想學(xué)習(xí)或者了解一下CGI開發(fā)的細(xì)節(jié),可以作為參考,或者如果你已經(jīng)有一個(gè)以C++為主體代碼的項(xiàng)目,需要一點(diǎn)簡(jiǎn)單的Web包裝,又不想學(xué)習(xí)或者引入一門新的腳本語言,可以試試看這個(gè)WebAppLib
其他:
webapp::String 的實(shí)現(xiàn),受當(dāng)時(shí)知識(shí)水平的限制,為了能沿用 std::string 的全部接口,是 public 繼承自std::string的,現(xiàn)在看來顯然不是一個(gè)說得過去的方案,只是在那幾年的使用場(chǎng)景中,似乎也沒有發(fā)現(xiàn)有不穩(wěn)定的情況,所以現(xiàn)在懶得去修改了,各位自行決定是否使用吧。
附說明,摘自《Effective C++》
條款14: 確定基類有虛析構(gòu)函數(shù):當(dāng)通過基類的指針去刪除派生類的對(duì)象,而基類又沒有虛析構(gòu)函數(shù)時(shí),結(jié)果將是不可確定的。
類庫和函數(shù)列表:
String | 繼承并兼容與std::string的字符串類,增加了開發(fā)中常用的字符串處理函數(shù) | Cgi | 支持文件上傳的CGI參數(shù)讀取類 | Cookie | HTTP Cookie設(shè)置與讀取類 | MysqlClient | MySQL數(shù)據(jù)庫連接類,MySQL連接處理C函數(shù)接口的C++封裝 | MysqlData | MySQL查詢結(jié)果數(shù)據(jù)集類,MySQL查詢結(jié)果數(shù)據(jù)提取C函數(shù)接口的C++封裝 | Template | 支持在模板中嵌入條件跳轉(zhuǎn)、循環(huán)輸出腳本的 HTML 模板類 | HttpClient | HTTP/1.1通信協(xié)議客戶端類 | DateTime | 日期時(shí)間運(yùn)算、格式化輸出類 | TextFile | 固定分隔符文本文件讀取解析類 | ConfigFile | INI格式配置文件解析類 | FileSystem | 文件系統(tǒng)操作函數(shù)庫 | Encode | 字符串編碼解碼函數(shù)庫 | Utility | 系統(tǒng)調(diào)用與工具函數(shù)庫 |
簡(jiǎn)單范例:- /// \file example.cpp
- /// 代碼示例文件,演示一個(gè)簡(jiǎn)單CGI流程
- #include <iostream>
- #include "webapplib.h"
- using namespace webapp;
- int main() {
- /***************************************************************************
- 演示完整的CGI應(yīng)用程序流程,模擬WEB查詢動(dòng)作
- 1、讀取CGI參數(shù)和Cookie數(shù)據(jù)(String、Cgi、Cookie)
- 2、使用讀取到的參數(shù)調(diào)用權(quán)限檢查接口(ConfigFile、HttpClient)
- 3、使用讀取到的參數(shù)查詢數(shù)據(jù)庫(MysqlClient)
- 4、使用日志文件記錄用戶請(qǐng)求(FileSystem、Utility、Encode)
- 5、更新用戶端Cookie(Cookie、DateTime)
- 6、顯示HTML頁面(Template)
- ***************************************************************************/
- ////////////////////////////////////////////////////////////////////////////
- // 1、讀取CGI參數(shù)和Cookie數(shù)據(jù)(Cgi、Cookie)
-
- Cgi cgi;
- Cookie cookie;
- String username = cgi["username"];
- String usercookie = cookie["usercookie"];
-
- /*提示 webapp::Cgi在讀不到CGI環(huán)境變量時(shí)會(huì)運(yùn)行在調(diào)試模式,提示輸入CGI參數(shù)值*/
-
- ////////////////////////////////////////////////////////////////////////////
- // 2、使用讀取到的參數(shù)調(diào)用權(quán)限檢查接口(ConfigFile、HttpClient)
-
- ConfigFile conf( "example.conf" );
- String check_interface = conf["check_interface"];
-
- cout << "---------------------------------------------------------" << endl;
- cout << "check user privilege from:" << check_interface << endl;
-
- HttpClient www;
- www.request( check_interface + "?username=" + username );
- if ( www.done() && www.content()=="CHECK_PASS" ) {
- cout << "check pass" << endl;
- } else {
- cout << "check fail" << endl;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // 3、使用讀取到的參數(shù)查詢數(shù)據(jù)庫(MysqlClient)
- String value;
- #ifndef _WEBAPPLIB_NOMYSQL
- String sql;
- sql.sprintf( "SELECT value FROM table WHERE user='%s'", escape_sql(username).c_str() );
-
- MysqlClient mysqlclient;
- MysqlData mysqldata;
- mysqlclient.connect( "example.mysql.com", "user", "pwd", "database" );
- if ( mysqlclient.is_connected() ) {
- if ( mysqlclient.query(sql,mysqldata) ) {
- value = mysqldata( 0, "value" );
- } else {
- cout << mysqlclient.error() << endl;
- }
- }
- #endif //_WEBAPPLIB_NOMYSQL
- ////////////////////////////////////////////////////////////////////////////
- // 4、使用日志文件記錄用戶請(qǐng)求(FileSystem、Utility、Encode)
-
- String log_path = "/tmp/";
- String log_file = log_path + "/logfile.txt";
- if ( !file_exist(log_path) || !is_dir(log_path) ) {
- make_dir( log_path );
- }
- file_logger( log_file, "username:%s", username.c_str() );
- file_logger( log_file, "usermd5:%s", md5_encode(username).c_str() );
-
- cout << "---------------------------------------------------------" << endl;
- String file_content;
- file_content.load_file( log_file );
- cout << file_content << endl;
- ////////////////////////////////////////////////////////////////////////////
- // 5、更新用戶端Cookie(Cookie、DateTime)
-
- DateTime now;
- DateTime expires = now + ( TIME_ONE_DAY*3 ); // Cookie有效期為三天
- cookie.set_cookie( "username", username, expires.gmt_datetime() );
-
- ////////////////////////////////////////////////////////////////////////////
- // 6、顯示HTML頁面(Template)
-
- Template page("example.tmpl");
- page.set( "username", username );
- page.set( "value", value );
-
- // 顯示查詢結(jié)果
- cout << "---------------------------------------------------------" << endl;
- http_head();
- page.print();
- }
復(fù)制代碼 代碼中使用的配置文件和模板文件
example.conf- # comments
- check_interface = http://example.com/check
復(fù)制代碼 example.tmpl- welcome {{$username}}!
- you query result is here:
- {{$value}}
復(fù)制代碼 |
|