程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> 深入PHP許願牆模塊功能分析

深入PHP許願牆模塊功能分析

編輯:PHP綜合
許願牆模塊功能分析
一,熱點技術
1,實現可拖放DOM技術移動許願字條
可拖放DOM模式(Draggable DOM pattern)的宗旨在於允許浏覽者自己定義頁面中各元素的位置,並且,只需要用鼠標選中要移動的部分,把它拖到新的位置上,就可以定制頁面。

DOM是Document Object Model文檔對象模型的縮寫,是一種與浏覽器、平台、語言無關的接口,使用戶可以訪問頁面其他的標准組件。DOM是以層次結構組織的節點或信息片段的集合。這個層次結構允許開發人員在樹中導航尋找特定信息。分析該結構通常需要加載整個文檔的構造層次結構,然後才能做任何工作。由於它基於信息層次,因此DOM被認為基於樹或基於對象。
具體實現時以下時間會被觸發:
(1)moveStart
(2)Move
(3)moveEnd
當按下鼠標左鍵,開始移動鼠標時,在被拖動的許願條上就會觸發moveStart事件。用戶可以使用moveStart事件處理函數在拖動開始時允許javaScript代碼。當moveStart事件被觸發後,Move時間會一直觸發,只要對象還在被拖動,就一直觸發。當拖動停止時,則觸發moveEnd事件。
echo輸出許願條樣式布局,代碼如下:
復制代碼 代碼如下:
echo "
 <DIV class='".$pagecolor."'style='left:".$L."px;top:".$T."px;z-index:".$Z."' id='".$id."' onmousedown='Move(this,event)' ondblclick=Show(".$id.",'shadeDiv')>      
  <TABLE cellSpacing=0 cellPadding=0 border=0>
   <TBODY>
    <TR>
     <TD>
       <DIV class=shead>
         <span class='Num' >愛牆編號:".$id."   ".$sendtime." <a onclick='myClose(".$id.")'>×</span>
      </DIV>
     </TD>
    </TR>
    <TR>
     <TD>
       <DIV class=sbody><img src='".$face."' id='IconImg' style='float:left'>
        <span id='PickerSample'>".$Picker."</span><br>    <span id='ContentSample'>$content</span>
      </DIV>
       <DIV class=sbody >
       <H2><span id='authorSample'>".$author."</span></H2>
      </DIV>
      <DIV class=sbot align='right'>
       <br><a href='#' onclick='holdout(".$id.",".$hits.")''>[祝福你]</a> 福氣:<span id='fq_id".$id."'>".$hits."</span> <span id='QQSample'>QQ:<a href='http://wpa.qq.com/msgrd?uin=".$QQ."&Site=1&Menu=yes' title='單擊與他/她交談' target='_blank'>".$QQ."</a></span>
      </DIV>
     </TD>
    </TR>
   </TBODY>
  </TABLE>
 </DIV>";

當按下鼠標左鍵時,應用鼠標時間onmousedown觸發Move()函數
復制代碼 代碼如下:
var Layer='';
document.onmouseup=moveEnd;
document.onmousemove=moveStart;
var b;
var c;
function Move(Object,event){ //移動DIV許願字條
 Layer=Object.id;
 if(document.all){
  document.getElementById(Layer).setCapture();
  b=event.x-document.getElementById(Layer).style.pixelLeft; //設置左邊框
  c=event.y-document.getElementById(Layer).style.pixelTop; //設置右邊框
 }else if(window.captureEvents){
  window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
  b=event.layerX;  //返回時間對象相對於本體的橫坐標
  c=event.layerY;  //返回時間對象相對於本體的縱坐標
 }
 /**實現鼠標單擊字條時,字條置上**/
  document.getElementById(Layer).style.zIndex=iLayerMaxNum;
  iLayerMaxNum=iLayerMaxNum+1;
 /********************************/
}

document.all是文檔中所有標簽組成的一個數組變量,包括了文檔對象中的所有元素,這個數組可以訪問文檔中的所有元素。
語法:
document.all[i]
document.all[name]
document.all.tags[tagname]
說明:
all[]是一個多功能的類似數組的對象,它提供了對文檔中所有HTML元素的訪問。all[]數組源自於IE4並已經被很多其他浏覽器采用

all[]已經被Document接口的標准的getElementById()方法和getElementByTagName()方法以及Document對象的getElementByName()方法所取代。

all[]包含的元素保存了最初的順序,如果你知道他們在數組中的確切數字化位置,可以直接從數組中提取他們。然而,更為常見的是使用all[]數組,根據他們的HTML屬性name或id來訪問元素。如果元素擁有指定的name,將得到共享同一名稱的元素的一個數組。
document.all可以判斷浏覽器是否是IE
復制代碼 代碼如下:
 if(document.all){
  alert("is IE!");
 }

window.captureEvents()
window.captureEvents(event1 | event2 | eventN)
captureEvents()方法捕獲所有發生的事件類型,如果有多個事件發生,則用|豎線隔開;captureEvents()方法主要事件如下:
Event.ABORT
Event.BLUR
Event.CHANGE
Event.CLICK
Event.DBLCLICK
Event.DRAGDROP
Event.ERROR
Event.FOCUS
Event.KEYDOWN
Event.KEYPRESS
Event.KEYUP
Event.LOAD
Event.MOUSEDOWN
Event.MOUSEMOVE
Event.MOUSEOUT
Event.MOUSEOVER
Event.MOUSEUP
Event.MOVE
Event.RESET
Event.RESIZE
Event.SELECT
Event.SUBMIT
Event.UNLOAD
示例代碼:
復制代碼 代碼如下:
<html>
    <head>
    <title>Using window.captureEvents</title>
    <script language="JavaScript1.2">
    <!--
    var counter = 0;
    window.captureEvents(Event.CLICK)
    window.onclick = myClickHandler;
    function myClickHandler(){
  window.document.myForm.myText.handleEvent;
    }
    function changeText(){
  document.myForm.myText.value = counter++;
    }
    -->
    </script>
    </head>
    <body>
    <form name="myForm">
  <input type=TEXT size=2 value="" name="myText" onClick='changeText()'>
    </form>
    </body>
</html>

當鼠標移動時,觸發moveStart()函數,代碼如下:
復制代碼 代碼如下:
function moveStart(d){
 if(Layer!=''){  //如果圖層不為空
  if(document.all){
   document.getElementById(Layer).style.left=event.x-b; //設置左邊距
   document.getElementById(Layer).style.top=event.y-c;  //設置右邊距
  }else if(window.captureEvents){
   document.getElementById(Layer).style.left=(d.clientX-b)+"px";
   document.getElementById(Layer).style.top=(d.clientY-c)+"px";
  }
 }
}

應用DOM方法(document對象的getElementById方法)獲取包含許願字條layer層左邊距和上邊距的距離。b和c分別表示獲取Layer層的橫縱坐標。
clientX:檢索與窗口客戶區域有關的鼠標坐標的x坐標,屬性為只讀,沒有默認值。
clientY:檢索與窗口客戶區域有關的鼠標光標的y坐標,屬性為只讀,沒有默認值。
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft

各浏覽器通用屬性:
screenX:
鼠標在顯示屏幕上的坐標。
clientX:鼠標在頁面顯示區域的坐標。

特有屬性:(
注:IE和FF的定位有個1px的差別,實際上,IE的定位從0開始,FF的定位從1開始,FF永遠會比IE大1px,需要根據實際情況處理。)
pageX:FF特有,鼠標在頁面上的位置,從頁面左上角開始定位,這個可以很方便在整個頁面上進行定位,IE沒有直接替換的屬性。

layerX:FF特有,鼠標相對於“觸發事件的元素的層級關系中離該元素最近的,設置了position的父元素”的邊界的位置,從border的左上角開始定位,即如果這個父元素存在border,則坐標原點在border的左上角,而不是內容區域的左上角。

offsetX:IE特有,鼠標相對於“觸發事件的元素”的位置,從內容區域左上角開始定位,不是從border左上角開始!這個屬性比較好用,用來判斷鼠標點在一個元素中的哪個位置很方便,FF沒有直接替換的屬性。

x:
IE特有,跟layerX一個效果,可作為layerX的直接替換屬性。

offsetLeft:這個屬性不是事件對象的屬性,而是DOM對象所有的,該屬性表示的是DOM對象在“該DOM對象的層級關系中離該對象最近的,設置了position的父對象”中的位置,雖然話是這麼說的,但是不同的浏覽器效果不一樣,FF中嚴格按上述說明執行,但是在IE6/7中,這個屬性返回該DOM對象在其直接父對象中的位置,但是IE8改正了這個問題,不過IE8又有了一個新問題,其他的浏覽器都是從父對象的內容區域的左上角開始定位,IE8確是從父元素的border的左上角開始定位,由於測試環境為IETester中的IE8,不能排除是IETester的問題。
當鼠標抬起時,觸發moveEnd()函數,代碼如下:
復制代碼 代碼如下:
function moveEnd(d){
 if(Layer!=''){  //如果layer圖層不為空
  if(document.all){
   document.getElementById(Layer).releaseCapture();
   Layer=''; //將layer圖層設為空
  }else if(window.captureEvents){
   window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
   Layer=''; //將layer圖層設為空
  }
 }
}

在上面的代碼中,setCapture()函數的作用是將後續的mouse事件都發送給這個對象,releaseCapture()函數是將mouse事件返回,由document、window等對象來自行處理,這樣就保證了在拖動的過程中,不會由於經過了其他元素而受到干擾。另外,還有一個很重要的因素,在win32上,MOUSEMOVE的時間不是連續的,並不是每次移動一個像素的鼠標指針,就會發生一個MOUSEMOVE事件,Windows會周期性檢測鼠標指針的位置變化來產生MOUSEMOVE的事件。所以,如果是一個很小的頁面對象,例如一個直徑5像素的圓點,如果沒有setCapture和releaseCapture,那麼在按住鼠標之後,快速地移動鼠標,就有可能鼠標移動走了但小圓點還在原地,就是因為下一次的mousemove事件已經不再發給這個圓點對象了。

2,對QQ號文本框中禁止非數字字符輸入
在動態網站中,為了確保用戶輸入的文本或數值的有效性,必須對用戶輸入的數據加以驗證,確保數據的准確及安全性。本模塊禁止用戶向QQ文本框中輸入漢字或英文字符。
復制代碼 代碼如下:
<input name="QQ" type="text" id="QQ"
<SPAN style="WHITE-SPACE: pre"> </SPAN>onKeyUp="setQQ();if(/(^0+)/.test(value))value=value.replace(/^0*/, '')" 
<SPAN style="WHITE-SPACE: pre"> </SPAN>onKeyDown="setQQ();"    //鍵盤按下時觸發,比如按著1不放時,該函數生效
<SPAN style="WHITE-SPACE: pre"> </SPAN>onKeyPress="return event.keyCode>=48 && event.keyCode<=57;" size="16" maxlength="10"
<SPAN style="WHITE-SPACE: pre"> </SPAN>onpaste="var s=clipboardData.getData('text'); if(!/\D/.test(s))value=s.replace(/^0*/,'');
<SPAN style="WHITE-SPACE: pre"> </SPAN>return false;"
/>

上面代碼中,分別應用3個事件來控制QQ號輸入的值。
onKeyUp事件:事件會在鍵盤按鍵被松開時發生。如果是數字則可以添加到QQ號文本框中。
onKeyPress事件:事件會在鍵盤按鍵被按下並釋放一個鍵時發生。只允許用戶輸入0~9之間的數字。
onpaste事件:當用戶粘貼數據以便從系統剪切板向文檔傳送數據時在目標對象上觸發。當用戶向QQ號文本框中粘貼字符串時,只允許用戶粘貼數字串。
另外,應用isNaN()方法來驗證輸入的QQ號是否是數值型。
isNaN(num Value);
numvalue:是必選項,用來檢查是否為NaN的值。
當提交簽字許願字條時,將觸發checkForm()函數,應用document.getElementById()函數和表單字段的ID(QQ文本框的ID號為“QQ”)來直接獲取這個元素。應用isNaN()方法來驗證QQ號是否為數值型。
復制代碼 代碼如下:
function checkForm(){         //祝福內容
 if(isNaN(document.getElementById('QQ').value)){
  alert('您輸入的QQ號不是數值型,請重新輸入!');
  document.getElementById('QQ').focus();
  return false;
 }
}

常用文本框限制代碼:
代碼示例:
onkeyup="value=value.replace(/[^a-zA-Z]/g,'')"
說明:
replace(/[^a-zA-Z]/g,'')
其中有^為邏輯詞“非”,然後後面跟著a-zA-Z指的是英文字母大小寫范圍,“/g”表示用後面的''中的字符(當前為空)全局替換。
此句代碼的含義為:在文本框中只能輸入大寫或小寫字母,如果不是,則自動刪除。
常用輸入限制代碼:
只能輸入英文字母:
復制代碼 代碼如下:
 <input type="text" onkeyup="value=value.replace(/[^a-zA-Z]/g,'')"/>

只能輸入英文和數字:
復制代碼 代碼如下:
 <input type="text" onkeyup="value=value.replace(/[^0-9a-zA-Z]/g,'')"/>
 <input type="text" onkeyup="value=value.replace(/[\W]/g,'')"/>     \W匹配字母或數字或下劃線或漢字,\D表示匹配數字

只能輸入數字和x(用於身份證號的輸入) :
復制代碼 代碼如下:
 <input type="text" onKeyUp="value=value.replace(/[^\d|x]/g,'')" />   |後面的就是可以排除的非數字,可是一個范圍x-z

只能輸入數字
復制代碼 代碼如下:
 <input type="text" onKeyUp="value=value.replace(/[^\d]/g,'')" />  \D表示匹配數字,中文輸入法輸入時,存在後續表格不能輸入中文問題
 <input type="text" onKeypress="if(event.keyCode < 45 || event.keyCode >57) event.returnValue = false;">  不能輸入字母,但能輸入/.-等
 <INPUT TYPE="text" onkeyup="this.value=this.value.replace(/[^\d]/g,'')" onpaste="return false">  不能輸入數字,不允許粘貼
 <input name=txt1 onchange="if(/\D/.test(this.value)){alert('只能輸入數字');this.value='';}">
 <input onkeyup="if(isNaN(value))execCommand('undo')" onafterpaste="if(isNaN(value)) execCommand('undo')"> 但可以輸入空格,解決中文輸入法問題

只能輸入字母和漢字(還有一些非數字字符)
復制代碼 代碼如下:
 <input onkeyup="value=value.replace(/[\d]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[\d]/g,''))">

小數點後只能有最多兩位(數字,中文都可輸入),不能輸入字母和運算符號
復制代碼 代碼如下:
 <input onKeyPress="if((event.keyCode<48 || event.keyCode>57) && event.keyCode!=46 || /\.\d\d$/.test(value))event.returnValue=false">

3,限制紙條內容的長度
在簽寫許願內容時,通常需要限制用戶輸入文本的長度。在字符串長度的計算上,漢字是占兩個字符(漢字的寬度以及存儲所占的位置決定了一個漢字占兩個字符),而英文字母和數字都被識別為一個字符。在PHP中獲取字符串長度應用strlen()函數實現。但是在本模塊中,為了能夠實現統計許願內容所允許輸入的剩余字符數,這裡就要重新輸寫計算中英文數字混合字符串長度的函數。在簽寫許願內容時,實時限制字符數。
添加一個文本框,用來控制輸入祝福紙條內容剩余的字節數。
復制代碼 代碼如下:
<INPUT style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" readOnly maxLength=3 size=3 value=150 name=freeLength>

在上面的代碼中,應用“freeLength”來實時輸出祝福紙條內容所剩余的字符數。
添加一個編輯框用來輸入祝福紙條的內容,添加onkeydown和onkeyup事件來觸發javascript腳本自定義的函數textCounter(),用來限制該編輯輸入的字符數,最多輸入150個字符,如果許願內容大於150,則自動刪除,僅保留最大容量值。
復制代碼 代碼如下:
<textarea name="content" id="content" cols="66" rows="6"
 onkeydown="textCounter(this.form.content,this.form.freeLength,150)" 
 onkeyup="textCounter(this.form.content,this.form.freeLength,150)"
 onafterpaste="textCounter(this.form.content,this.form.freeLength,150)">
</textarea>

在上面的代碼中,textCounter()函數有3個參數值,第一個參數值“this.form.content”是指輸入的許願內容;第二個參數值“this.form.freeLength”是指允許輸入的許願內容字符數;第三個參數“150”是輸入許願內容的最大容量值。

應用javascript腳本自定義一個函數textCounter(),控制祝福內容不能超過150個字符,這裡需要注意的是,中英文所占的字節數不同。

DBCS是亞洲的字符集,包含ANSI(ANSI即ASCII碼值為0~255之間的字符)。DBCS使用1個或者2個字節來表示一個字符集,超過256個字符則占用兩個字節。當字符為ANSI時,存放於文件中只占用1個字節。如果非ANSI(大於256個字符),則占用兩個字節。因此,這裡就用三目運算符來分別計算英文數字和漢字所占用的字節數。當變量StrValue.charCodeAt(i)小於等於256時,按1個字節計算;大於256時按2個字節計算。
復制代碼 代碼如下:
function textCounter(field, countfield, maxlimit) {  //祝福內容限制在120個字符內
  var StrValue  = field.value;
   var ByteCount = 0;
 var StrLength = field.value.length;
 for (i=0;i<StrLength;i++){   //記算祝福文字個數,英文數字占1個字符,漢字占2個字
  ByteCount = (StrValue.charCodeAt(i)<=256) ? ByteCount + 1 : ByteCount + 2;
 }
 if(ByteCount<=maxlimit){
  strtemp=StrValue;
  document.getElementById('ContentSample').innerHTML = StrValue;
  countfield.value = maxlimit - ByteCount;
 }else{
  document.getElementById('content').innerHTML = strtemp;
 }
}

該函數只能限制顯示部分150字節,但是輸入框沒有現在,而且粘貼超過150字節時,顯示為空白。修改代碼如下:
復制代碼 代碼如下:
function textCounter(field, countfield, maxlimit) {  //祝福內容限制在150個字符內
  var StrValue  = field.value;
   var ByteCount = 0;
 var StrLength = field.value.length;
 var cutstr = '';
 for (i=0;i<StrLength;i++){   
  ByteCount = (StrValue.charCodeAt(i)<=256) ? ByteCount + 1 : ByteCount + 2; //記算祝福文字個數,英文數字占1個字符,漢字占2個字
        if( ByteCount<=maxlimit){
   cutstr = StrValue.substring(0,i+1); //如果輸入字符小於限制長度,截取當前輸入字符i+1為輸入字符個數
   strtemp = cutstr; 
        } else {
   cutstr=strtemp;  //否則截取最大輸入字符長度
  }
 }
 if(ByteCount<=maxlimit){
  document.getElementById('ContentSample').innerHTML = cutstr;  //輸出顯示內容
  countfield.value = maxlimit - ByteCount;
 }else{
  document.getElementById('content').value = cutstr;  //限制輸入框顯示內容
  document.getElementById('ContentSample').innerHTML = cutstr;  //輸出顯示內容
  countfield.value =0; //剩余字節數
 }
}

在上面的代碼中,“countfield.value”是用來計算輸入字符串剩余的字符數,並將該值賦給textCounter()函數的第2個參數值“this.form.freeLength”,以此來實時計算當前許願內容所允許輸入的字符數量。

4,PHP驗證碼類當前頁面校驗驗證碼輸入對與錯
當前頁面驗證輸入是否正確的方法Ajax,add.js
復制代碼 代碼如下:
function codecheck(){
 var getVcode = document.getElementById('checkcode').value; //獲取驗證碼輸入框的內容
 xmlhttp.open("get","codeChk.php?code="+getVcode,true);   //將驗證碼發送到codeChk.php頁面檢驗驗證碼是否正確
 xmlhttp.onreadystatechange=function(){ 
  if(xmlhttp.readyState==4)
  {
   if(xmlhttp.status==200)
   {
    var msg=xmlhttp.responseText;
    if(msg==1){
     document.getElementById("messageImg").src="images/dui.gif"; //驗證碼正確,輸出顯示正確圖片
     document.getElementById('txt_hyan').value = getVcode; 
    }else{
     document.getElementById("messageImg").src="images/cuo.gif"; //驗證碼錯誤,輸出顯示錯誤圖片
     document.getElementById('checkcode').focus();
     return false;
    }
   }
  }
 }
 xmlhttp.send(null);
}

codeChk.php驗證碼檢驗頁面
復制代碼 代碼如下:
<?php 
 session_start();
 require 'secoder.class.php';  //先把類包含進來,實際路徑根據實際情況進行修改。 
 $vcode = new YL_Security_Secoder();      //實例化一個對象 
 $code = $_GET['code'];
 echo $vcode->check($code);  //check($code)函數返回的是true或者false,返回true時,codeChk.php頁面輸出的是1,否則沒有輸出    
?>

secoder.class.php驗證碼類中的check($code)函數
復制代碼 代碼如下:
public static function check($code) {
 isset($_SESSION) || session_start();
 // 驗證碼不能為空
 if(empty($code) || empty($_SESSION[self::$seKey])) {
  return false;

 }
 // session 過期
 if(time() - $_SESSION[self::$seKey]['time'] > self::$expire) {
  unset($_SESSION[self::$seKey]);
  return false;
 }
 if(strtoupper($code) == $_SESSION[self::$seKey]['code']) {  //不區分大小寫比較
  return true;  
 }
 return false;

}

5,定義生成指定范圍的許願條隨機算法
本模塊需要生成一個指定范圍的隨機算法,用來顯示許願字條的顯示位置,以使每次展示在讀者眼前的都是不同的許願字條。本模塊主要應用rand()函數控制許願牆紙的顯示位置。
rand()函數用於產生一個隨機整數
語法:rand(min,max)
參數:min,max可選,規定隨機數產生的范圍
如果沒有提供可選參數 min 和 max,rand() 返回 0 到 RAND_MAX 之間的偽隨機整數。在某些平台下(例如 Windows)RAND_MAX 只有 32768。如果需要的范圍大於 32768,那麼指定 min 和 max 參數就可以生成大於 RAND_MAX 的數了,或者考慮用 mt_rand() 來替代它。
mt_rand() 使用 Mersenne Twister 算法返回隨機整數
語法:mt_rand(min,max)
如果沒有提供可選參數 min 和 max,mt_rand() 返回 0 到 RAND_MAX 之間的偽隨機數。很多老的libc的隨機數發生器具有一些不確定和未知的特性而且很慢。php的rand()函數默認使用libc隨機數發生器。mt_rand()函數是非正式用來替換它的。該函數用了Mersenne Twister中已知的特性作為隨機數發生器,它可以產生隨機數值的平均速度比libc提供的rand()快四倍。
隨機顯示許願牆紙的關鍵代碼如下:
復制代碼 代碼如下:
$T=rand(320,520);
$L=rand(5,790); 
$Z=$page_count;
$Z = $Z - 3;
echo "
 <DIV class='".$pagecolor."'style='left:".$L."px;top:".$T."px;z-index:".$Z.";' id='".$id."' onmousedown='Move(this,event)' ondblclick=Show(".$id.",'shadeDiv')>      
  <TABLE cellSpacing=0 cellPadding=0 border=0>
   <TBODY>
    <TR>
     <TD>
       <DIV class=shead>
         <span class='Num' >愛牆編號:".$id."   ".$sendtime." <a onclick='myClose(".$id.")'>×</span>
      </DIV>
     </TD>
    </TR>
    <TR>
     <TD>
       <DIV class=sbody><img src='".$face."' id='IconImg' style='float:left'>
        <span id='PickerSample'>".$Picker."</span><br>    <span id='ContentSample'>$content</span>
      </DIV>
       <DIV class=sbody >
       <H2><span id='authorSample'>".$author."</span></H2>
      </DIV>
      <DIV class=sbot align='right'>
       <br><a href='#' onclick='holdout(".$id.",".$hits.")''>[祝福你]</a> 福氣:<span id='fq_id".$id."'>".$hits."</span> <span id='QQSample'>QQ:<a href='http://wpa.qq.com/msgrd?uin=".$QQ."&Site=1&Menu=yes' title='單擊與他/她交談' target='_blank'>".$QQ."</a></span>
      </DIV>
     </TD>
    </TR>
   </TBODY>
  </TABLE>
 </DIV>";

6,解析IP獲取用戶所在城市
在PHP中,使用PHP預定義變量$_SERVER['REMOTE_ADDR']獲取客戶端的IP地址。然後將IP按照通用的算法將其解析成一個數字串(每個城市都有一個對應的數字串),通過這個數字串來確定查詢用戶所在的城市名稱。
在數據庫中,IP區域的存儲時一個數字串,並非實際的IP地址,這時就需要對客戶端或服務器端的IP轉換成指定數字串的格式,從而進行地域信息的查詢。
復制代碼 代碼如下:
$ip=getenv('REMOTE_ADDR');   //獲取客戶端IP地址
/********解釋IP區域***********/
$cip=cip($ip);
$csql="select * from tb_ip where (ip1<'".$cip."' and  ip2>'".$cip."') or (ip1=ip2 and ip2='".$cip."')";
//執行查詢
$res = $DB->fetch_one_array($csql);
$cip1=$res['country'];
if($cip1==""){
 $cip1="IP不詳";
}

二,實現過程
1,雙擊許願字條,該字條置頂顯示,並屏蔽整個頁面
當用戶雙擊許願字條後,該許願字條將置頂顯示,同時屏蔽整個頁面,以達到突出顯示的效果。
(1)控制DIV突顯效果,首頁設置一個隱藏的DIV,ID名稱為“shadeDiv”,代碼如下
<div style="display:none;" id="shadeDiv" onclick="Hide();"></div>
(2)應用Javascript腳本自定義一個Hide()函數,通過設置DIV的顯示屬性display設置為空,從而隱藏DIV,代碼如下:
復制代碼 代碼如下:
function Hide(){
 document.getElementById("shadeDiv").style.display = "none";
 iLayerMaxNum = iLayerMaxNum+2;
}

(3)在CSS樣式表中設置隱藏DIV的樣式。代碼如下:
#shadeDiv{filter:alpha(Opacity=55);opacity:0.35;background: #333;position:absolute;} //IE浏覽器下濾鏡效果,兼容性不好
(4)接下來,雙擊已經設計好的許願字條DIV圖層,代碼如下:
ondblclick=Show(".$id.",'shadeDiv')
(5)自定義一個函數show(),用來控制背景的效果。
復制代碼 代碼如下:
function Show(n,divName){
 document.getElementById(n).style.zIndex = iLayerMaxNum+1;
 document.getElementById(divName).style.display = "block";
 document.getElementById(divName).style.zIndex = iLayerMaxNum;
 var size = getPageSize(); //設置隱藏區域的面積,這裡是獲取許願牆顯示區域的面積,即本例中設置濾鏡的面積
 document.getElementById(divName).style.width = size[0]+"px"; 
 document.getElementById(divName).style.height = size[1]+"px";
}

(6)設置紙條顯示的區域,這裡得到的僅僅是數字
復制代碼 代碼如下:
function getPageSize(){
 var w =document.body.clientWidth;
 var h= document.body.clientHeight;
 arrayPageSize = new Array(w,h);
 return arrayPageSize;
}

2,應用Jpgraph圖形類庫實現3D餅形圖表按地域統計分析許願比率,實現過程如下:
(1)應用浮動框架技術實現不同類別下的地域統計分析結果,每一個黃顏色的版塊分別是一個浮動框架.浮動框架布局的代碼如下:
復制代碼 代碼如下:
<!----------------------------應用3D餅形圖按地域統計分析”全部“許願的比率---------------------------->
<div align="center">
    <IFRAME frameBorder=0 id=top name=top scrolling=no src="statistic_all.php" style="HEIGHT:290px;VISIBILITY:inherit;WIDTH:1004px;Z-INDEX:3">
    </IFRAME>
</div>
<!----------------------------應用3D餅形圖按地域統計分析”親情類“許願的比率---------------------------->
<div align="center">
 <IFRAME frameBorder=0 id=top name=top scrolling=no src="statistic_relative.php" style="VISIBILITY:inherit;WIDTH:330px;height:260px;Z-INDEX:3">
    </IFRAME>
</div>
<!----------------------------應用3D餅形圖按地域統計分析”愛情類“許願的比率----------------------------> 
<div align="center">
 <IFRAME frameBorder=0 id=top name=top scrolling=no src="statistic_love.php"    style="HEIGHT:90px;VISIBILITY:inherit;WIDTH:330px;height:260px;Z-INDEX: 3">
    </IFRAME>
</div>
<!----------------------------應用3D餅形圖按地域統計分析”友情類“許願的比率---------------------------->
<div align="center">
 <IFRAME frameBorder=0 id=top name=top scrolling=no src="statistic_friend.php" style="VISIBILITY:inherit;WIDTH:330px;height:260px;Z-INDEX:3">
 </IFRAME>
</div>
<!----------------------------應用3D餅形圖按地域統計分析”自己類“許願的比率---------------------------->
<div align="center">
 <IFRAME frameBorder=0 id=top name=top scrolling=no src="statistic_self.php" style="VISIBILITY:inherit;WIDTH:330px;height:260px;Z-INDEX:3">
 </IFRAME>
</div>
<!----------------------------應用3D餅形圖按地域統計分析”奧運會類“許願的比率---------------------------->
<div align="center">
 <IFRAME frameBorder=0 id=top name=top scrolling=no src="statistic_olympic.php" style="VISIBILITY:inherit;WIDTH:330px;height:260px;Z-INDEX:3">
 </IFRAME>
</div>
<!----------------------------應用3D餅形圖按地域統計分析”汶川類“許願的比率---------------------------->
<div align="center">
 <IFRAME frameBorder=0 id=top name=top scrolling=no src="statistic_wch.php" style="VISIBILITY:inherit;WIDTH:330px;height:260px;Z-INDEX:3">
 </IFRAME>
</div>

(2)應用3D餅形圖動態統計分析全部區域的許願比率
首先應用Jpgraph類庫實現圖表分析,需要應用include語句引用jpgraph.php文件。代碼如下:
復制代碼 代碼如下:
<?php
 include("global.php");  //鏈接數據庫源文件
 include("jpgraph/jpgraph.php");  //引用圖表分析類文件
?>

繪制餅形圖需要引用jpgraph_pie.php文件。繪制3D效果的餅形圖需要創建PiePlot3D類對象,PiePlot3D類在Jpgraph_pie3d.php中定義,需要應用include語句調用該文件。代碼如下:
復制代碼 代碼如下:
<?php
 include("jpgraph/jpgraph_pie.php");  //引用餅形圖類文件
 include_once("jpgraph/jpgraph_pie3d.php");  //引用3D餅圖PiePlot3D對象所在的類文件
?>

創建graph對象,生成一個990x276像素大小的畫布,設置統計圖所在畫布的位置以及畫布的陰影。設置標題的字體以及圖例的字體。設置餅形圖所在畫布的位置以及半徑,將繪制的3D餅形圖添加到圖像中。
復制代碼 代碼如下:
<?php
$graph = new PieGraph(990,276); //創建畫布
$graph->SetShadow(); //設置陰影
$graph->title->Set("應用3D餅形圖統計分析全部區域許願比率"); //設置標題名稱
$graph->title->SetFont(FF_SIMSUN,FS_BOLD); //設置標題的字體加粗
$graph->legend->SetFont(FF_SIMSUN,FS_NORMAL); //設置餅形圖文字的字體
$size=0.5; //設置餅形圖的半徑
/***********************統計全部許願比率*************************/
//創建餅形圖對象
$p0= new PiePlot3D($arraynum0); //創建餅形圖對象
$p0->SetLegends($arraycip0); 
$p0->SetSize($size); //設置餅形圖的大小
$p0->SetCenter(0.45,0.48); //設置餅形圖的坐標位置
$p0->SetLegends($arraycip0); //設置城市名稱
$p0->value->SetFont(FF_FONT0); //設置字體
$p0->title->SetFont(FF_SIMSUN,FS_BOLD);  //設置標題字體加粗
/*************************************************************/
$graph->Add($p0);  //添加3D餅形圖到圖像中
$graph->Stroke(); //輸出圖像
?>

(3)應用3D餅形圖動態統計分析”親情類“的許願比率。其實現方法與獲取全部的許願比率的方法基本類似,不同的是這裡在檢索親情類許願人數時設置了where查詢條件。另外在設置餅形圖的半徑和位置上稍微有變化。
復制代碼 代碼如下:
<?php
include("global.php"); //鏈接數據庫文件
include ("jpgraph/jpgraph.php"); //引用圖表分析類文件
include ("jpgraph/jpgraph_pie.php"); //引用餅形圖類文件
include_once ("jpgraph/jpgraph_pie3d.php");  //引用3D餅圖PiePlot3D對象所在的類文件
/***********************統計親情類別*************************/
$sql2="select distinct(count(cip)) as num,cip from tb_wishes where wishsort='親情' group by cip ";
$DB->query($sql2);  //動態統計親情類許願
$res2=$DB->get_rows_array($sql2); //生成二維數組
$rows_count2=count($res2);  //統計二維數組的數量
$arraynum2=array(); //聲明城市”親情類“許願總數數組
$arraycip2=array();  //聲明”親情類“城市名稱數組
//解析數組
for($k=0;$k<$rows_count2;$k++){
 array_push($arraynum2,$res2[$k][num]); //輸出城市的許願數量
 array_push($arraycip2,$res2[$k][cip]);  //輸出城市名稱
}
/*************************************************************/
//創建畫布
$graph = new PieGraph(320,246);  //創建畫布
$graph->SetShadow(); //設置陰影
$graph->title->Set("統計分析全部區域的[ 親情類 ] 許願比率");  //設置標題名稱
$graph->title->SetFont(FF_SIMSUN,FS_BOLD); //設置標題的字體加粗
$graph->legend->SetFont(FF_SIMSUN,FS_NORMAL); //設置餅形圖文字的字體
$size=0.3;  //設置餅形圖的半徑
/***********************統計親情許願比率*************************/
$p= new PiePlot3D($arraynum2); //創建餅形圖對象
$p->SetLegends($arraycip2);  //設置城市名稱
$p->SetSize($size);  //設置餅形圖的大小
$p->SetCenter(0.45,0.55); //設置餅形圖的坐標位置
$p->value->SetFont(FF_FONT0); //設置字體
$p->title->SetFont(FF_SIMSUN,FS_BOLD); //設置標題字體加粗
/*************************************************************/
$graph->Add($p); //添加3D餅形圖到圖像中
$graph->Stroke(); //輸出圖像
?>

3,許願牆列表,許願牆字條高級搜索功能的實現
為了便於訪客能更清晰地查看各種不同類別的許願字條,本模塊設計了愛牆列表和許願字條高級搜索功能。其中,愛牆列表時在默認狀態下檢索全部的許願字條,而高級搜索功能是按照訪客設置的一定的查詢條件來檢索與之匹配的許願字條。
設計愛牆列表及許願字條高級搜索的表單元素如下:
復制代碼 代碼如下:
<table width="1004" height="25" border="0" cellpadding="0" cellspacing="0">
 <form name="form" method="get" action="">
  <tr>
   <td align="center" bgcolor="#339933">請輸入查詢條件:
    <input type="text" name="content1" size="30" class="inputs"> 
    <select name="select">
    <option value="奧運會">奧運會</option>
    <option value="汶川">汶川</option>
    <option value="愛情">愛情</option>
    <option value="親情">親情</option>
    <option value="友情">友情</option>
    <option value="自己">自己</option>
    <option value="全部" selected="selected">全部</option>
    </select>
    <input type="submit" name="submit" value="檢索許願" class="btn_search">
     (支持多條件查詢,如:愛牆號、許願人、許願內容等) 
   </td>
       </tr>
    </form>
</table>

4,許願牆顯示效果如圖:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved