|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2006-06-06, 08:15 AM | #1 (permalink) |
榮譽會員
|
軟體 - PHPWind 源碼解析 第一彈
PHPWind 源碼解析 第一彈
前陣子心血來潮 想去看看PHPWIND的源碼 結果到處都找不到參考 只能自己動手了 真是一看不知道看了嚇一跳啊 本只打算看一個global.php文件的 結果為了看懂這一個文件牽扯出了58個文件需要檢視 暈死 花了差不多半個星期的業餘時間 結合php手冊的說明,以及自己對源碼的分析理解 總算在今天晚上全部看完 以在源文件中新增註釋的方法寫入源碼分析 下面只貼出其中幾個重要文件的源碼分析吧 其餘文件請自行下載附件檢視 基本上看懂這些文件,可以對phpwind論壇的執行機制有個大概的瞭解 做人要厚道哦,轉貼請註明 claudedb 原創 註: 1、本源碼分析針對PHPWind 4.3.2 060428更新版做出 2、除部分文件外,多數文件均可直接使用,不影響論壇的正常執行 3、歡迎大家指出文中的錯誤,畢竟我不是PHPWind的作者,肯定會有理解上的偏差 global.php CODE: <?php /** * * Copyright (c) 2003-06 PHPWind.net. All rights reserved. * Support : http://www.phpwind.net * This software is the proprietary information of PHPWind.com. * */ //此文件內容為全局變數和公用函數 //定義只有執行錯誤和語法編譯錯誤才會顯示錯誤訊息 error_reporting(E_ERROR | E_PARSE); //設置php.ini中 magic_quotes_runtime 選項值為0 //若 magic_quotes_runtime 打開時,所有外部引入的資料庫資料或者文件等等都會自動轉為含有反斜線溢出字元的資料。 //0表示關閉此功能 set_magic_quotes_runtime(0); //microtime() 當前 Unix 時間戳以及微秒數。本函數僅在支持 gettimeofday() 系統調用的操作系統下可用。 //如果調用時不帶可選參數,本函數以 "msec sec" 的格式返回一個字元串,其中 sec 是自 Unix 紀元(0:00:00 January 1, 1970 GMT)起到現在的秒數,msec 是微秒部分。字元串的兩部分都是以秒為單位返回的。 //用$t_array變數記錄microtime()函數產生的msec和sec,此時$t_array代表數組 $t_array = explode(' ',microtime()); //$P_S_T記錄當前時間秒數 $P_S_T = $t_array[0] + $t_array[1]; //判斷__FILE__是否為空,返回路徑值,並定義為D_P和R_P //其中__FILE__文件的完整絕對路徑和文件名 //D_P和R_P的區別在於,當論壇使用二級目錄設置時,D_P用於分論壇,R_P用於記錄總論壇目錄的絕對路徑 //具體參考PHPWind論壇關於二級目錄方面的說明 //在沒有使用這方面設置的時候這兩個值相等 define('D_P',__FILE__ ? getdirname(__FILE__).'/' : './'); define('R_P',D_P); //銷毀以下變數 unset($_ENV,$HTTP_ENV_VARS,$_REQUEST,$HTTP_POST_VARS,$HTTP_GET_VARS,$HTTP_POST_FILES,$HTTP_COOKIE_VARS); //get_magic_quotes_gpc函數取得 PHP 環境配置的變數 magic_quotes_gpc (GPC, Get/Post/Cookie) 值。返回 0 表示關閉本功能;返回 1 表示本功能打開。當 magic_quotes_gpc 打開時,所有的 ' (單引號), " (雙引號), \ (反斜線) and 空字元會自動轉為含有反斜線的溢出字元。 //在magic_quotes_gpc功能關閉的情況下,對$_POST、$_GET、$_COOKIE中的特殊字元轉義處理 if(!get_magic_quotes_gpc()){ //$_POST 經由 HTTP POST 方法提交至腳本的變數。 Add_S($_POST); //$_GET 經由 URL 請求提交至腳本的變數。 Add_S($_GET); //$_FILES 通過 HTTP POST 方法傳遞的已上傳文件檔案專案組成的數組。 Add_S($_FILES); //$_COOKIE 經由 HTTP Cookies 方法提交至腳本的變數。 Add_S($_COOKIE); } //$_SERVER 變數由 web 服務器設定或者直接與當前腳本的執行環境相關聯。 //如果服務器變數中存在HTTP_X_FORWARDED_FOR,則從中取得客戶端ip,如果沒有則到HTTP_CLIENT_IP中取,都沒有則到REMOTE_ADDR中取 //'HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR'是代理的IP //這些IP頭消息未必能夠取得到(因為不同的瀏覽器不同的網路設備,可能發不同的IP頭消息).所以PHP就嘗試把每個IP頭消息判斷一下,若有,則取其中的一個. //$c_agentip記錄是否為代理ip if($_SERVER['HTTP_X_FORWARDED_FOR']){ $onlineip = $_SERVER['HTTP_X_FORWARDED_FOR']; $c_agentip=1; }elseif($_SERVER['HTTP_CLIENT_IP']){ $onlineip = $_SERVER['HTTP_CLIENT_IP']; $c_agentip=1; }else{ $onlineip = $_SERVER['REMOTE_ADDR']; $c_agentip=0; } //str_replace 用指定的字元串替換在被搜索的字元串中找到的字元串; //第一個,要搜索的字元串,第二個為替換為的字元串,第三個被搜索的字元串 //取得客戶端ip值 $onlineip = substrs(str_replace("\n",'',$onlineip),16); //返回自從 Unix 紀元(格林威治時間 1970 年 1 月 1 日 00:00:00)到當前時間的秒數。 $timestamp= time(); //require_once require_once() 語句在腳本執行期間包含並執行指定文件。此行為和 require() 語句類似, //唯一區別是如果該文件中的代碼已經被包含了,則不會再次包含.應該用於在腳本執行期間同一個文件有可能被 //包含超過一次的情況下,想確保它只被包含一次以避免函數重定義,變數重新賦值等問題。 //包含require/defend.php文件,如果其中有重複包含,略過 require_once(R_P.'require/defend.php'); //根據時區設置$db_cvtime取得正確的時間$timestamp $db_cvtime != 0 && $timestamp += $db_cvtime*60; //如果論壇執行在DEBUG模式下 if($db_debug){ //定義顯示所有錯誤除了執行NOTICE錯誤 error_reporting(E_ALL ^ E_NOTICE); } //PHPWind論壇版本變數 $wind_version = "4.3.2"; //線上列表大小值 $db_olsize = 96; //靜態htm快取記憶體目錄名(註:此處變數$htm dir應去掉中間的空格,被論壇屏蔽了) $htm dir = 'htm_data'; //'PHP_SELF' 當前正在執行腳本的文件名,與 document root 相關 //'SCRIPT_NAME' 當前執行腳本的絕對路徑名,注: 如果腳本在 CLI 中被執行,作為相對路徑,例如 //file.php 或 ../file.php,$_SERVER['SCRIPT_FILENAME'] 將包含用戶指定的相對路徑。 //'QUERY_STRING' 查詢(query)的字元串(URL 中第一個問號 ? 之後的內容)。 //如果PHP_SELF(當前正在執行腳本的文件名)為空,則設置其為SCRIPT_NAME(包含當前腳本的路徑) !$_SERVER['PHP_SELF'] && $_SERVER['PHP_SELF']=$_SERVER['SCRIPT_NAME']; //取得請求url完整的路徑儲存在$REQUEST_URI變數中 $REQUEST_URI = $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']; //判斷當前執行文件名中是否包含靜態目錄$db_dir,如果包含,則 if(strpos($_SERVER['PHP_SELF'],$db_dir)!==false){ //strpos 查找字元串第一次出現的位置,第一個為被查找的字元串,第二個為要查找的字元串。返回值為0,或 //者被查找的字元第一次出現的數位位置的值; //取到靜態目錄前 $tmp=substr($_SERVER['PHP_SELF'],0,strpos($_SERVER['PHP_SELF'],$db_dir)); }else{ //取全部 $tmp=$_SERVER['PHP_SELF']; } //HTTP_HOST-當前請求的 Host: 頭訊息的內容 //設置論壇地址 $db_bbsurl="http://$_SERVER[HTTP_HOST]".substr($tmp,0,strrpos($tmp,'/')); //(int) 強制類型轉換為整型 //定義整型變數$fid用於記錄板塊id $fid = (int)$fid; //定義整型變數$tid用於記錄帖子id $tid = (int)$tid; //初始化附件儲存目錄$attachname及js腳本路徑$js_path $attachname = $js_path = ''; //包含data/bbscache/dbset.php文件,如果其中有重複包含,略過 require_once(D_P.'data/bbscache/dbset.php'); //ob_start("ob_gzhandler");是一種壓縮技術 //ob_start();僅僅啟動緩衝 並沒有壓縮輸出 //ob_start 用來 打開輸出緩衝區。 當緩衝區啟動時,所有來自PHP程式的非文件頭訊息均不會發送,而是儲存在內部緩衝區。為了輸出緩衝區的內容,可以使用ob_end_flush()或者使用ob_end_clean()來輸出緩衝區的內容。 //是否允許GZIP 壓縮輸出,允許使用ob_gzhandler壓縮技術,否則只啟動緩衝 $db_obstart == 1 ? ob_start('ob_gzhandler') : ob_start(); //如果使用跨台固定圖片鏈,則圖片路徑為$db_http值,否則使用$picpath圖片儲存目錄 $imgpath = $db_http != 'N' ? $db_http : $picpath; //如果使用遠端附件連接設置,則附件路徑為$db_attachurl,否則使用$attachname附件儲存目錄 $attachpath = $db_attachurl != 'N' ? $db_attachurl : $attachname; //本機圖片路徑 $imgdir = R_P.$picpath; //本機附件路徑 $attachdir = R_P.$attachname; //如果D_P和R_P不相等並且使用了跨台固定圖片鏈,即使用了二級目錄功能 if(D_P != R_P && $db_http != 'N'){ //取總站論壇地址 $R_url=substr($db_http,-1)=='/' ? substr($db_http,0,-1) : $db_http; $R_url=substr($R_url,0,strrpos($R_url,'/')); }else{ //總站論壇地址即全局變數$db_bbsurl中的論壇地址值 $R_url=$db_bbsurl; } //如果cookie中上次訪問變數lastvisit值是否為空 if(GetCookie('lastvisit')){ //取cookie中的上次訪問變數lastvisit值,以"\t"分割並分別賦於$c_oltime,$lastvisit,$lastpath //$c_oltime-用戶線上時間,$lastvisit-上次訪問時間,$lastpath-上次訪問路徑 list($c_oltime,$lastvisit,$lastpath) = explode("\t",GetCookie('lastvisit')); //判斷現在和上次訪問之間的時間差是否小於論壇設定的線上用戶時限,如果小於,則用戶此次線上時間累加相應時間數值 ($onbbstime=$timestamp-$lastvisit)<$db_onlinetime && $c_oltime+=$onbbstime; }else{ $lastvisit=$lastpath=''; $c_oltime=0; } //取線上偏移cookie(線上列表文件中的偏移量) $ol_offset = GetCookie('ol_offset'); //取風格cookie $skinco = GetCookie('skinco'); //若重新整理預防時間不等於0 if ($db_refreshtime!=0){ //$REQUEST_URI 訪問此網頁面所需的 URI。 //如果$REQUEST_URI與上次最後訪問的路徑相同,且與上次訪問的時間差小於論壇設定的重新整理預防時間 if($REQUEST_URI==$lastpath && $onbbstime<$db_refreshtime){ //如果Cookie中沒有winduser即用戶的記錄,設置$groupid為guest即當前用戶歸於遊客組 !GetCookie('winduser') && $groupid='guest'; //創始人賬號設置為TRUE $manager=TRUE; //如果cookie中沒有風格變數,則風格設置為論壇的預定風格 $skin = $skinco ? $skinco : $db_defaultstyle; //轉網頁面顯示語言文件中refresh_limit對應鍵值的提示訊息 Showmsg("refresh_limit"); } } //引用 在 PHP 中引用意味著用不同的名字訪問同一個變數內容。這並不像 C 的指針,替代的是,引用是符號 //表別名。注意在 PHP 中,變數名和變數內容是不一樣的,因此同樣的內容可以有不同的名字。PHP 的引用允 //許用兩個變數來指向同一個內容。意思是,當這樣做時: $a =& $b;這意味著 $a 和 $b 指向了 //同一個變數。注: $a 和 $b 在這裡是完全相同的,這並不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向 //了同一個地方。注: 如果具有引用的數組被拷貝,其值不會解除引用。對於數組傳值給函數也是如此。 $H_url =& $db_wwwurl; $B_url =& $db_bbsurl; //包含data/sql_config.php文件,如果其中有重複包含,略過 require_once(D_P.'data/sql_config.php'); //如果論壇關閉 if ($db_bbsifopen==0){ //從cookie中取得AdminUser(管理人員)變數值,並對其進行解碼操作後,以"\t"分割存入數組$CK中 $CK = explode("\t",StrCode(GetCookie('AdminUser'),'DECODE')); //如果上次訪問時間$CK[0]與現在相差超過1800s即30分鐘 //或者賬號$CK[1]不是創始人賬號$manager //或者不符合安全檢測 if ($timestamp-$CK[0]>1800 || $CK[1]!=$manager || !SafeCheck($CK,PwdCode($manager_pwd))){ //取得風格值 $skin = $skinco ? $skinco : $db_defaultstyle; //設置用戶組為空 $groupid = ''; //轉網頁面顯示$db_whybbsclose訊息即論壇關閉的原因 Showmsg($db_whybbsclose); } } //gmdate -- 格式化一個 GMT/UTC 日期/時間 //date -- 格式化一個本機時間/日期,返回將整數 timestamp 按照給定的格式字串而產生的 //字元串。如果沒有給出時間戳則使用本機當前時間。換句話說,timestamp 是可選擇的,預定值為 time()。注: //有效的時間戳典型範圍是格林威治時間 1901 年 12 月 13 日 20:45:54 到 2038 年 1 月 19 日 //03:14:07。(此範圍符合 32 位有符號整數的最小值和最大值)。不過在 PHP 5.1 之前此範圍在某些系統 //(如 Windows)中限制為從 1970 年 1 月 1 日到 2038 年 1 月 19 日。 //格式字串可以識別以下 format 參數的字元串 format 字元 說明 返回值例子 //日 --- --- //d 月份中的第幾天,有前導零的 2 位數位 01 到 31 //D 星期中的第幾天,文本表示,3 個字母 Mon 到 Sun //j 月份中的第幾天,沒有前導零 1 到 31 //l(「L」的小寫字母) 星期幾,完整的文本格式 Sunday 到 Saturday //N ISO-8601 格式數位表示的星期中的第幾天(PHP 5.1.0 新加) 1(表示星期一)到 7(表示星期天) //S 每月天數後面的英文後綴,2 個字元 st,nd,rd 或者 th。可以和 j 一起用 //w 星期中的第幾天,數位表示 0(表示星期天)到 6(表示星期六) //z 年份中的第幾天 0 到 366 //星期 --- --- //W ISO-8601 格式年份中的第幾周,每週從星期一開始(PHP 4.1.0 新加的) //月 --- --- //F 月份,完整的文本格式,例如 January 或者 March January 到 December //m 數位表示的月份,有前導零 01 到 12 //M 三個字母縮寫表示的月份 Jan 到 Dec //n 數位表示的月份,沒有前導零 1 到 12 //t 給定月份所應有的天數 28 到 31 //年 --- --- //L 是否為閏年 如果是閏年為 1,否則為 0 //o ISO-8601 格式年份數位。這和 Y 的值相同,只除了如果 ISO 的星期數(W)屬於前一年或下一年,則用 //那一年。(PHP 5.1.0 新加) Examples: 1999 or 2003 //Y 4 位數位完整表示的年份 例如:1999 或 2003 //y 2 位數位表示的年份 例如:99 或 03 //時間 --- --- //a 小寫的上午和下午值 am 或 pm //A 大寫的上午和下午值 AM 或 PM //B Swatch Internet 標準時 000 到 999 //g 小時,12 小時格式,沒有前導零 1 到 12 //G 小時,24 小時格式,沒有前導零 0 到 23 //h 小時,12 小時格式,有前導零 01 到 12 //H 小時,24 小時格式,有前導零 00 到 23 //i 有前導零的分鐘數 00 到 59 //s 秒數,有前導零 00 到 59 //時區 --- --- //e 時區標識(PHP 5.1.0 新加) 例如:UTC,GMT,Atlantic/Azores //I 是否為夏令時 如果是夏令時為 1,否則為 0 //O 與格林威治時間相差的小時數 例如:+0200 //T 本機所在的時區 例如:EST,MDT(在 Windows 下為完整文本格式,例如「Eastern //Standard Time」,中文版會顯示「中國標準時間」)。 //Z 時差偏移量的秒數。UTC 西邊的時區偏移量總是負的,UTC 東邊的時區偏移量總是正的。 -43200 到 43200 //完整的日期/時間 --- --- //c ISO 8601 格式的日期(PHP 5 新加) 2004-02-12T15:19:21+00:00 //r RFC 822 格式的日期 例如:Thu, 21 Dec 2000 16:01:07 +0200 //U 從 Unix 紀元(January 1 1970 00:00:00 GMT)開始至今的秒數 參見 time() //格式字串中不能被識別的字元將原樣顯示。Z 格式在使用 gmdate() 時總是返回 0。 //取當前預定時區時間的24小時時間值,賦於$t['hours'] $t = array('hours'=>gmdate('G',$timestamp+$db_timedf*3600)); //floor -- 捨去法取整 //今天的起始時間 $tdtime = (floor($timestamp/3600)-$t['hours'])*3600; //是否需要更新線上情況標記 $runfc = 'N'; //如果上次訪問時間和當前時間的時間差大於論壇設置的線上用戶時限 //或者板塊$fid不為空且不等於cookie中的上次訪問板塊id //或者上次訪問板塊id的cookie存在且$wind_in(論壇動作)為hm(論壇首頁) if($timestamp-$lastvisit>$db_onlinetime || ($fid && $fid != GetCookie('lastfid')) || (GetCookie('lastfid') && $wind_in=='hm')){ //設置cookie中上次訪問板塊id Cookie('lastfid',$fid); //設置$runfc為Y $runfc='Y'; //包含data/userglobal.php文件,如果其中有重複包含,略過 require_once(R_P.'require/userglobal.php'); } //包含require/db_'.$database.'.php文件,如果其中有重複包含,略過(此處為db_mysql.php) require_once(R_P.'require/db_'.$database.'.php'); //創建資料庫連接 $db = new DB($dbhost, $dbuser, $dbpw, $dbname, $pconnect); //銷毀$dbhost,$dbuser,$dbpw,$dbname,$pconnect,$manager_pwd變數 unset($dbhost,$dbuser,$dbpw,$dbname,$pconnect,$manager_pwd); //從cookie中取得winduser訊息解碼用"\t"分割後存入$winduid,$windpwd list($winduid,$windpwd)=explode("\t",StrCode(GetCookie('winduser'),'DECODE')); //若用戶登入id存在且密碼長度大等於16 if($winduid && strlen($windpwd)>=16){ //定義$winddb為用戶訊息數組 $winddb = User_info(); //用戶id $winduid = $winddb['uid']; //用戶組id $groupid = $winddb['groupid']; //用戶實際威望為資料庫中威望值/10取整 $userrvrc = (int)($winddb['rvrc']/10); //用戶名 $windid = $winddb['username']; //用戶時間顯示格式 $_datefm = $winddb['datefm']; //用戶時區設置 $_timedf = $winddb['timedf']; //用戶皮膚 $skin = $winddb['style'] ? $winddb['style'] : $db_defaultstyle; //用戶線上ip $winddb['onlineip']=substr($winddb['onlineip'],0,strpos($winddb['onlineip'],'|')); //如果用戶組id為-1則設置用戶組id為用戶的會員組id $groupid=='-1' && $groupid=$winddb['memberid']; //若用戶開啟簽名顯示功能 且 //((用戶開始使用簽名時間為空 且 簽名顯示一天需要交易幣個數不為空 且當前用戶組屬於需要購買簽名顯示的用戶組 且 用戶擁有的交易幣數大於簽名顯示一天需要交易幣個數) 或者 //(用戶開始使用簽名時間不為空 且 用戶開始使用簽名時間不等於今日開始時間)) if($winddb['showsign'] && (!$winddb['starttime'] && $db_signmoney && strpos($db_signgroup,",$groupid,") !== false && $winddb['currency'] > $db_signmoney || $winddb['starttime'] && $winddb['starttime'] != $tdtime)){ //包含require/Signfunc.php文件,如果其中有重複包含,略過 require_once(R_P.'require/Signfunc.php'); //對用交易幣購買簽名做相應的操作 Signfunc($winddb['showsign'],$winddb['starttime'],$winddb['currency']); } } else{ //若登入id不存在 //設置風格為論壇預定風格 $skin = $db_defaultstyle; //用戶組為遊客組 $groupid = 'guest'; //銷毀$winddb unset($winddb); //設置用戶名,用戶id,用戶時間顯示方式,用戶時區設置 $windid=$winduid=$_datefm=$_timedf=''; } //取最優先的風格 $_GET['skinco'] && $skinco=$_GET['skinco']; $_POST['skinco'] && $skinco=$_POST['skinco']; //如果風格存在,且D_P."data/style/$skinco.php"文件存在,風格變數中不包含".." if($skinco && file_exists(D_P."data/style/$skinco.php") && strpos($skinco,'..')===false){ //設置風格變數 $skin=$skinco; //設置風格cookie Cookie('skinco',$skinco); } //對處在ip封禁列表中的ip禁止登入 Ipban(); //設置上次訪問cookie,包括此次線上時間、當前時間、請求網頁面 Cookie('lastvisit',$c_oltime."\t".$timestamp."\t".$REQUEST_URI); //如果當前用戶組不是遊客 if($groupid!='guest'){ //且相應組別配置文件存在 if(file_exists(D_P."data/groupdb/group_$groupid.php")){ //包含相應組別配置文件,如有重複,略過 require_once(D_P."data/groupdb/group_$groupid.php"); }else{ //否則載入預定組別配置文件 require_once(D_P."data/groupdb/group_1.php"); } } else{ //載入遊客組配置文件 require_once(D_P."data/groupdb/group_2.php"); } //HTTP_REFERER 鏈接到當前網頁面的前一網頁面的 URL 地址。不是所有的用戶代理(瀏覽器)都會設置這個變數,而且有的還可以手工修改 HTTP_REFERER。因此,這個變數不總是真實正確的。 //HTTP_HOST 當前請求的 Host: 頭訊息的內容。 //如果允許用戶使用宣傳代碼且用戶名非空且傳入的參數$u為數位 //或者傳入的參數$a存在且長度不超過16且HTTP_REFERER中不含HTTP_HOST if($db_ads && !$windid && (is_numeric($u) || ($a && strlen($a)<16)) && strpos($_SERVER['HTTP_REFERER'],$_SERVER['HTTP_HOST'])===false){ //設置用戶宣傳cookie userads Cookie('userads',"$u\t$a"); } //如果SCR常量沒有定義 if(!defined('SCR')){ //定義其為other define('SCR','other'); } //標記網頁面類型 $SCR = SCR; $header_ad=$footer_ad=''; //如果網頁面類型不是帖子網頁面 if(SCR != 'read'){ //取得廣告訊息數組 $advertdb = AdvertInit(SCR,$fid); //is_array -- 檢測變數是否是數組 if(is_array($advertdb['header'])){ //array_rand -- 從數組中隨機取出一個或多個單元 //取得頁首廣告 $header_ad = $advertdb['header'][array_rand($advertdb['header'])]['code']; } if(is_array($advertdb['footer'])){ //取得頁尾廣告 $footer_ad = $advertdb['footer'][array_rand($advertdb['footer'])]['code']; } } //返回頁首導航 類似 霏凡論壇 -> 口- 超級灌水 function headguide($guidename=array(),$guide=''){ global $fid,$jinhua; if(is_array($guidename)){ foreach($guidename as $key=>$value){ if($key){ $headguide.=$value ? " -> <a href='$value'>$key</a>" : " -> $key"; } } } else{ $headguide.=" -> ".$guidename; } //返回頁首導航字元串 return $headguide; } //網頁面跳轉 function refreshto($URL,$content,$statime=1){ global $db_ifjump; //替換url中的特殊字元= $URL=str_replace('=','=',$URL); //如果開啟自動跳轉且多少秒後抓向$statime大於0 if($db_ifjump && $statime>0){ //清空緩衝 ob_end_clean(); //是否允許GZIP 壓縮輸出,允許使用ob_gzhandler壓縮技術,否則只啟動緩衝 global $tplpath,$fid,$imgpath,$db_obstart,$db_bbsname,$skin,$B_url; $index_name =& $db_bbsname; $index_url =& $B_url; $db_obstart==1 ? ob_start('ob_gzhandler') : ob_start(); //確定引用風格 if(file_exists(D_P."data/style/$skin.php") && strpos($skin,'..')===false){ include_once(D_P."data/style/$skin.php"); }else{ include_once(D_P."data/style/wind.php"); } //解出全局變數數組,如果有衝突不覆蓋 @extract($GLOBALS, EXTR_SKIP); //包含對應風格目錄下的lang_refreshto.php語言文件,如果其中有重複包含,略過 require_once GetLang('refreshto'); $lang[$content] && $content=$lang[$content]; //包含對應風格目錄下的refreshto.htm文件 @require PrintEot('refreshto'); //退出 exit; } else{ ObHeader($URL); } } //網頁面直接轉向 function ObHeader($URL){ global $db_obstart,$db_bbsurl,$db_htmifopen; //strtolower-小寫處理字元串 //如果開啟靜態目錄部署功能且url中不是http開頭 if($db_htmifopen && strtolower(substr($URL,0,4))!='http'){ $URL="$db_bbsurl/$URL"; } //網頁面直接轉向 if($db_obstart){ //header -- 發送一個原始 HTTP 標頭 header("Location: $URL");exit; }else{ ob_start(); echo "<meta http-equiv='refresh' content='0;url=$URL'>"; exit; } } //轉向顯示提示訊息的網頁面顯示提示訊息 function Showmsg($msg_info,$dejump=0){ //extract -- 從數組中將變數匯入到當前的符號表 //extract() 檢查每個鍵名看是否可以作為一個合法的變數名,同時也檢查和符號表中已有的變數名的衝突。對待非法/數位和衝突的鍵名的方法將根據 extract_type 參數決定。可以是以下值之一: //EXTR_OVERWRITE(如果有衝突,覆蓋已有的變數) //EXTR_SKIP(如果有衝突,不覆蓋已有的變數) //EXTR_PREFIX_SAME(如果有衝突,在變數名前加上前綴 prefix) //EXTR_PREFIX_ALL(給所有變數名加上前綴 prefix) //EXTR_PREFIX_INVALID(僅在非法/數位的變數名前加上前綴 prefix) //EXTR_IF_EXISTS(僅在當前符號表中已有同名變數時,覆蓋它們的值。其它的都不處理。可以用在已經定義了一組合法的變數,然後要從一個數組例如 $_REQUEST 中提取值覆蓋這些變數的場合。) //EXTR_PREFIX_IF_EXISTS(僅在當前符號表中已有同名變數時,建立附加了前綴的變數名,其它的都不處理) //EXTR_REFS(將變數作為引用提取。這有力地表明了匯入的變數仍然引用了 var_array 參數的值。可以單獨使用這個標誌或者在 extract_type 中用 OR 與其它任何標誌結合使用) //如果沒有指定 extract_type,則被假定為 EXTR_OVERWRITE。 //extract() 返回成功匯入到符號表中的變數數目。 //$GLOBALS由所有已定義全局變數組成的數組。變數名就是該數組的索引。 //將全局變數匯入當前符號表 @extract($GLOBALS, EXTR_SKIP); //在函數中聲明了全局變數,任何變數的所有引用變數都會指向到全局變數。包括修改 //聲明全局變數,風格圖片文件路徑$stylepath,表格寬度$tablewidth,小表格寬度$mtablewidth,風格模板路徑$tplpath,$runfc global $stylepath,$tablewidth,$mtablewidth,$tplpath,$runfc; $runfc=''; //檢查SIMPLE常量是否定義,如果定義過 if(defined('SIMPLE')){ //<base>是一個鏈接基準標記,用以改變網頁面中所有鏈接標記的參數預定值。 echo "<base href=\"$db_bbsurl/\">"; } //包含require/header.php文件,如果其中有重複包含,略過 require_once(R_P.'require/header.php'); //包含對應風格目錄下的lang_msg.php語言文件,如果其中有重複包含,略過 require_once GetLang('msg'); //如果相應的語言文件中對應鍵值存在,則設置$msg_info為對應值 $lang[$msg_info] && $msg_info=$lang[$msg_info]; //包含對應風格目錄下的showmsg.htm文件 require_once PrintEot('showmsg'); exit; } //返回參數指定的文件相應風格語言文件路徑 function GetLang($lang,$EXT="php"){ //聲明全局變數風格模板路徑 global $tplpath; //路徑為…… $path=R_P."template/$tplpath/lang_$lang.$EXT"; //如果該風格下模板指定的文件不存在,則路徑為預定的wind風格下的對應文件 !file_exists($path) && $path=R_P."template/wind/lang_$lang.$EXT"; return $path; } //返回參數指定的文件相應風格模板路徑 function PrintEot($template,$EXT="htm"){ //Copyright (c) 2003-06 PHPWind //聲明全局變數風格模板路徑 global $tplpath; //如果參數為空,則設置參數值為N if(!$template) $template=N; //路徑為…… $path=R_P."template/$tplpath/$template.$EXT"; //如果該風格下模板指定的文件不存在,則路徑為預定的wind風格下的對應文件 !file_exists($path) && $path=R_P."template/wind/$template.$EXT"; return $path; } //設置相關cookie function Cookie($ck_Var,$ck_Value,$ck_Time = 'F'){ //聲明全局變數COOKIE有效目錄$db_ckpath,COOKIE有效域名$db_ckdomain,$timestamp global $db_ckpath,$db_ckdomain,$timestamp; //如果設置有效的cookie時間參數為F則,cookie有效時間設置為31536000s即1年 //否則如果傳入的cookie參數值為空並且有效時間參數為0則設置cookie有效時間為31536000s即1年前,也就是無效 //如果都不是則設置時間為傳入的cookie有效時間參數值 $ck_Time = $ck_Time == 'F' ? $timestamp + 31536000 : ($ck_Value == '' && $ck_Time == 0 ? $timestamp - 31536000 : $ck_Time); //SERVER_PORT-服務器所使用的連接阜。預定為「80」。如果使用 SSL 安全連接,則這個值為用戶設置的 HTTP 連接阜。 //判斷是否使用安全連接 $S = $_SERVER['SERVER_PORT'] == '443' ? 1:0; //如果COOKIE有效目錄為空則設置其為根目錄 !$db_ckpath && $db_ckpath = '/'; //setcookie -- 發送一個 cookie 訊息 //參數說明:Cookie 的名字,Cookie 的值,Cookie 過期的時間(這是個 Unix 時間戳,即從 Unix 紀元開始的秒數),Cookie 在服務器端的有效路徑,該 cookie 有效的域名,指明 cookie 是否僅通過安全的 HTTPS 連接傳送(當設成 TRUE 時,cookie 僅在安全的連接中被設置,預定值為 FALSE) setCookie($ck_Var,$ck_Value,$ck_Time,$db_ckpath,$db_ckdomain,$S); } //取cookie中的某變數值 function GetCookie($Var){ //_COOKIE 通過 HTTP cookies 傳遞的變數組成的數組。是自動全局變數。 return $_COOKIE[$Var]; } //對處在ip封禁列表中的ip禁止登入 function Ipban(){ //聲明全局變數IP封禁列表$db_ipban,客戶端ip$onlineip,圖片目錄$imgpath,風格圖片文件路徑$stylepath global $db_ipban,$onlineip,$imgpath,$stylepath; //如果ip封禁列表不為空 if($db_ipban){ //以","分割 $baniparray=explode(",",$db_ipban); foreach($baniparray as $banip){ //ip為空繼續下個循環 if(!$banip)continue; //去掉變數中的空格 $banip=trim($banip); //如果客戶端ip在被封禁列表中 if(strpos(','.$onlineip.'.',','.$banip.'.')!==false){ //轉網頁面顯示語言文件中ip_ban對應鍵值的提示訊息 Showmsg('ip_ban'); } } } } //刪除文件 function P_unlink($filename){ //判斷是否$filename是否包含..,包含則退出顯示Forbidden strpos($filename,'..')!==false && exit('Forbidden'); //unlink -- 刪除文件 @unlink($filename); } //讀取文件內容 function readover($filename,$method="rb"){ //由於strpos函數返回是整數值,所以使用!==(不全等)符號判斷是否$filename是否包含..,包含則退出顯示Forbidden strpos($filename,'..')!==false && exit('Forbidden'); //fopen -- 打開文件或者 URL, //mode 說明 //'r' 只讀方式打開,將文件指針指向文件頭。 //'r+' 讀寫方式打開,將文件指針指向文件頭。 //'w' 寫入方式打開,將文件指針指向文件頭並將文件大小截為零。如果文件不存在則嘗試創建之。 //'w+' 讀寫方式打開,將文件指針指向文件頭並將文件大小截為零。如果文件不存在則嘗試創建之。 //'a' 寫入方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創建之。 //'a+' 讀寫方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創建之。 //'x' 創建並以寫入方式打開,將文件指針指向文件頭。如果文件已存在,則 fopen() 調用失敗並返回 FALSE, //並產生一條 E_WARNING 級別的錯誤訊息。如果文件不存在則嘗試創建之。這和給 底層的 open(2) 系統調 //用指定 O_EXCL|O_CREAT 標記是等價的。此選項被 PHP 4.3.2 以及以後的版本所支持,僅能用於本機文 //件。 //'x+' 創建並以讀寫方式打開,將文件指針指向文件頭。如果文件已存在,則 fopen() 調用失敗並返回 //FALSE,並產生一條 E_WARNING 級別的錯誤訊息。如果文件不存在則嘗試創建之。這和給 底層的 open //(2) 系統調用指定 O_EXCL|O_CREAT 標記是等價的。此選項被 PHP 4.3.2 以及以後的版本所支持,僅能用 //於本機文件。 //@為錯誤運算符。當將其放置在一個 PHP 表達式之前,該表達式可能產生的任何錯誤訊息都被忽略掉。 //以讀方式打開文件,並將返回的資源(resource)儲存在$handle變數中 if($handle=@fopen($filename,$method)){ //flock -- 輕便的咨詢文件鎖定 //flock() 操作的 handle 必須是一個已經打開的文件指針。operation 可以是以下值之一:LOCK_SH取得共享鎖定、LOCK_EX取得獨佔鎖定、LOCK_UN釋放鎖定、LOCK_NB不希望 flock() 在鎖定時堵塞 flock($handle,LOCK_SH); //filesize返回文件字節數 //fread() 從文件指針 handle 讀取最多 length 個字節(這裡為全部),返回類型為string $filedata=@fread($handle,filesize($filename)); //fclose -- 關閉一個已打開的文件指針 fclose($handle); } //返回文件內容 return $filedata; } //寫入文件 function writeover($filename,$data,$method="rb+",$iflock=1,$check=1,$chmod=1){ //Copyright (c) 2003-06 PHPWind //判斷是否$filename是否包含..,包含則退出顯示Forbidden $check && strpos($filename,'..')!==false && exit('Forbidden'); //touch -- 設定文件的訪問和修改時間 touch($filename); //以讀寫方式打開文件,並將返回的資源(resource)儲存在$handle變數中 $handle=fopen($filename,$method); if($iflock){ flock($handle,LOCK_EX); } //fwrite -- 寫入文件(可安全用於二進制文件) fwrite($handle,$data); //ftruncate -- 將文件截斷到給定的長度 if($method=="rb+") ftruncate($handle,strlen($data)); fclose($handle); //chmod -- 改變文件模式 //mode 參數包含三個八進制數按順序分別指定了所有者、所有者所在的組以及所有人的訪問限制。每一部分都可以通過加入所需的權限來計算出所要的權限。數位 1 表示使文件可執行,數位 2 表示使文件可寫,數位 4 表示使文件可讀。 $chmod && @chmod($filename,0777); } //打開文件,返回文件數組 function openfile($filename){ //讀取文件內容 $filedata=readover($filename); //做相應替換 $filedata=str_replace("\n","\n<:wind:>",$filedata); //以"<:wind:>"分割,相當於每行一個數組元素 $filedb=explode("<:wind:>",$filedata); //count -- 計算數組中的單元數目或對像中的內容個數,返回 var 中的單元數目,通常是一個 array,任何其它 //類型都只有一個單元。對於對象,如果安裝了 SPL,可以通過實現 Countable 接頭來調用 count()。該接頭 //只有一個方法 count(),此方法返回 count() 函數的返回值。如果 var 不是數組類型或者實現了Countable //接頭的對象,將返回 1,有一個例外,如果 var 是 NULL 則結果是 0。注: 可選擇的 mode 參數自 PHP //4.2.0 起可用。如果可選擇的 mode 參數設為 COUNT_RECURSIVE(或 1),count() 將遞歸地對數組計 //數。對計算多維數組的所有單元尤其有用。mode 的預定值是 0。count() 識別不了無限遞歸。count() 對沒 //有初始化的變數返回 0,但對於空的數組也會返回 0。用 isset() 來測試變數是否已經初始化。 $count=count($filedb); //如果數組最後一個元素為空或者為"\r",銷毀此元素 if($filedb[$count-1]==''||$filedb[$count-1]=="\r"){unset($filedb[$count-1]);} //empty -- 檢查一個變數是否為空,如果 var 是非空或非零的值,則 empty() 返回 FALSE。換句話說, //""、0、"0"、NULL、FALSE、array()、var $var; 以及沒有任何內容的對象都將被認為是空的,如果 var //為空,則返回 TRUE。除了當變數沒有置值時不產生警告之外,empty() 是 (boolean) var 的反義詞。 if(empty($filedb)){$filedb[0]="";} //返回文件數組 return $filedb; } //更新線上訊息 function Update_ol(){ global $runfc; if($runfc == 'Y'){ //聲明全局變數在線上文件中的偏移量$ol_offset,用戶id$winduid,是否開啟IP統計$db_ipstates,是否修改$isModify global $ol_offset,$winduid,$db_ipstates,$isModify; //如果用戶id存在 if($winduid != ''){ //更新線上會員文件 list($alt_offset,$isModify) = addonlinefile($ol_offset,$winduid); }else{ //更新線上遊客文件 list($alt_offset,$isModify) = addguestfile($ol_offset); } //如果返回的文件中偏移量和當前cookie中的不同,更新該cookie if($alt_offset!=$ol_offset)Cookie('ol_offset',$alt_offset,0); //重置是否更新線上訊息標記為空 $runfc=''; //如果開啟ip統計 且 //(cookie中ipstate訊息為空且修改標記為是 或 //cookie中ipstate訊息存在但其小於今日開始時間) if($db_ipstates && ((!GetCookie('ipstate') && $isModify===1) || (GetCookie('ipstate') && GetCookie('ipstate')<$GLOBALS['tdtime']))){ //包含require/ipstates.php,若有重複,略過 require_once(R_P.'require/ipstates.php'); } } } //頁腳處理顯示函數 function footer(){ //聲明全局變數資料庫訪問類$db,是否開啟GZIP 壓縮輸出$db_obstart,是否在頁腳顯示程式執行時間$db_footertime,是否開啟靜態目錄部署功能$db_htmifopen,當前時間秒數$P_S_T,頭部和尾部表格寬度$mtablewidth,聯繫我們URL$db_ceoconnect,PHPWind版本$wind_version,圖片目錄$imgpath,此風格在image目錄下的資料夾名稱$stylepath,頁腳廣告$footer_ad,論壇聯盟廣告$db_union,當前時間$timestamp global $db,$db_obstart,$db_footertime,$db_htmifopen,$P_S_T,$mtablewidth,$db_ceoconnect,$wind_version,$imgpath,$stylepath,$footer_ad,$db_union,$timestamp; //更新線上訊息 Update_ol(); //如果訪問類不為空 if($db){ //記錄查詢次數 $qn=$db->query_num; } //顯示是否開始gzip壓縮 $ft_gzip=($db_obstart==1 ? "Gzip enabled" : "Gzip disabled").$db_union[3]; //如果設置了允許在頁腳顯示程式執行時間 if ($db_footertime == 1){ $t_array = explode(' ',microtime()); //number_format 按照千分制劃分數位,string number_format ( float number [, int decimals [, //string dec_point, string thousands_sep]] )它接受一個、兩個或四個參數,不接受三個;給 //定一個將沒有十進制 . 點號,只有千分制 , 逗號;兩個,具有十進制的 . 點號和千進制的 , 句號;四個,十進 //制、千進制全部用 , 都好劃分;註:僅千進制的第一個字元被使用;例如,你使用foo作為千進制的區分,那 //麼1000就成為1f000; $totaltime = number_format(($t_array[0]+$t_array[1]-$P_S_T),6); $wind_spend = "Total $totaltime(s) query $qn,"; } //按格式取當前時間 $ft_time=get_date($timestamp,'m-d H:i'); //包含對應風格目錄下的footer.htm文件 include PrintEot('footer'); //ob_get_contents 返回輸出快取記憶體的內容,如輸出快取記憶體未被啟動,將返回快取記憶體內容或Flase; $output = str_replace(array('<!--<!---->','<!---->'),array('',''),ob_get_contents()); //如果開啟靜態目錄功能 if($db_htmifopen){ //preg_replace -- 執行正則表達式的搜索和替換,mixed preg_replace ( mixed pattern, mixed //replacement, mixed subject [, int limit] )在 subject 中搜索 pattern 模式的匹配項並替換為 //replacement。如果指定了 limit,則僅替換 limit 個匹配,如果省略 limit 或者其值為 -1,則所有的匹配項 //都會被替換。replacement 可以包含 \\n 形式或(自 PHP 4.0.4 起)$n 形式的逆向引用,首選使用後者。 //每個此種引用將被替換為與第 n 個被捕獲的括號內的子模式所匹配的文本。n 可以從 0 到 99,其中 \\0 或 //$0 指的是被整個模式所匹配的文本。對左圓括號從左到右計數(從 1 開始)以取得子模式的數目。對替換模式 //在一個逆向引用後面緊接著一個數位時(即:緊接在一個匹配的模式後面的數位),不能使用熟悉的 \\1 符號 //來表示逆向引用。舉例說 \\11,將會使 preg_replace() 搞不清楚是想要一個 \\1 的逆向引用後面跟著一個 //數位 1 還是一個 \\11 的逆向引用。本例中的解決方法是使用 \${1}1。這會形成一個隔離的 $1 逆向引用, //而使另一個 1 只是單純的文字。 $output = preg_replace( "/\<a(\s*[^\>]+\s*)href\=([\"|\']?)([^\"\'>\s]+\.php\?[^\"\'>\s]+)([\"|\']?)/ies", "Htm_cv('\\3','<a\\1href=\"')", $output ); } ob_end_clean(); $db_obstart == 1 ? ob_start('ob_gzhandler') : ob_start(); echo $output; //flush -- 重新整理輸出緩衝,重新整理PHP程式的緩衝,而不論PHP執行在何種情況下(CGI ,web服務器等等)。該 //函數將當前為止程式的所有輸出發送到用戶的瀏覽器。flush() 函數不會對服務器或客戶端瀏覽器的快取記憶體模式產 //生影響。因此,必須同時使用 ob_flush() 和flush() 函數來重新整理輸出緩衝。個別web服務器程式,特別是 //Win32下的web服務器程式,在發送結果到瀏覽器之前,仍然會快取記憶體腳本的輸出,直到程式結束為止。有些 //Apache的模塊,比如mod_gzip,可能自己進行輸出快取記憶體,這將導致flush()函數產生的結果不會立即被發送 //到客戶端瀏覽器。甚至瀏覽器也會在顯示之前,快取記憶體接收到的內容。例如 Netscape 瀏覽器會在接受到換行 //或 html 標記的開頭之前快取記憶體內容,並且在接受到 </table> 標記之前,不會顯示出整個表格。一些版本的 //Microsoft Internet Explorer 只有當接受到的256個字節以後才開始顯示該網頁面,所以必須發送一些額外的 //空格來讓這些瀏覽器顯示網頁面內容。 flush; exit; } //返回靜態目錄功能開始時網頁面的訪問路徑 function Htm_cv($url,$tag){ //聲明全局變數靜態目錄$db_dir,靜態目錄延伸名設置$db_ext global $db_dir,$db_ext; //ereg -- 正則表達式匹配,注: 使用 Perl 相容正則表達式語法的 preg_match() 函數通常是比 ereg() 更快 //的替代方案。以區分大小寫的方式在 string 中尋找與給定的正則表達式 pattern 所匹配的子串。如果找到與 //pattern 中圓括號內的子模式相匹配的子串並且函數調用給出了第三個參數 regs,則匹配項將被存入 regs //數組中。$regs[1] 包含第一個左圓括號開始的子串,$regs[2] 包含第二個子串,以此類推。$regs[0] 包含 //整個匹配的字元串。注: 直到 PHP 4.1.0 為止,$regs 將被填充為正好十個單元,即使實際匹配的子串少於十 //個。這並不影響 ereg() 匹配更多子串的能力。如果沒有找到匹配,則 $regs 不會被 ereg() 更改。 如果在 //string 中找到 pattern 模式的匹配則返回 TRUE,如果沒有找到匹配或出錯則返回 FALSE。 if(ereg("^http|ftp|telnet|mms|rtsp|admin.php|rss.php",$url)===false){ if(strpos($url,'#')!==false){ $add = substr($url,strpos($url,'#')); } $url = str_replace( array('.php?','=','&',$add), array($db_dir,'-','-',''), $url ).$db_ext.$add; } return $tag.$url.'"'; } //取得用戶訊息數組 function User_info(){ //聲明全局變數資料庫訪問類$db,當前時間$timestamp,線上用戶時限$db_onlinetime,用戶id$winduid,用戶密碼$windpwd,是否記錄會員線上時間並在版塊內顯示$db_ifonlinetime,用戶此次線上時間$c_oltime,客戶端ip$onlineip,是否開啟IP驗證功能$db_ipcheck,今日開始時間$tdtime; global $db,$timestamp,$db_onlinetime,$winduid,$windpwd,$db_ifonlinetime,$c_oltime,$onlineip,$db_ipcheck,$tdtime; $ct=''; //取得資料表中的相應記錄 //相關字段名解釋如下: //用戶id-m.uid, //用戶名-m.username, //用戶密碼-m.password, //用戶郵箱-m.email, //用戶qq號-oicq, //用戶系統組id-m.groupid, //用戶會員組id-m.memberid, //用戶註冊時間-m.regdate, //用戶時區設置-m.timedf, //用戶風格設置-m.style, //用戶時間顯示格式設置-m.datefm, //主題列表每頁個數-m.t_num, //文章列表每頁個數-m.p_num, //是否已啟動-m.yz, //是否有新的短消息-m.newpm, //是否開啟簽名展示功能-m.showsign, //用戶交易帳號訊息-m.payemail //用戶發帖數-md.postnum, //用戶威望數-md.rvrc, //用戶金錢數-md.money, //用戶自定義積分數-md.credit, //用戶交易幣數-md.currency, //用戶上次訪問時間-md.lastvisit, //用戶這次訪問時間-md.thisvisit, //用戶線上時間-md.onlinetime, //用戶上次回復時間-md.lastpost, //用戶今日發帖數-md.todaypost, //用戶線上ip情況-md.onlineip, //用戶上傳時間-md.uploadtime, //用戶上傳數-md.uploadnum, //使用所見即所得編輯器還是windcode編輯器-md.editor, //簽名使用起始時間-md.starttime $detail =$db->get_one("SELECT m.uid,m.username,m.password,m.email,oicq,m.groupid,m.memberid,m.regdate,m.timedf,m.style,m.datefm,m.t_num,m.p_num,m.yz,m.newpm,m.showsign,m.payemail,md.postnum,md.rvrc,md.money,md.credit,md.currency,md.lastvisit,md.thisvisit,md.onlinetime,md.lastpost,md.todaypost,md.onlineip,md.uploadtime,md.uploadnum,md.editor,md.starttime FROM pcr_members m LEFT JOIN pcr_memberdata md USING(uid) WHERE m.uid='$winduid'"); //如果用戶登入ip字段中不存在當前客戶端ip訊息 if(strpos($detail['onlineip'],$onlineip)===false){ //以"."分割客戶端ip $iparray=explode(".",$onlineip); //如果用戶登入ip字段中不存在當前客戶端ip的前2節則退出標記設為Y if(strpos($detail['onlineip'],$iparray[0].'.'.$iparray[1])===false) $loginout='Y'; } //如果查詢不到該會員訊息即$detail為空 //或者用戶密碼在編碼後和cookie中儲存的值不相同 //或者退出標記為Y且論壇開啟了IP驗證功能 if(!$detail || PwdCode($detail['password']) != $windpwd || ($loginout=='Y' && $db_ipcheck==1)){ //銷毀$detail unset($detail); //設置當前用戶組為遊客 $GLOBALS['groupid']='guest'; //包含require/checkpass.php文件,如果其中有重複包含,略過 require_once(R_P.'require/checkpass.php'); //退出並清空cookies Loginout(); //轉網頁面顯示語言文件中ip_change對應鍵值的提示訊息 Showmsg('ip_change'); }else{ //銷毀用戶訊息中的密碼變數 unset($detail['password']); //如果當前時間和資料庫中用戶這次訪問時間差大於線上用戶時限 if($timestamp-$detail['thisvisit']>$db_onlinetime){ //非隱身 if(!GetCookie('hideid')){ $ct="lastvisit=thisvisit,thisvisit='$timestamp'"; //更新數組中上次訪問時間變數為這次訪問時間 $detail['lastvisit'] = $detail['thisvisit']; //更新數組中這次訪問時間變數為當前時間 $detail['thisvisit'] = $timestamp; } //如果設置了記錄會員線上時間並在版塊內顯示且ct變數不為空,且用戶此次線上時間大於0 if($db_ifonlinetime == 1 && $ct && $c_oltime > 0){ //如果用戶此次線上時間大於線上用戶時限的1.2倍 if($c_oltime > $db_onlinetime*1.2){ //更新用戶此次線上時間為線上用戶時限 $c_oltime = $db_onlinetime; } $ct .= ",onlinetime=onlinetime+'$c_oltime'"; $c_oltime = 0; } //若ct變數不為空,則更新資料庫中的上次訪問時間、這次訪問時間、線上時間 $ct && $db->update("UPDATE pcr_memberdata SET $ct WHERE uid='$winduid' AND $timestamp-thisvisit>$db_onlinetime"); } } //返回用戶訊息數組 return $detail; } //返回pwd的編碼後值 function PwdCode($pwd){ //連接頭訊息、$pwd參數(密碼)以及論壇安全驗證參數,md5加密後返回該值 return md5($_SERVER["HTTP_USER_AGENT"].$pwd.$GLOBALS['db_hash']); } //安全檢測,若不符合銷毀相應cookie,符合重新設置相應cookie function SafeCheck($CK,$PwdCode,$var='AdminUser',$expire=1800){ //聲明全局變數$timestamp global $timestamp; //上次訪問時間和當前時間的時間差賦於變數$t $t = $timestamp - $CK[0]; //如果其超過定義的過期時間或者$CK[2]中存儲的密碼(編碼後的密碼連接上次訪問時間再md5加密後得到的值)並不匹配 if($t > $expire || $CK[2] != md5($PwdCode.$CK[0])){ //設置$var狀態為無效,即銷毀此cookie Cookie($var,'',0); return false; }else{ //設置上次訪問時間為當前時間 $CK[0] = $timestamp; //設置存儲的密碼訊息為編碼後的密碼連接當前時間再md5加密後得到的值 $CK[2] = md5($PwdCode.$timestamp); //implode 聯結數組元素為一個字元串;string implode ( string glue, array pieces )第一個參數為分割符 //第二個參數為要聯結的數組單元; //用"\t"連接數組$CK $Value = implode("\t",$CK); //設置變數$$var為$Value編碼後的值 $$var = StrCode($Value); Cookie($var,StrCode($Value)); return true; } } //對字元串進行編碼或解碼處理,並返回編碼或解碼後得到的值 function StrCode($string,$action='ENCODE'){ //HTTP_USER_AGENT-當前請求的 User-Agent: 頭訊息的內容。該字元串表明了訪問該網頁面的用戶代理的訊息。一個典型的例子是:Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586)。也可以使用 get_browser() 得到此訊息。 //連接頭訊息和論壇安全驗證參數,md5加密後,從第8位起取18個字元,作為變數key的值 $key = substr(md5($_SERVER["HTTP_USER_AGENT"].$GLOBALS['db_hash']),8,18); //base64_decode -- 對使用 MIME base64 編碼的資料進行解碼 //如果選擇的操作是編碼操作,則string變數不變仍舊為自己本身參數的值,否則為base64解碼該參數後得到的值 $string = $action == 'ENCODE' ? $string : base64_decode($string); //記錄key的長度,為18 $len = strlen($key); $code = ''; //對string中的每個字元 for($i=0; $i<strlen($string); $i++){ //k變數存儲$i % $len餘數 $k = $i % $len; //位運算符允許對整型數中指定的位進行置位。如果左右參數都是字元串,則位運算符將操作字元的 ASCII 值。 //$a ^ $b Xor(按位異或) 將把 $a 和 $b 中不同的位設為 1。 //把$string[$i]和$key[$k]以ascii值方式進行異或運算後,值累加到code變數中 $code .= $string[$i] ^ $key[$k]; } //base64_encode -- 使用 MIME base64 對資料進行編碼 //設計此種編碼是為了使二進制資料可以通過非純 8-bit 的傳輸層傳輸,例如電子郵件的主體。 //Base64-encoded 資料要比原始資料多佔用 33% 左右的空間。 //如果選擇的操作是加碼操作,則code變數不變,否則為base64編碼code後得到的值 $code = $action == 'DECODE' ? $code : base64_encode($code); return $code; } //返回$content字元串$length長度的值,超過$length顯示".." function substrs($content,$length){ //取字元集設置 global $db_charset; if($length && strlen($content)>$length){ if($db_charset!='utf-8'){ $retstr=''; for($i = 0; $i < $length - 2; $i++) { //ord 返回字元串的第一個字元的二進制值;string chr ( int ascii ) 返回相對應於 ascii 所指定的單個字元。 $retstr .= ord($content[$i]) > 127 ? $content[$i].$content[++$i] : $content[$i]; } return $retstr.' ..'; }else{ //trim 去除字元串裡的空格或其他字元,string trim ( string str [, string charlist] ), //" " (ASCII 32 (0x20)), 空格."\t" (ASCII 9 (0x09)),tab字元."\n" (ASCII 10 (0x0A)),換行符; //"\r" (ASCII 13 (0x0D)), Enter鍵符."\0" (ASCII 0 (0x00)),空字元."\x0B" (ASCII 11 (0x0B)), 垂直tab. return utf8_trim(substr($content,0,$length)).' ..'; } } return $content; } //將非utf8字元集字元串取整字元串避免亂碼 function utf8_trim($str) { $len = strlen($str); for($i=strlen($str)-1;$i>=0;$i-=1){ $hex .= ' '.ord($str[$i]); $ch = ord($str[$i]); if(($ch & 128)==0) return substr($str,0,$i); if(($ch & 192)==192)return substr($str,0,$i); } return($str.$hex); } //按格式返回時間 function get_date($timestamp,$timeformat=''){ //聲明全局變數論壇預定時間顯示格式$db_datefm,預定時區設置$db_timedf,用戶時間顯示格式$_datefm,用戶時區設置$_timedf global $db_datefm,$db_timedf,$_datefm,$_timedf; //如果傳入參數設定了時間格式,則時間格式取參數中設定的值,否則看是否用戶設置了時間顯示格式,有則取用戶的時間顯示格式,否則取論壇預定時間顯示格式 $date_show=$timeformat ? $timeformat : ($_datefm ? $_datefm : $db_datefm); //取得時區設置(用戶沒設置取論壇預定的) if($_timedf){ $offset = $_timedf=='111' ? 0 : $_timedf; }else{ $offset = $db_timedf=='111' ? 0 : $db_timedf; } //按格式返回真實的用戶顯示時間 return gmdate($date_show,$timestamp+$offset*3600); } //遞歸執行,使得每個數組中的字元串都是為了資料庫查詢語句等的需要在某些特殊字元前加上了反斜線的字元串 function Add_S(&$array){ foreach($array as $key=>$value){ if(!is_array($value)){ //addslashes -- 使用反斜線引用字元串,返回字元串,該字元串為了資料庫查詢語句等的需要在某些字元前加 //上了反斜線。這些字元是單引號(')、雙引號(")、反斜線(\)與 NUL(NULL 字元)。 一個使用 //addslashes() 的例子是當你要往資料庫中輸入資料時。例如,將名字 O'reilly 插入到資料庫中,這就需要對 //其進行轉義。大多資料庫使用 \ 作為轉義符:O\'reilly。這樣可以將資料放入資料庫中,而不會插入額外的 \。 //當 PHP 指令 magic_quotes_sybase 被設置成 on 時,意味著插入 ' 時將使用 ' 進行轉義。預定情況下, //PHP 指令 magic_quotes_gpc 為 on,它主要是對所有的 GET、POST 和 COOKIE 資料自動執行 //addslashes()。不要對已經被 magic_quotes_gpc 轉義過的字元串使用 addslashes(),因為這樣會導致 //雙層轉義。遇到這種情況時可以使用函數 get_magic_quotes_gpc() 進行檢測。 $array[$key]=addslashes($value); }else{ Add_S($array[$key]); } } } //對字元中的特殊字元進行轉義,並返回轉換後的字元串 function Char_cv($msg){ $msg = str_replace('&','&',$msg); $msg = str_replace(' ',' ',$msg); $msg = str_replace('"','"',$msg); $msg = str_replace("'",''',$msg); $msg = str_replace("<","<",$msg); $msg = str_replace(">",">",$msg); $msg = str_replace("\t"," ",$msg); $msg = str_replace("\r","",$msg); $msg = str_replace(" "," ",$msg); return $msg; } //認證碼檢查函數 function GdConfirm($code){ //銷毀cookie中的cknum Cookie('cknum','',0); if(!$code || !SafeCheck(explode("\t",StrCode(GetCookie('cknum'),'DECODE')),$code,'cknum',1800)){ //轉網頁面顯示語言文件中check_error對應鍵值的提示訊息 Showmsg('check_error'); } } //廣告初始化函數 function AdvertInit($SCR,$fid){ //聲明全局變數當前時間$timestamp global $timestamp; //包含data/bbscache/advert_data.php include(D_P.'data/bbscache/advert_data.php'); $newadvert = array(); foreach($advertdb as $key=>$val){ foreach($val as $k=>$v){ //strtotime -- 將任何英文文本的日期時間描述解析為 Unix 時間戳,本函數預期接受一個包含美國英語日期格 //式的字元串並嘗試將其解析為 Unix 時間戳(自 January 1 1970 00:00:00 GMT 起的秒數),其值相對於 //now 參數給出的時間,如果沒有提供此參數則用系統當前時間。本函數將使用 TZ 環境變數(如果有的話)來 //計算時間戳。自 PHP 5.1.0 起有更容易的方法來定義時區用於所有的日期/時間函數。此過程在 //date_default_timezone_get() 函數網頁面中有說明。注: 如果給定的年份是兩位數位的格式,則其值 0-69 //表示 2000-2069,70-100 表示 1970-2000。參數 time 被解析的字元串,格式根據 GNU Date //Input Formats 語法 now 用來計算返回值的時間戳 返回值 成功則返回時間戳,否則返回 FALSE。 //在 PHP 5.1.0 之前本函數在失敗時返回 -1。 php5.1.0 失敗時返回 FALSE,不再是 -1。 //如果是頭部橫幅廣告或者底部橫幅廣告且結束時間為空 //或者結束時間小於當前時間 if(($key=='header' || $key=='footer') && !$v['endtime'] || strtotime($v['endtime']) < $timestamp){ //跳出執行下個循環 continue; } //如果是首頁且投放範圍為首頁 if($SCR == 'index' && strpos(",$v[fid],",",-1,")!==false){ $newadvert[$key][]=$v; //如果是板塊且投放範圍為主題列表網頁面 }elseif($SCR == 'thread' && strpos(",$v[fid],",",-2,")!==false){ $newadvert[$key][]=$v; //如果是帖子且投放範圍為帖子網頁面 }elseif($SCR == 'read' && strpos(",$v[fid],",",-3,")!==false){ $newadvert[$key][]=$v; //如果投放範圍為所有網頁面 }elseif(strpos(",$v[fid],",",-4,")!==false){ $newadvert[$key][]=$v; //如果板塊fid不為空投放範圍包含該板塊 }elseif($fid && strpos(",$v[fid],",",$fid,")!==false){ $newadvert[$key][]=$v; } } } //返回廣告數組 return $newadvert; } //取路徑,去除$path中的文件名 function getdirname($path){ if(strpos($path,'\\')!==false){ //strrpos 查找匹配字元串出現的最後位置;沒找到,返回False return substr($path,0,strrpos($path,'\\')); }elseif(strpos($path,'/')!==false){ return substr($path,0,strrpos($path,'/')); }else{ return '/'; } } ?> [Copy to clipboard] data\sql_config.php CODE: <?php //此文件內容為論壇資料庫配置訊息,以及插件創始人訊息 /** * 以下變數需根據您的服務器說明檔修改 */ $dbhost = 'localhost'; // 資料庫服務器 $dbuser = 'root'; //資料庫用戶名 $dbpw = 'phpwind.net'; // 資料庫密碼 $dbname = 'phpwind'; // 資料庫名 $database = 'mysql'; //資料庫類型 $PW = 'pcr_'; //表區分符 $pconnect = 0; //是否持久連接 /* MYSQL編碼設置 如果您的論壇出現亂碼現象,需要設置此項來修復 請不要隨意更改此項,否則將可能導致論壇出現亂碼現象 */ $charset='gbk'; /** * 論壇創始人,擁有論壇所有權限 */ //創始人賬號 $manager='admin'; //創始人md5加密密碼 $manager_pwd='21232f297a57a5a743894a0e4a801fc3'; /** * 鏡像站點設置 */ $db_hostweb=1; //是否為主站點 /* * 附件url地址 例如: http://www.phpwind.net/attachment 最後為附件目錄 */ $attach_url=''; /** * 插件配置 */ $db_hackdb=array( //插件名稱 唯一標識符 前台文件名 後台文件名 是否啟用(0不顯示1下拉表菜單顯示2直接顯示) 相關文件(前台程式文件,後台程式文件,前台模板文件,後台模板文件) 'bank'=>array('銀行','bank','bank.php','bankset.php','1','hack/bank.php,hack/bankset.php,template/wind/bank.htm,template/admin/bankset.htm'), 'colony'=>array('朋友圈','colony','colony.php','colonyset.php','1','hack/colony.php,hack/colonyset.php,template/admin/colonyset.htm,template/wind/colony.htm'), 'advert'=>array('廣告管理','advert','','advert.php','1','hack/advert.php'), 'new'=>array('首頁調用管理','new','','new.php','0','hack/new.php'), 'medal'=>array('勳章中心','medal','medal.php','medalset.php','0','hack/medal.php,hack/medalset.php,template/wind/medal.htm,template/admin/medalset.htm'), 'toolcenter'=>array('道具中心','toolcenter','toolcenter.php','toolsetting.php','0','hack/toolcenter.php,hack/toolsetting.php,template/wind/toolcenter.htm,template/admin/toolsetting.htm'), 'blog'=>array('博客','blog','blog.php','blogset.php','0','hack/blog.php,hack/blogset.php,template/wind/blog.htm,template/admin/blogset.htm'), 'live'=>array('網路電視','live','live.php','','2',''), ); ?> [Copy to clipboard] data\bbscache\config.php CODE: <?php //此文件內容為論壇核心設置,論壇程式修改的時候同時修改資料庫和本文件 //如果某些變數沒有,說明還沒有在後台儲存過相應設置,本文件中的某些變數需要儲存過相應設置才會存在 //定時更改圖片目錄防止圖片盜鏈(小時) $db_hour='20'; //是否使用跨台固定圖片鏈 $db_http='N'; //是否自動不定期更改圖片鏈 $db_autochange='0'; //論壇狀態:是否關閉 $db_bbsifopen='1'; //論壇關閉的原因 $db_whybbsclose='論壇升級中... 請等候 15分鐘'; //論壇標題 $db_bbsname='PHPwind Board'; //論壇地址 $db_bbsurl='http://localhost/phpwind'; //論壇標題(4.0.1以下版本使用) $db_wwwname='PHPwind Studio'; //論壇地址(4.0.1以下版本使用) $db_wwwurl='http://localhost/phpwind'; //聯繫我們URL:(出現在頁尾) $db_ceoconnect='http://www.phpwind.net/sendemail.php?username=fengyu'; //管理員信箱 $db_ceoemail='webmaster@phpwind.com'; //分版塊文章多少時間表示為新帖(3600=1小時) $db_newtime='3600'; //簽名中是否使用 Wind 代碼功能 $db_signwindcode='1'; //簽名中是否使用 Wind IMG功能 $db_windpic['pic']='1'; //簽名中是否使用 Wind Flash功能 $db_windpic['flash']='0'; //簽名中[img]標籤的寬度大小控制 $db_windpic['picwidth']='700'; //簽名中[img]標籤的高度大小控制 $db_windpic['picheight']='200'; //簽名中[size]標籤的大小控制 $db_windpic['size']='3'; //服務器時間校正 (分),此功能用於校正服務器操作系統時間設置錯誤的問題,當確認論壇預定時區設置正確後,論壇顯示時間仍有錯誤,請使用此功能校正 $db_cvtime='0'; //預定時區設置 $db_timedf='8'; //論壇文章列表每頁顯示主題數 $db_perpage='20'; //閱讀一主題時每頁顯示帖子數 $db_readperpage='10'; //用戶文章被回復是否發送郵件 $db_replysendmail='0'; //每篇文章的最大長度(字節) $db_postmax='50000'; //帖子中是否使用 Wind IMG功能 $db_windpost['pic']='1'; //帖子中[img]標籤的寬度大小控制 $db_windpost['picwidth']='700'; //帖子中[img]標籤的高度大小控制 $db_windpost['picheight']=''; //帖子中[size]標籤的大小控制 $db_windpost['size']='5'; //帖子中是否使用 Wind Flash功能 $db_windpost['flash']='0'; //4.0.1以下版PHPWind參數,含義不明 $db_indexnotice='1'; //post回復時顯示提示舊帖數 $db_showreplynum='5'; //快捷回復帖子是否使用 Wind IMG功能 $db_windreply['pic']='1'; //快捷回復帖子是否使用 Wind Flash功能 $db_windreply['flash']='0'; //回復增加的威望值(4.0.1以下) $db_dtreplyrvrc='1'; //重新整理預防時間(多少秒間重新整理被視為惡意重新整理) $db_refreshtime='0'; //線上用戶時限(多少分鐘內有動作視為線上) $db_onlinetime='3600'; //是否在頁腳顯示程式執行時間 $db_footertime='1'; //版塊內是否顯示線上用戶 $db_threadonline='0'; //上傳附件大小上限(k)超管不受限制 $db_uploadmaxsize='2048000'; //上傳附件允許後綴(空格隔開) $db_uploadfiletype='gif jpg rar txt zip swf jqf'; //附件儲存方式 //0- 預定(全部存入同一目錄) //1- 按版塊存入不同目錄 //2- 按類型存入不同目錄 //3- 按月份存入不同目錄 //4- 按天存入不同目錄 $db_attachdir='0'; //一次最多上傳附件個數 $db_attachnum='4'; //帖子中是否使用 Wind (wmv,asf,ra,ram,rm)功能 $db_windpost['mpeg']='1'; //帖子中是否使用 iframe功能 $db_windpost['iframe']='0'; //以下四項為4.0.1以下版PHPWind發表帖子以及回復增加的威望和金錢 $db_dtpostrvrc='10'; $db_dtpostmoney='5'; $db_dtjhrvrc='50'; $db_dtjhmoney='5'; //最大線上人數 $db_onlinelmt='0'; //以下三項為4.0.1以下版PHPWind刪除帖子以及回復減少的威望和金錢 $db_dtdelrvrc='10'; $db_dtdelrprvrc='10'; $db_dtdelmoney='5'; //首頁是否顯示線上用戶 $db_indexonline='1'; //是否使用自動跳轉 $db_ifjump='1'; //是否打開註冊提示窗 $db_regpopup='0'; //是否記錄會員線上時間並在版塊內顯示 $db_ifonlinetime='0'; //首頁是否顯示線上遊客 $db_showguest='0'; //資源回收筒ID $db_recycle='3'; //首頁是否顯示今天生日會員 $db_indexshowbirth='0'; //GZIP 壓縮輸出:選擇是將允許論壇通過 gzip 輸出網頁面,可以很明顯的降低帶寬需求,但只有在客戶端支持的情況下才可使用,並會加大服務器系統開銷 $db_obstart='1'; //是否顯示友情鏈接 $db_indexlink='1'; //是否滾動顯示友情鏈接 $db_indexmqshare='0'; //預定論壇風格 $db_defaultstyle='wind'; //COOKIE有效目錄,使一個空間放置多個論壇,都能訪問! $db_ckpath='/'; //COOKIE有效域名 $db_ckdomain=''; //以下兩項為4.0.1以下版PHPWind參數,含義不明 $db_windreadable='1'; $db_schpernum='10000'; //各分版塊帖子導航裡是否顯示表情符 $db_threademotion='0'; //是否顯示今日昨日發帖數 $db_todaypost='0'; //各分版塊帖子裡是否顯示快速發表主題 $db_threadshowpost='0'; //自定義首頁各版塊的圖片logo //0-不使用 //1-預定 //2-自定義 $db_indexfmlogo='2'; //是否使用自動貼圖 $db_autoimg='1'; //每篇文章的最小長度(字節) $db_postmin='3'; //投票選項個數控制 $db_selcount='15'; //瀏覽帖子處是否顯示會員IP來源 $db_ipfrom='1'; //回復增加的金錢值(4.0.1以下) $db_dtreplymoney='1'; //是否開啟IP驗證功能:可以加強論壇安全,選擇開啟將對登入者ip進行驗證,如果與上一次登入ip前2位不同,將要求重新登入 $db_ipcheck='0'; //是否統計今日到訪會員 $db_today='0'; //註冊會員在多少時間內不能發表文章(小時) $db_postallowtime='0'; //閱讀帖子時是否顯示線上用戶 $db_showonline='1'; //IP封禁列表 $db_ipban=''; //4.0.1以下版PHPWind參數,含義不明 $db_ifcheck='1'; //是否允許用戶使用宣傳代碼 $db_ads='1'; //點擊率延遲更新功能(小時) $db_hithour='0'; //4.0.1以下版PHPWind參數,含義不明 $db_upgrade='1'; //是否開啟工作行程優化 $db_lp='0'; //是否開啟總置頂, 分類置頂功能 $db_topped='0'; //是否開啟新消息聲音提示 $db_msgsound='0'; //論壇預定時間顯示格式 //格式如:yyyy-mm-dd,yy-m-d //yyyy代表4位數年份,yy代表2位數年份 //mm代表有前導零01-12,m代表沒前導零1-12 //dd代表有前導零01-31,d代表沒前導零1-3 $db_datefm='Y-m-d H:i'; //認證碼功能(4.0以前) $db_lgck='0'; //論壇首頁調用文件 $db_bfn='index.php'; //以下兩項為4.0.1以下版PHPWind參數,含義不明 $db_hfn='bbs'; //4.0.1一下版本使用作用不明 $db_cfn='c_index.php'; //參與線上顯示的用戶組 $db_showgroup=',3,4,5,16,'; //是否開啟頭像上傳功能 頭像高度 頭像寬度 頭像大小 $db_upload='1 200 180 20480'; //是否使用附件上傳功能 $db_allowupload='1'; //是否使用下拉框方式顯示版主 $db_adminshow='0'; //主題列表最大顯示頁數 $db_maxpage='1000'; //用戶列表最大頁數 $db_maxmember='1000'; //標題最大長度 $db_titlemax='100'; //貨幣名稱 貨幣單位 威望名稱 威望單位 貢獻值名稱 貢獻值單位 $db_credits='金錢 RMB 威望 點 貢獻值 點'; //4.0.1以下版PHPWind參數,含義不明 $db_savecheck='1'; //論壇安全驗證參數:除非論壇出現安全危機,請不要隨意修改 $db_hash='89Y**4^M*l'; //搜索查詢的最大結果數 $db_maxresult='500'; //帖子獎懲設置 //數組經過serialize函數做序列化操作,使用時需用unserialize解序列化操作使用 //精華一個主題增加、發佈一個主題增加、回復一個主題增加、取消精華主題減少、刪除一個主題減少、刪除一個回復減少的威望情況 //s:4:"rvrc";a:6:{s:6:"Digest";i:20;s:4:"Post";i:10;s:5:"Reply";i:10;s:8:"Undigest";i:20;s:6:"Delete";i:10;s:8:"Deleterp";i:10;} //精華一個主題增加、發佈一個主題增加、回復一個主題增加、取消精華主題減少、刪除一個主題減少、刪除一個回復減少的金錢情況 //s:5:"money";a:6:{s:6:"Digest";i:20;s:4:"Post";i:10;s:5:"Reply";i:10;s:8:"Undigest";i:20;s:6:"Delete";i:10;s:8:"Deleterp";i:10;} //精華一個主題增加、發佈一個主題增加、回復一個主題增加、取消精華主題減少、刪除一個主題減少、刪除一個回復減少的好評度情況 //i:1;a:6:{s:6:"Digest";i:0;s:4:"Post";i:0;s:5:"Reply";i:0;s:8:"Undigest";i:0;s:6:"Delete";i:0;s:8:"Deleterp";i:0;} $db_creditset='a:3:{s:4:"rvrc";a:6:{s:6:"Digest";i:20;s:4:"Post";i:10;s:5:"Reply";i:10;s:8:"Undigest";i:20;s:6:"Delete";i:10;s:8:"Deleterp";i:10;}s:5:"money";a:6:{s:6:"Digest";i:20;s:4:"Post";i:10;s:5:"Reply";i:10;s:8:"Undigest";i:20;s:6:"Delete";i:10;s:8:"Deleterp";i:10;}i:1;a:6:{s:6:"Digest";i:0;s:4:"Post";i:0;s:5:"Reply";i:0;s:8:"Undigest";i:0;s:6:"Delete";i:0;s:8:"Deleterp";i:0;}}'; //是否允許快速編輯主題(實現不重新整理網頁面提交資料,只有管理人員有權限) $db_ajaxsubject='1'; //是否允許快速編輯主題內容(實現不重新整理網頁面提交資料,管理人員和作者有權限) $db_ajaxcontent='1'; //是否為DEBUG 模式執行論壇:不屏蔽程式報錯訊息,論壇出現異常時打開此模式,將錯誤訊息提交給程式開發商,以便盡快得到解決 $db_debug='0'; //是否開啟註冊認證碼功能 前台登入認證碼功能 發帖認證碼功能 短消息認證碼功能 其它認證碼功能 後台登入認證碼功能 $db_gdcheck='0 0 0 0 0 0'; //簽名顯示一天需要交易幣個數 $db_signmoney='0'; //需要購買簽名顯示的用戶組 $db_signgroup=',5,6,7,16,8,9,10,11,12,13,14,15,'; //是否使用圖片水印功能 $db_watermark='0'; //水印位置 //0-隨機位置 //1-上頭位置居左 //2-上頭位置居中 //3-上頭位置居右 //7-中心位置 //4-底部居左 //5-底部居中 //6-底部居右 $db_waterpos='1'; //水印圖片文件名.水印圖片存放路徑:$imgpath/water,如果水印圖片不存在,則使用文字水印 $db_waterimg='mark.gif'; //水印圖片文字 $db_watertext='http://www.phpwind.net'; //水印圖片文字字體大小 $db_waterfont='5'; //水印圖片文字顏色(十六進制顏色值,預定為#FF0000:紅色) $db_watercolor='#0000FF'; //水印透明度,該值決定圖片水印清晰度,其值範圍從 0 到 100。 $db_waterpct='85'; //帖子中表情,動作以及 img,wmv,rm 等標籤的最多轉換次數 $db_cvtimes='30'; //二級目錄/域名功能 0-不使用 1-直接訪問 2-二級域名訪問 $db_forumdir='0'; //是否使用遠端附件連接設置 $db_attachurl='N'; //4.0.1以下版PHPWind參數,含義不明 $db_kijiji='1'; //管理操作原因:顯示在前台管理操作的操作原因備選框中,操作者可自行輸入或選擇一個操作原因,操作原因將包含在用戶通知消息和後台管理操作記錄中每行填寫一個操作原因,空行顯示為分隔符「-------」 $db_adminreason='廣告帖 惡意灌水 非法內容 與版規不符 重複發帖 優秀文章 原創內容'; //預定編碼設置 $db_charset='gbk'; //CC攻擊防護設置 0-不使用 1-普通模式 2-加強模式 $db_cc='0'; //是否開啟 JS調用 此功能允許在您的網站首頁或其他地方調用論壇的內容 調用方式分為: 版塊調用、公告調用、基本訊息調用、會員排行調用、文章調用。 $db_jsifopen='0'; //快取記憶體更新時間(秒) $db_jsper='600'; //允許調用網站域名 $db_bindurl=''; //是否在帖子網頁面顯示用戶加入的{$db_hackdb[colony][0]}(指朋友圈,名稱根據論壇設置變化) $db_showcolony='0'; //選擇要在閱讀帖子網頁面(read.php)顯示的自定義積分 $db_showcustom=',1,'; //是否顯示文章系統 $db_showcms='0'; //文章系統是否打開 $db_cmsifopen='0'; //文章系統關閉原因 $db_whycmsclose='文章系統關閉中,請從上頭位置鏈接進入社區'; //論壇聯盟廣告 $db_union='a:0:{} //是否開啟靜態目錄部署功能 $db_htmifopen='0'; //靜態目錄 $db_dir='.php?'; //靜態目錄延伸名設置 $db_ext='.html'; //是否開啟定時打開與關閉論壇發貼設置 發言開啟於(點) 發言關閉於(點) $db_openpost='1 1 2'; //Meta 關鍵詞 為所有網頁面輸入 Meta 關鍵詞,讓搜索引擎更容易找到您的論壇. $db_metakeyword='admin'; //Meta 描述 為所有網頁面輸入 Meta 描述,以便能夠在搜索引擎中正確搜索到您的論壇. $db_metadescrip='admin'; //是否開啟定時打開與關閉論壇搜索功能 搜索開啟於(點) 搜索關閉於(點) $db_opensch='1 1 2'; //新增水印的圖片大小控制 只對超過程式設置的大小的附件圖片才加上水印圖片或文字(設置為0不限制) //寬度 $db_waterwidth=''; //是否開啟WAP功能 $db_wapifopen='0'; //新增水印的圖片大小控制 只對超過程式設置的大小的附件圖片才加上水印圖片或文字(設置為0不限制) //高度 $db_waterheight=''; //WAP 網頁面長度控制 $db_waplimit=''; //是否開啟IP統計 $db_ipstates='1'; ?> [Copy to clipboard] data\groupdb\group_3.php CODE: <?php //此文件內容為管理員組配置文件 //後台會員組設置後更新資料庫的同時更新此文件 //本文件中的某些變數需要儲存過相應設置才會存在 //用戶組id $gp_gid='3'; //用戶組類別 system 系統組,default 預定組,member 會員組,special 特殊組 $gp_gptype='system'; //用戶組頭銜 $gp_grouptitle='管理員'; //等級圖片號 $gp_groupimg='3'; //升級點數需求 $gp_grouppost='0'; //最大短消息數 $gp_maxmsg='100'; //是否允許隱身登入 $gp_allowhide='1'; //是否允許瀏覽帖子 $gp_allowread='1'; //是否允許用戶使用自定義頭像 $gp_allowportait='1'; //是否允許用戶使用頭像上傳功能 $gp_upload='1'; //是否允許回復主題 $gp_allowrp='1'; //是否允許自定義榮譽頭銜 $gp_allowhonor='1'; //是否允許刪除自己的帖子 $gp_allowdelatc='1'; //是否允許發表主題 $gp_allowpost='1'; //是否允許發起投票 $gp_allownewvote='1' //是否允許參與投票; $gp_allowvote='1'; //是否允許發html帖 $gp_htmlcode='1'; //是否允許使用所見即所得編輯器 $gp_wysiwyg='1'; //是否允許發隱藏帖 $gp_allowhidden='1'; //是否允許發加密帖 $gp_allowencode='1'; //是否允許發出售帖 $gp_allowsell='1'; //搜索權限控制 0不允許使用搜索1只允許搜索主題2允許搜索主題和內容 $gp_allowsearch='2'; //是否允許檢視會員列表 $gp_allowmember='1'; //是否允許檢視會員資料 $gp_allowprofile='1'; //是否允許使用報告功能 $gp_allowreport='1'; //是否允許發送短消息 $gp_allowmessege='1'; //是否允許檢視統計與排行 $gp_allowsort='1'; //是否允許使用主題排序(主題列表網頁面 ) $gp_alloworder='1'; //是否允許上傳附件 $gp_allowupload='1'; //是否允許下載附件 $gp_allowdownload='1'; //上傳附件需要的威望值(4.0以前版本) $gp_allowloadrvrc='0'; //一天最多上傳附件個數 $gp_allownum='50'; //編輯時間約束(分鐘)超過設定時間後拒絕用戶編輯。留空或者鍵入0則沒有約束 $gp_edittime='0'; //灌水預防(多少秒間隔內不能發帖,設為0則不做限制) $gp_postpertime='0'; //兩次搜索時間間隔(秒) $gp_searchtime='0'; //個人簽名最大字節數 $gp_signnum='1000'; //上傳附件被扣金錢為 $gp_uploadmoney='0'; $_G=array( //是否允許檢視帖子操作記錄 (允許用戶檢視自己的帖子被操作情況) 'atclog'=>'0', //是否允許使用展區功能 'show'=>'1', //是否允許檢視ip來源 (如果論壇核心設置中關閉此功能,則此項設置無效) 'viewipfrom'=>'1', //簽名中的圖片最大寬度(留空使用核心裡的設置) 'imgwidth'=>'', //簽名中的圖片最大高度(留空使用核心裡的設置) 'imgheight'=>'', //簽名中[size]標籤的最大值(留空使用核心裡的設置) 'fontsize'=>'', //是否允許使用「只接收特定用戶組的短消息」的功能 'msggroup'=>'1', //收藏夾容量 'maxfavor'=>'100', //是否允許檢視投票結果 'viewvote'=>'1', //發表的文章是否需要管理員審核(此項只有是開啟版塊文章審核時有效) 'atccheck'=>'1', //是否開啟論壇評分權限(下面3項起作用的前提是開啟此選項) //若開啟版主評分權限, 則版主在所有版塊內都擁有評分權限, 若關閉版主的評分權限, 則版主只在自己管理的版塊內擁有評分權限. 'markable'=>'1', //每天最多允許發表多少篇帖子(設置為0不限制) 'postlimit'=>'', //上傳附件大小上限 留空或設置為"0"使用論壇核心設置中的設置 'uploadmaxsize'=>'0', //上傳附件允許後綴(空格隔開) 留空使用論壇核心設置中的設置 'uploadtype'=>'', //評分上限 評分最小值 評分最大值 評分類型 'markdb'=>'300|-20|20|,rvrc,money,credit,1,', ); ); //是否為預定用戶組 $gp_ifdefault='0'; $SYSTEM=array( //是否允許進後台 'allowadmincp'=>'1', 'visithide'=>'0', //是否允許批量刪除主題 前台帖子管理權限 'delatc'=>'1', //是否允許批量移動帖子 前台帖子管理權限 'moveatc'=>'1', //是否允許批量複製帖子 前台帖子管理權限 'copyatc'=>'1', //是否擁有前台" 精、鎖、提、亮 "管理權限 'typeadmin'=>'1', //是否允許檢視需要驗證的帖子 'viewcheck'=>'1', //是否允許檢視關閉帖子 'viewclose'=>'1', //是否允許檢視附件(4.0以前) 'attachper'=>'0', //是否允許刪除附件 'delattach'=>'1', //是否允許檢視IP 瀏覽帖子時顯示 0無1全部板塊2所管理板塊 'viewip'=>'1', //是否開啟評分權限(4.0以前) 'markable'=>'0', //評分最大值(4.0以前) 'maxcredit'=>'0', //評分類型(4.0以前) 'credittype'=>'', //評分限制(4.0以前) 'creditlimit'=>'', //是否開啟會員禁言權限 'banuser'=>'1', //是否允許永久禁言 'bantype'=>'1', //禁言時間限制 封禁會員的最大天數 'banmax'=>'30', //是否允許檢視加密帖(隱藏,加密,出售) 'viewhide'=>'1', //是否允許灌水 不受灌水時間限制 'postpers'=>'1', //發表的文章是否需要管理員審核(4.0以前) 'atccheck'=>'0', //是否允許回復鎖定帖 'replylock'=>'1', //是否允許刪除自己的帖子(4.0以前) 'modown'=>'0', //是否允許刪除單一帖子(包括回復) 'modother'=>'1', //是否允許編輯帖子 編輯用戶帖子 'deltpcs'=>'1', //置頂權限 0無1版塊置頂2版塊置頂,分類置頂3版塊置頂,分類置頂,總置頂 'topped'=>'3', //是否允許進行主題分類管理 主題分類批量管理權限 'tpctype'=>'1', //是否允許進行主題驗證管理 前台主題驗證管理權限 'tpccheck'=>'1', ); ?> [Copy to clipboard] data\style\wind.php CODE: <?php //此文件內容為管理員組配置文件 //後台會員組設置後更新資料庫的同時更新此文件 //本文件中的某些變數需要儲存過相應設置才會存在 //用戶組id $gp_gid='3'; //用戶組類別 system 系統組,default 預定組,member 會員組,special 特殊組 $gp_gptype='system'; //用戶組頭銜 $gp_grouptitle='管理員'; //等級圖片號 $gp_groupimg='3'; //升級點數需求 $gp_grouppost='0'; //最大短消息數 $gp_maxmsg='100'; //是否允許隱身登入 $gp_allowhide='1'; //是否允許瀏覽帖子 $gp_allowread='1'; //是否允許用戶使用自定義頭像 $gp_allowportait='1'; //是否允許用戶使用頭像上傳功能 $gp_upload='1'; //是否允許回復主題 $gp_allowrp='1'; //是否允許自定義榮譽頭銜 $gp_allowhonor='1'; //是否允許刪除自己的帖子 $gp_allowdelatc='1'; //是否允許發表主題 $gp_allowpost='1'; //是否允許發起投票 $gp_allownewvote='1' //是否允許參與投票; $gp_allowvote='1'; //是否允許發html帖 $gp_htmlcode='1'; //是否允許使用所見即所得編輯器 $gp_wysiwyg='1'; //是否允許發隱藏帖 $gp_allowhidden='1'; //是否允許發加密帖 $gp_allowencode='1'; //是否允許發出售帖 $gp_allowsell='1'; //搜索權限控制 0不允許使用搜索1只允許搜索主題2允許搜索主題和內容 $gp_allowsearch='2'; //是否允許檢視會員列表 $gp_allowmember='1'; //是否允許檢視會員資料 $gp_allowprofile='1'; //是否允許使用報告功能 $gp_allowreport='1'; //是否允許發送短消息 $gp_allowmessege='1'; //是否允許檢視統計與排行 $gp_allowsort='1'; //是否允許使用主題排序(主題列表網頁面 ) $gp_alloworder='1'; //是否允許上傳附件 $gp_allowupload='1'; //是否允許下載附件 $gp_allowdownload='1'; //上傳附件需要的威望值(4.0以前版本) $gp_allowloadrvrc='0'; //一天最多上傳附件個數 $gp_allownum='50'; //編輯時間約束(分鐘)超過設定時間後拒絕用戶編輯。留空或者鍵入0則沒有約束 $gp_edittime='0'; //灌水預防(多少秒間隔內不能發帖,設為0則不做限制) $gp_postpertime='0'; //兩次搜索時間間隔(秒) $gp_searchtime='0'; //個人簽名最大字節數 $gp_signnum='1000'; //上傳附件被扣金錢為 $gp_uploadmoney='0'; $_G=array( //是否允許檢視帖子操作記錄 (允許用戶檢視自己的帖子被操作情況) 'atclog'=>'0', //是否允許使用展區功能 'show'=>'1', //是否允許檢視ip來源 (如果論壇核心設置中關閉此功能,則此項設置無效) 'viewipfrom'=>'1', //簽名中的圖片最大寬度(留空使用核心裡的設置) 'imgwidth'=>'', //簽名中的圖片最大高度(留空使用核心裡的設置) 'imgheight'=>'', //簽名中[size]標籤的最大值(留空使用核心裡的設置) 'fontsize'=>'', //是否允許使用「只接收特定用戶組的短消息」的功能 'msggroup'=>'1', //收藏夾容量 'maxfavor'=>'100', //是否允許檢視投票結果 'viewvote'=>'1', //發表的文章是否需要管理員審核(此項只有是開啟版塊文章審核時有效) 'atccheck'=>'1', //是否開啟論壇評分權限(下面3項起作用的前提是開啟此選項) //若開啟版主評分權限, 則版主在所有版塊內都擁有評分權限, 若關閉版主的評分權限, 則版主只在自己管理的版塊內擁有評分權限. 'markable'=>'1', //每天最多允許發表多少篇帖子(設置為0不限制) 'postlimit'=>'', //上傳附件大小上限 留空或設置為"0"使用論壇核心設置中的設置 'uploadmaxsize'=>'0', //上傳附件允許後綴(空格隔開) 留空使用論壇核心設置中的設置 'uploadtype'=>'', //評分上限 評分最小值 評分最大值 評分類型 'markdb'=>'300|-20|20|,rvrc,money,credit,1,', ); ); //是否為預定用戶組 $gp_ifdefault='0'; $SYSTEM=array( //是否允許進後台 'allowadmincp'=>'1', 'visithide'=>'0', //是否允許批量刪除主題 前台帖子管理權限 'delatc'=>'1', //是否允許批量移動帖子 前台帖子管理權限 'moveatc'=>'1', //是否允許批量複製帖子 前台帖子管理權限 'copyatc'=>'1', //是否擁有前台" 精、鎖、提、亮 "管理權限 'typeadmin'=>'1', //是否允許檢視需要驗證的帖子 'viewcheck'=>'1', //是否允許檢視關閉帖子 'viewclose'=>'1', //是否允許檢視附件(4.0以前) 'attachper'=>'0', //是否允許刪除附件 'delattach'=>'1', //是否允許檢視IP 瀏覽帖子時顯示 0無1全部板塊2所管理板塊 'viewip'=>'1', //是否開啟評分權限(4.0以前) 'markable'=>'0', //評分最大值(4.0以前) 'maxcredit'=>'0', //評分類型(4.0以前) 'credittype'=>'', //評分限制(4.0以前) 'creditlimit'=>'', //是否開啟會員禁言權限 'banuser'=>'1', //是否允許永久禁言 'bantype'=>'1', //禁言時間限制 封禁會員的最大天數 'banmax'=>'30', //是否允許檢視加密帖(隱藏,加密,出售) 'viewhide'=>'1', //是否允許灌水 不受灌水時間限制 'postpers'=>'1', //發表的文章是否需要管理員審核(4.0以前) 'atccheck'=>'0', //是否允許回復鎖定帖 'replylock'=>'1', //是否允許刪除自己的帖子(4.0以前) 'modown'=>'0', //是否允許刪除單一帖子(包括回復) 'modother'=>'1', //是否允許編輯帖子 編輯用戶帖子 'deltpcs'=>'1', //置頂權限 0無1版塊置頂2版塊置頂,分類置頂3版塊置頂,分類置頂,總置頂 'topped'=>'3', //是否允許進行主題分類管理 主題分類批量管理權限 'tpctype'=>'1', //是否允許進行主題驗證管理 前台主題驗證管理權限 'tpccheck'=>'1', ); ?> [Copy to clipboard] require\checkpass.php CODE: <?php //此文件內容為密碼檢測退出等代碼 //禁止直接訪問此文件,若直接訪問直接退出顯示Forbidden !function_exists('readover') && exit('Forbidden'); //退出論壇函數 function Loginout(){ //聲明全局變數資料庫訪問類$db,當前時間$timestamp,線上用戶時限$db_onlinetime,用戶組id$groupid,用戶登入id$windid,用戶id$winduid,COOKIE有效目錄$db_ckpath,COOKIE有效域名$db_ckdomain global $db,$timestamp,$db_onlinetime,$groupid,$windid,$winduid,$db_ckpath,$db_ckdomain; //這次訪問時間為當前時間與線上用戶時限1.5倍的差 $thisvisit=$timestamp-$db_onlinetime*1.5; //更新資料庫中用戶這次訪問時間訊息 $db->update("UPDATE pcr_memberdata SET thisvisit='$thisvisit' WHERE uid='$winduid' "); //取得cookie中設置訊息ck_info,以"\t"分割存入$db_ckpath,$db_ckdomain list($db_ckpath,$db_ckdomain)=explode("\t",GetCookie('ck_info')); //銷毀cookie winduser Cookie('winduser','',0); //銷毀cookie hideid Cookie('hideid','',0); //銷毀cookie lastvisit Cookie('lastvisit','',0); //銷毀cookie pwdcheck foreach(GetCookie('pwdcheck') as $key=>$val){ Cookie("pwdcheck[$key]",'',0); } //銷毀cookie ck_info Cookie('ck_info','',0); } //向資料庫更新某會員這次登入ip訊息 function Loginipwrite($winduid){ //聲明全局變數資料庫訪問類$db,當前時間$timestamp,客戶端ip$onlineip global $db,$timestamp,$onlineip; //按格式記錄登入ip訊息 $logininfo="$onlineip|$timestamp|6"; //更新資料庫中上次訪問時間為這次訪問時間,這次防衛時間為當前時間,線上ip情況 $db->update("UPDATE pcr_memberdata SET lastvisit=thisvisit,thisvisit='$timestamp',onlineip='$logininfo' WHERE uid='$winduid' "); } //檢查用戶名和密碼匹配情況 function checkpass($username,$password){ //聲明全局變數資料庫訪問類$db,當前時間$timestamp,客戶端ip$onlineip,COOKIE有效目錄$db_ckpath,COOKIE有效域名$db_ckdomain global $db,$timestamp,$onlineip,$db_ckpath,$db_ckdomain; //取資料庫記錄存入數組$men中,索引包括用戶id,用戶密碼,用戶組id,是否已啟動,線上ip訊息 $men=$db->get_one("SELECT m.uid,m.password,m.groupid,m.yz,md.onlineip FROM pcr_members m LEFT JOIN pcr_memberdata md ON md.uid=m.uid WHERE username='$username'"); //該用戶存在 if($men){ //以"|"分割用戶線上ip $e_login=explode("|",$men['onlineip']); //如果登入ip不等於$onlineip.' *'或者當前時間離上次登入超過600s或者密碼重試次數大於1 if($e_login[0]!=$onlineip.' *' || ($timestamp-$e_login[1])>600 || $e_login[2]>1 ){ $men_uid=$men['uid']; $men_pwd=$men['password']; $check_pwd=$password; //判斷用戶是否啟動 if($men['yz'] > 2){ //轉網頁面顯示語言文件中login_jihuo對應鍵值的提示訊息 Showmsg('login_jihuo'); } if(strlen($men_pwd)==16){ $check_pwd=substr($password,8,16);/*支持 16 位 md5截取密碼*/ } if($men_pwd==$check_pwd){ if(strlen($men_pwd)==16){ //更新資料庫中用戶密碼訊息 $db->update("UPDATE pcr_members SET password='$password' WHERE uid='$men_uid'"); } //記錄用戶組id訊息 $L_groupid=(int)$men['groupid']; //設置COOKIE有效目錄$db_ckpath,COOKIE有效域名$db_ckdomain相關cookie Cookie("ck_info",$db_ckpath."\t".$db_ckdomain); }else{ //聲明全局變數還剩多少次密碼嘗試機會 global $L_T; $L_T=$e_login[2]; $L_T ? $L_T--:$L_T=5; $F_login="$onlineip *|$timestamp|$L_T"; //更新相應用戶的線上ip情況 $db->update("UPDATE pcr_memberdata SET onlineip='$F_login' WHERE uid='$men_uid'"); //轉網頁面顯示語言文件中login_pwd_error對應鍵值的提示訊息 Showmsg('login_pwd_error'); } }else{ //超過密碼錯誤嘗試次數,該ip不允許在600s再次嘗試 //聲明全局變數距離下次可嘗試密碼的剩餘時間$L_T global $L_T; $L_T=600-($timestamp-$e_login[1]); //轉網頁面顯示語言文件中login_forbid對應鍵值的提示訊息 Showmsg('login_forbid'); } } else { //聲明全局變數錯誤登入名$errorname global $errorname; $errorname=$username; //轉網頁面顯示語言文件中user_not_exists對應鍵值的提示訊息 Showmsg('user_not_exists'); } //返回數組訊息包括用戶id,用戶組id,編碼後的密碼訊息 return array($men_uid,$L_groupid,PwdCode($password)); } ?> [Copy to clipboard] require\db_mysql.php CODE: <?php //此文件內容為資料庫訪問相關公用函數 //禁止直接訪問此文件,若直接訪問直接退出顯示Forbidden !function_exists('readover') && exit('Forbidden'); //定義整個資料庫訪問類DB Class DB { //查詢次數變數 var $query_num = 0; //構造函數,建立與資料庫的連接 function DB($dbhost, $dbuser, $dbpw, $dbname, $pconnect = 0) { $this->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect); } //連接資料庫函數 function connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect = 0) { //mysql_connect -- 打開一個到 MySQL 服務器的連接 //mysql_pconnect -- 打開一個到 MySQL 服務器的持久連接 //mysql_pconnect() 和 mysql_connect() 非常相似,但有兩個主要區別。 //首先,當連接的時候本函數將先嘗試尋找一個在同一個主機上用同樣的用戶名和密碼已經打開的(持久)連接,如果找到,則返回此連接標識而不打開新連接。 //其次,當腳本執行完畢後到 SQL 服務器的連接不會被關閉,此連接將保持打開以備以後使用(mysql_close() 不會關閉由 mysql_pconnect() 建立的連接)。 //判斷是否開啟持久連接設置,開啟則使用持久連接,未開啟則使用一般連接 $pconnect==0 ? @mysql_connect($dbhost, $dbuser, $dbpw) : @mysql_pconnect($dbhost, $dbuser, $dbpw); //mysql_errno -- 返回上一個 MySQL 操作中的錯誤訊息的數位編碼 //如果返回錯誤代碼,則資料庫掛起輸出錯誤訊息 mysql_errno()!=0 && $this->halt("Connect($pconnect) to MySQL ($dbhost,$dbuser) failed"); //如果資料庫版本大於4.1且全局變數中字元集參數不為空 if($this->server_info() > '4.1' && $GLOBALS['charset']){ //mysql_query -- 發送一條 MySQL 查詢 //設置NAMES參數為相應字元集參數值,避免PHP讀取mysql資料庫時出現中文亂碼 mysql_query("SET NAMES '".$GLOBALS['charset']."'"); } //如果資料庫版本大於5.0 if($this->server_info() > '5.0'){ //設置sql_mode參數為空 mysql_query("SET sql_mode=''"); } //如果資料庫名存在 if($dbname) { //mysql_select_db -- 選擇 MySQL 資料庫 //如果選擇資料庫未成功 if (!@mysql_select_db($dbname)){ //資料庫掛起,輸出錯誤訊息 $this->halt('Cannot use database '.$dbname); } } } //關閉資料庫函數 function close() { //mysql_close -- 關閉 MySQL 連接 return mysql_close(); } //選擇資料庫函數 function select_db($dbname){ if (!@mysql_select_db($dbname)){ $this->halt('Cannot use database '.$dbname); } } //資料庫訊息函數 function server_info(){ //mysql_get_server_info -- 取得 MySQL 服務器版本訊息 return mysql_get_server_info(); } //查詢資料庫函數 function query($SQL,$method='') { //如果表區分符設置的不是pcr_則替換sql語句中的pcr_為相應的表區分符 $GLOBALS['PW']=='pcr_' or $SQL=str_replace('pcr_',$GLOBALS['PW'],$SQL); //mysql_unbuffered_query -- 向 MySQL 發送一條 SQL 查詢,並不獲取和快取記憶體結果的行 //mysql_unbuffered_query() 向 MySQL 發送一條 SQL 查詢 query,但不像 mysql_query() 那樣自動獲取並快取記憶體結果集。一方面,這在處理很大的結果集時會節省可觀的記憶體。另一方面,可以在獲取第一行後立即對結果集進行操作,而不用等到整個 SQL 語句都執行完畢。 //如果傳入的方法參數為U_B且函數mysql_unbuffered_query存在,則 if($method=='U_B' && function_exists('mysql_unbuffered_query')){ $query = mysql_unbuffered_query($SQL); }else{ $query = mysql_query($SQL); } //查詢次數+1 $this->query_num++; //echo $SQL.'<br>'.$this->query_num.'<br>'; //如果沒有查詢結果,則資料庫掛起輸出錯誤訊息 if (!$query) $this->halt('Query Error: ' . $SQL); //返回查詢結果資源 return $query; } //讀取一條資料記錄函數 function get_one($SQL){ $query=$this->query($SQL,'U_B'); //mysql_fetch_array -- 從結果集中取得一行作為關聯數組,或數位數組,或二者兼有 //mysql_fetch_array() 中可選擇的第二個參數 result_type 是一個常量,可以接受以下值:MYSQL_ASSOC,MYSQL_NUM 和 MYSQL_BOTH。 //MYSQL_ASSOC 返回的資料列使用字段名作為數組的索引名。 //MYSQL_BOTH 返回的資料列使用字段名及數位索引作為數組的索引名。 //MYSQL_NUM 返回的資料列使用數位索引作為數組的索引名。索引從 0 開始,表示返回結果的第一個字段。 $rs =& mysql_fetch_array($query, MYSQL_ASSOC); //返回結果數組 return $rs; } //連帶更新函數 function pcr_update($SQL_1,$SQL_2,$SQL_3){ //取$SQL_1執行得到的數組 $rt=$this->get_one($SQL_1); //若得到的數組不為空 if($rt){ //更新執行$SQL_2 $this->update($SQL_2); } else{ //更新執行$SQL_3 $this->update($SQL_3); } } //更新資料庫函數 function update($SQL) { //如果表區分符設置的不是pcr_則替換sql語句中的pcr_為相應的表區分符 $GLOBALS['PW']=='pcr_' or $SQL=str_replace('pcr_',$GLOBALS['PW'],$SQL); //如果開啟工作行程優化 if($GLOBALS['db_lp']==1){ //如果你指定關鍵詞 LOW_PRIORITY,執行將被延遲,直到沒有其它的客戶端正在讀取表。 //給更新命令加上 LOW_PRIORITY關鍵字 if(substr($SQL,0,7)=='REPLACE'){ $SQL=substr($SQL,0,7).' LOW_PRIORITY'.substr($SQL,7); } else{ $SQL=substr($SQL,0,6).' LOW_PRIORITY'.substr($SQL,6); } } if(function_exists('mysql_unbuffered_query')){ $query = mysql_unbuffered_query($SQL); }else{ $query = mysql_query($SQL); } //查詢次數+1 $this->query_num++; //echo $SQL.'<br>'.$this->query_num.'<br>'; //如果沒有結果,則資料庫掛起輸出錯誤訊息 if (!$query) $this->halt('Update Error: ' . $SQL); //返回結果資源 return $query; } //從結果集中取得結果數組,根據參數決定數組索引 function fetch_array($query, $result_type = MYSQL_ASSOC) { return mysql_fetch_array($query, $result_type); } //返回影響記錄數 function affected_rows() { //mysql_affected_rows -- 取得前一次 MySQL 操作所影響的記錄行數 return mysql_affected_rows(); } //返回結果集行數 function num_rows($query) { //mysql_num_rows -- 取得結果集中行的數目 $rows = mysql_num_rows($query); return $rows; } //釋放結果記憶體 function free_result($query) { //mysql_free_result -- 釋放結果記憶體 //mysql_free_result() 僅需要在考慮到返回很大的結果集時會佔用多少記憶體時調用。在腳本結束後所有關聯的記憶體都會被自動釋放。 return mysql_free_result($query); } //取得操作產生的id function insert_id() { //mysql_insert_id -- 取得上一步 INSERT 操作產生的 ID $id = mysql_insert_id(); return $id; } //資料庫掛起函數,並輸出相應錯誤訊息 function halt($msg='') { //包含require/db_mysql_error.php文件,如果其中有重複包含,略過 require_once(R_P.'require/db_mysql_error.php'); //輸出資料庫錯誤提示訊息 new DB_ERROR($msg); } } ?> [Copy to clipboard] require\userglobal.php CODE: <?php //此文件內容為用戶相關公用函數 //禁止直接訪問此文件,若直接訪問直接退出顯示Forbidden !function_exists('readover') && exit('Forbidden'); //檢查文件相應偏移是否存在某值 function checkinline($filename,$offset,$keyword) { //聲明全局變數線上列表大小值$db_olsize global $db_olsize; //如果偏移值為空,或者偏移值不能被$db_olsize+1整除,返回0 if(!$offset || $offset%($db_olsize+1)!=0) return 0; //以讀方式打開相應文件 $fp=fopen($filename,"rb"); //設置共享鎖 flock($fp,LOCK_SH); //定位到相應偏移 fseek($fp,$offset); //從該偏移處讀取$db_olsize大小的資料存入$Checkdata $Checkdata=fread($fp,$db_olsize); //關閉文件 fclose($fp); //查找文件中是否含有相關關鍵字 if(strpos("\n".$Checkdata,"\n".$keyword."\t")!==false){ return 1; }else{ return 0; } } //取得文件的可插入偏移值 function GetInsertOffset($filename){ //聲明全局變數線上列表大小值$db_olsize,登入用戶id $windid,客戶端ip $onlineip global $db_olsize,$windid,$onlineip; //設置初始偏移 $N_offset=0; //判斷是否需要修改 $isModify=1; //以只讀方式打開相應文件 $fp=fopen($filename,"rb"); //設置共享鎖 flock($fp,LOCK_SH); //當文件指針還未移到文件末尾時循環 while(feof($fp)===false){ //從文件中讀取($db_olsize+1)*2000大小(即2000份)的資料存入$Checkdata $Checkdata=fread($fp,($db_olsize+1)*2000); //如果登入用戶id不為空,且$Checkdata中有找到的登入用戶id,則將該位置記錄為偏移值 if($windid && $offset=strpos("\n".$Checkdata,"\n".$windid."\t")){ //$windid通過安全驗證 //無須修改 $isModify=0; //取得真實偏移值 $offset+=$N_offset; break; //如果登入用戶id為空,且$Checkdata中有找到的客戶端ip,則將該位置記錄為偏移值 }elseif(!$windid && $offset=strpos("\n".$Checkdata,"\n".$onlineip."\t")){ //$windid通過安全驗證 //無須修改 $isModify=0; //取得真實偏移值 $offset+=$N_offset; break; //str_pad 填充字元串到指定長度 //以上兩者均不符合即均找不到的話,若$padfp為空,查找$Checkdata中空行位置,並記錄該偏移值到$padfp }elseif(!$padfp && $padfp=strpos($Checkdata,str_pad(" ",$db_olsize-1)."\n")){ //取得真實空行偏移值 $padfp+=$N_offset-1; //$padfp=$offset; //break; } //ftell -- 返回文件指針讀/寫的位置 //設置下一輪初始偏移為此輪最後偏移 $N_offset=ftell($fp); } //若偏移量$offset為空 if(!$offset){ //當空行可以找到時,設置其為空行的偏移,否則即為文件末尾偏移 $offset=$padfp ? $padfp : $N_offset; } //關閉相應文件,銷毀$Checkdata fclose($fp); unset($Checkdata); //返回數組,包括可插入偏移值及是否需要修改 return array($offset,$isModify); } //在線上列表文件的指定偏移處插入會員id function addonlinefile($offset,$uid) { //聲明全局變數用戶登入id($windid),用戶組id($groupid),用戶上次訪問時間($lastvisit),當前時間($timestamp),客戶端ip($onlineip),線上用戶時限($db_onlinetime),板塊id($fid),帖子id($tid),論壇動作($wind_in),今天的起始時間$tdtime,線上列表大小值($db_olsize),是否統計今日到訪會員($db_today) global $windid,$groupid,$lastvisit,$timestamp,$onlineip,$db_onlinetime,$fid,$tid,$wind_in,$tdtime,$db_olsize,$db_today; if (strlen($fid)>4)$fidwt='';else $fidwt=$fid; if (strlen($tid)>7)$tidwt='';else $tidwt=$tid; //取得用戶動作賦於$wherebbsyou $wherebbsyou=getuseraction($fid,$wind_in); //按格式取當前時間真實值 $acttime=get_date($timestamp,'m-d H:i'); //設置線上文件為data/bbscache/online.php $D_name="data/bbscache/online.php"; //取hideid即是否隱身狀態cookie //非隱身 if(GetCookie('hideid')!=1){ //線上訊息 登入id 當前時間 客戶端ip 板塊id 帖子id 用戶組id 用戶當前動作 當前時間真實值 用戶id $newonline="$windid\t$timestamp\t$onlineip\t$fidwt\t$tidwt\t$groupid\t$wherebbsyou\t$acttime\t$uid\t"; //補齊字長 $newonline=str_pad($newonline,$db_olsize)."\n"; //檢查是否已經存在於online文件中,存在則 if(checkinline(D_P.$D_name,$offset,$windid)){ //無須修改 $isModify=0; //將新的線上訊息寫入data/bbscache/online.php文件中的相應偏移處 writeinline(D_P.$D_name,$newonline,$offset); } else{ //取得data/bbscache/online.php文件可插入偏移地址 list($offset,$isModify)=GetInsertOffset(D_P.$D_name); writeinline(D_P.$D_name,$newonline,$offset); } //如果允許統計今日到訪會員並且上次訪問時間與當前時間差大於設定的線上用戶時限 if ($db_today && $timestamp-$lastvisit>$db_onlinetime) { //包含require/today.php文件,如果其中有重複包含,略過 require_once(R_P.'require/today.php'); } //隱身 }elseif(GetCookie('hideid')==1){ //包含require/hidden.php文件,如果其中有重複包含,略過 require_once(R_P.'require/hidden.php'); } //如果需要修改 if($isModify===1){ //頻度可控制性 //修改data/bbscache/guest.php文件 ModifySelectFile(D_P."data/bbscache/guest.php"); } //返回插入偏移量,是否修改 return array($offset,$isModify); } //在線上遊客列表文件的指定偏移處插入遊客訪問訊息 function addguestfile($offset) { //聲明全局變數當前時間($timestamp),客戶端ip($onlineip),帖子id($tid),板塊id($fid),論壇動作($wind_in),線上列表大小值($db_olsize) global $timestamp,$onlineip,$tid,$fid,$wind_in,$db_olsize; if (strlen($fid)>4)$fidwt='';else $fidwt=$fid; if (strlen($tid)>7)$tidwt='';else $tidwt=$tid; //取得用戶動作賦於$wherebbsyou $wherebbsyou=getuseraction($fid,$wind_in); //按格式取當前時間真實值 $acttime=get_date($timestamp,'m-d H:i'); //線上訊息 客戶端ip 當前時間 板塊id 帖子id 用戶當前動作 當前時間真實值 $newonline="$onlineip\t$timestamp\t<FiD>$fidwt\t$tidwt\t$wherebbsyou\t$acttime\t";//<FiD>主要用於thread.php裡快速找到指定的版塊遊客 //補齊字長 $newonline=str_pad($newonline,$db_olsize)."\n"; //設置線上文件為data/bbscache/guest.php $D_name="data/bbscache/guest.php"; //檢查是否已經存在於guest文件中,存在則 if(checkinline(D_P.$D_name,$offset,$onlineip)){ //無須修改 $isModify=0; //將新的線上訊息寫入data/bbscache/guest.php文件中的相應偏移處 writeinline(D_P.$D_name,$newonline,$offset); } else{ //取得data/bbscache/guest.php文件可插入偏移地址 list($offset,$isModify)=GetInsertOffset(D_P.$D_name); writeinline(D_P.$D_name,$newonline,$offset); } //如果需要修改 if($isModify===1){ //頻度可控制性 //修改data/bbscache/online.php文件 ModifySelectFile(D_P."data/bbscache/online.php"); //若線上會員數為0 if($GLOBALS['userinbbs']===0){ //設置線上會員數為-1 $GLOBALS['userinbbs']--; //修改data/bbscache/guest.php文件,且延遲設為1 ModifySelectFile(D_P.$D_name,1); } } //返回插入偏移量,是否修改 return array($offset,$isModify); } //在文件指定偏移處寫入相應內容 function writeinline($filename,$data,$offset) { //以讀寫方式打開相應文件 $fp=fopen($filename,"rb+"); //取得獨佔鎖定 flock($fp,LOCK_EX); //定位到相應偏移 fseek($fp,$offset); //在該偏移處寫入相應內容 fwrite($fp,$data); //關閉該文件 fclose($fp); } //編輯選擇的文件,更新線上人數,線上遊客數,線上會員數 function ModifySelectFile($filename,$deny=0) { //聲明全局變數線上列表大小值$db_olsize,當前時間$timestamp,線上用戶時限$db_onlinetime,客戶端ip$onlineip,線上遊客數$guestinbbs,線上會員數$userinbbs; global $db_olsize,$timestamp,$db_onlinetime,$onlineip,$guestinbbs,$userinbbs; //判斷傳入的文件參數是否為D_P."data/bbscache/guest.php",如果是遊客則數組索引定為0,如果不是則數組索引定為2 $array_bit = $filename===D_P."data/bbscache/guest.php" ? 0 : 2; //設定定長空行 $addnbsp=str_pad(" ",$db_olsize)."\n"; //設定定長首行 $addfb=str_pad("<?die;?>",$db_olsize)."\n"; //設定分割長度,步數,線上人數,線上時間定義為當前時間與論壇允許的線上時限差即$db_onlinetime時間前有活動的會員或遊客納入計算範圍 $cutsize=$db_olsize+1;$step=$olnum=0;$onlinetime=$timestamp-$db_onlinetime; $A_offset=array(); //以只讀方式打開文件 $fp=fopen($filename,"rb"); //設置共享鎖 flock($fp,LOCK_SH); //定位指針到文件末尾 fseek($fp,0,SEEK_END); //ftell -- 返回文件指針讀/寫的位置 //當返回的文件指針大於分割大小(也就是至少還有一份資料)且步數少於20000(最多取20000份資料),循環 while(ftell($fp)>$cutsize && $step<20000){ $step++; //設置此次偏移值 $offset=-($cutsize*$step); //從文件尾部開始定位指針到偏移處 fseek($fp,$offset,SEEK_END); //從指針處讀取42字節訊息存入$line $line=fread($fp,42); //empty -- 檢查一個變數是否為空 if(empty($end)){ //如果$line含"\t"或者現在的文件指針值小等於$cutsize if(strpos($line,"\t")!==false || ftell($fp)<=$cutsize){ //記錄當前的偏移值為結束值 $end=$offset; } } //如果$line含"\t" if(strpos($line,"\t")!==false){ $detail=explode("\t",$line); //如果線上時間早於$db_onlinetime時間前或者客戶端ip匹配且$deny參數為0 if($detail[1]<$onlinetime || ($detail[$array_bit]===$onlineip && $deny==0)){ //偏移值計入偏移數組 $A_offset[]=$offset; } else{ //線上人數增加1個 $olnum++; } } } fclose($fp); //以讀寫方式打開文件 $fp=fopen($filename,"rb+"); //設置獨佔鎖 flock($fp,LOCK_EX); //在文件開頭寫入首行訊息 fwrite($fp,$addfb); //對偏移數組中的每個值 foreach($A_offset as $value){ //從尾部定位到該偏移後,寫入空行 fseek($fp,$value,SEEK_END);fwrite($fp,$addnbsp); } //isset -- 檢測變數是否設置 //ftruncate -- 將文件截斷到給定的長度 if(isset($end)) ftruncate($fp,filesize($filename)+$end+$cutsize); fclose($fp); //包含data/bbscache/olcache.php文件,如果其中有重複包含,略過 include_once(D_P.'data/bbscache/olcache.php'); //若修改遊客文件 if($filename===D_P."data/bbscache/guest.php"){ //線上遊客人數等於線上人數 $guestinbbs=$olnum; //線上會員數+1 $userinbbs++; }else{ //線上會員人數等於線上人數 $userinbbs=$olnum; //線上遊客數+1 $guestinbbs++; } //記錄線上會員和線上遊客訊息 $olcache="<?php\n\$userinbbs=$userinbbs;\n\$guestinbbs=$guestinbbs;\n?>"; //寫入到data/bbscache/olcache.php文件中 writeover(D_P.'data/bbscache/olcache.php',$olcache); } //取得用戶動作 function getuseraction($id,$action) { //聲明全局變數板塊訊息$forum global $forum; //包含對應風格目錄下的lang_action.php語言文件,如果其中有重複包含,略過 require_once GetLang('action'); //包含data/bbscache/forum_cache.php文件,如果其中有重複包含,略過 include_once(D_P.'data/bbscache/forum_cache.php'); //取得相應板塊名稱 $name=$forum[$id]['name']; //若名稱不為空 if($name){ //preg_replace -- 執行正則表達式的搜索和替換 $name=preg_replace("/\<(.+?)\>/is","",$name); //取前13位返回 return substrs($name,13); //取如果動作不為空 } elseif($action){ //若該動作在語言文件中的對應值存在 if($lang[$action]){ //返回該動作中文說明 return $lang[$action]; } else{ //返回論壇首頁說明 return $lang['hm']; } }else{ //返回論壇首頁說明 return $lang['hm']; } } ?> [Copy to clipboard] |
__________________ |
|
送花文章: 3,
|