官术网_书友最值得收藏!

1.2 熱點關鍵技術

1.2.1 防SQL注入技術

SQL注入是指一些精通SQL語句的用戶,通過在表單或瀏覽器地址欄中輸入SQL語句來繞過系統檢驗的一種技術。一般防范SQL注入的手段是過濾敏感字符,例如引號等。

PHP相對于ASP來說,要安全得多。但這不代表PHP網站就不會出現SQL注入的情況。幸運的是,在PHP上防SQL注入,要比ASP簡單、方便,不需要寫一大段的轉換語句,只要幾個函數就可以了。

1.intval()函數

intval()函數的作用是返回變量的整數值,函數語法如下:

      int intval ( mixed var [, int base] )

2.addslashes()函數

addslashes()函數就是在操作數據庫時,對其中的特殊字符進行自動轉義,即在特殊字符前加上反斜線(\),包括單引號(' )、雙引號(")、NULL,但是不包括“%”和“_”。函數語法如下:

      string addslashes ( string str )

此外,還可以使用mysql_real_escape_string()來進行轉義,效果與addslashes()函數一樣。

1.2.2 Ajax無刷新驗證技術

Ajax(Asynchronous JavaScript and XML)即異步JavaScript和XML,是時下最流行的技術。Ajax不是新的技術,而是原有技術的集合,這從它的名字上就能夠看出來。

Ajax的核心技術是XMLHttpRequest。通過XMLHttpRequest中的open()方法和send()方法,可以在不刷新當前頁面的情況下向處理頁發送數據;通過XMLHttpRequest中的responseText屬性和responseXML屬性,可以得到處理頁的輸出結果。

Ajax能夠流行的原因,是因為它能為用戶提供良好的交互性,這個特性在本模塊中被充分地體現出來。注冊用戶無須經過“漫長”的等待就可以知道輸入的賬號是否可用,登錄用戶也不必擔心因為輸錯登錄信息而重新刷新整個頁面。

使用Ajax,一般分為下面幾步。

(1)創建XMLHttpRequest對象。不同的瀏覽器,創建XMLHttpRequest對象及使用的方法有一些差別,這里只針對IE瀏覽器進行創建,代碼如下:

      var xmlhttp = false;                                    //初始化變量
      //如果ActiveXObject存在,說明是IE 1.0以上的版本,否則使用XMLHttpRequest創建
      if(window.ActiveXObject){
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      }else if(window.XMLHttpReuqest){
            xmlhttp = new XMLHttpRequest();
      }

(2)對象創建成功后,就可以使用對象中的open()方法創建新請求了,方法格式如下:

      xmlhttp.open(rmethod, rurl, isAsync);

參數說明如下。

? rmethod:指明請求的方法,如get()或post()?

? rurl:指明請求的頁面??梢允墙^對地址,也可以是相對地址。

? isAsync:指明請求是否為異步。默認為True,即異步。

(3)如果isAsync等于True,那么當請求的狀態改變時,將調用onreadystatechange屬性,該屬性指定了一個回調函數,格式如下:

      xmlhttp.onreadystatechange = reabackfunc;

或者

      xmlhttp.onreadystatechange = function(){…}

(4)在回調函數中,首先需要判斷http的請求狀態和http狀態碼。這是通過readyState屬性和status屬性來判斷的。readyState屬性有5種狀態值,常用的是4,表示數據接收完畢。status屬性的值比較多,常用的是200,表示請求成功。一般使用這兩個屬性一起來判斷,格式如下:

      xmlhttp.onreadystatechange = function(){
            if(readyState == 4 and status == 200){
              …
            }
      }

(5)當響應頁處理結束后,即滿足了“readystate==4 and status == 200”這個條件,就可以使用XMLHttpRequest對象的屬性獲取響應頁的值了。常用的有responseText、responesXML、responseStream等,這里以responseText為例進行介紹。

responesText屬性是將響應頁的輸出信息作為字符串返回,格式如下:

      str = xmlhttp.responseText;

(6)最后使用send()方法來接收回應。send()方法可以傳遞數據,但這取決于open()方法中的rmethod參數,當參數為get時,數據是附在URL中進行傳遞的;當參數為post時,數據只能使用send()方法進行傳遞。send()方法的語法如下:

      xmlhttp.send([rdate]);

1.2.3 驗證碼技術

驗證碼技術是為了防止用戶名和密碼被暴力破解,在登錄頁面上生成一組隨機數,每次刷新頁面時,隨機數都會改變。一般是4位,也有更多位的。

1.獲取驗證碼

PHP中的驗證碼可以通過rand()函數生成隨機數的方式得到。rand()函數可以獲取指定范圍內的隨機數,該函數語法如下:

      int rand([int min, int max])

如果省略兩個參數,那么將返回0到RAND_MAX之間的隨機整數。否則,返回min和max之間的整數。例如本例中要獲取4位十六進制的整數,代碼如下:

      <? php
            for($i=0; $i<4; $i++){
              $num .= dechex(rand(0,15));               //生成隨機數
            }
            …
      ?>

函數dechex()可以將參數轉換為十六進制數表示。

使用JavaScript也可以生成十六進制隨機數,但是稍有些復雜。JavaScript中不能直接將十進制數轉換為十六進制數,需要手動進行轉換。首先使用Math.random()函數生成0~15的隨機數,然后使用Math.ceil()函數將隨機數取整,接下來就要逐次判斷該值,如果該值大于9,那么將10~15的數一一對應轉換為a、b、…、f。轉換完成后,將值累加,最后傳給valcode.php頁。

使用JavaScript生成十六進制隨機數的完整代碼如下:

      //生成隨機數
      function showval(){
            num = ' ' ;
            for(i=0; i<4; i++){                           //循環輸出4位驗證碼
              tmp = Math.ceil((Math.random() * 15)); //取得1位十六進制的整數
                    if(tmp > 9){                          //依次判斷隨機數
                        switch(tmp){
                          case(10):                       //如果隨機數等于10,則轉換為a
                              num += ' a' ;
                              break;
                          case(11):
                              num += ' b' ;               //如果隨機數等于11,則轉換為b
                              break;
                          case(12):
                              num += ' c' ;               //如果隨機數等于12,則轉換為c
                              break;
                          case(13):                       //如果隨機數等于13,則轉換為d
                              num += ' d' ;
                              break;
                          case(14):                       //如果隨機數等于14,則轉換為e
                              num += ' e' ;
                              break;
                          case(15):                       //如果隨機數等于15,則轉換為f
                              num += ' f' ;
                              break;
                        }
                    }else{
                        num += tmp;
                    }
            }
            $(' chkid' ).src=' valcode.php? num=' +num;   //將生成的隨機數傳給圖像生成頁
            $(' chknm' ).value = num;                     //將隨機數的值保存到頁面的隱藏域中
      }

2.顯示隨機數圖片

顯示隨機數的方法很多,將隨機數寫入一個圖片中再顯示是目前常用的方法。在PHP中,可以使用GD函數庫來實現。使用到的函數主要有imagecreate()函數、imagecolorallocate()函數、imagestring()函數、imagesetpixel()函數、imagepng()函數和imagedestroy()函數。

1)imagecreate()函數

imagecreate()函數用來創建一個基于調色板的空白圖像源,這是生成圖片的第一步,函數語法如下:

      resource imagecreate ( int width, int height )

其中,參數width和height分別指定了圖像的寬和高。

2)imagecolorallocate()函數

imagecolorallocate()函數可以為創建后的圖像分配顏色,函數語法如下:

      int imagecolorallocate ( resource image, int red, int green, int blue )

參數說明如下。

? image:一個圖像源。

? red、green和blue:表示紅、黃、藍三元素的成分,每種顏色的取值范圍在1~255。

3)imagestring()函數

圖像創建完成后,就可以使用imagestring()函數來添加圖像文字了,該函數的語法如下:

      bool imagestring ( resource image, int font, int x, int y, string s, int col )

參數說明如下。

? image:一個圖像源。

? font:可以設置字體,如果使用系統默認字體,則可以使用1~5的數字。

? x和y:分別表示文字相對于整幅圖像的x軸和y軸坐標,即所輸入的字符串的左上角坐標。

? s:要顯示的字符串。

? col:為字體顏色,也是使用imagecolorallocate()函數來分配的。

4)imagesetpixel()函數

使用imagecolorallocate()創建的是一個單一背景色的圖像,如果希望向圖像中添加干擾碼,則可以使用imagesetpixel()函數,該函數的作用是畫一個像素點,函數語法如下:

      bool imagesetpixel ( resource image, int x, int y, int color )

參數說明與imagestring()函數相似,這里不再贅述。

5)imagepng()函數

該函數將創建完成的圖片以png的格式輸出,函數語法如下:

      bool imagepng ( resource image [, string filename] )

參數說明如下。

? image:要保存的圖像源。

? filename:要保存的圖像名。如果省略,則直接輸出到瀏覽器。

6)imagedestroy()函數

圖像保存完畢后,使用imagedestroy()函數來釋放內存,函數語法如下:

      bool imagedestroy ( resource image )

驗證碼的生成文件是valcode.php,其完整代碼如下:

      <? php
       header("content-type:image/png");           //設置頁面編碼
       $num = $_GET[' num' ];                      //獲取超鏈接傳遞的隨機數
       $imagewidth=60;                             //定義畫布的寬
       $imageheight=18;                            //定義畫布的高
       $numimage = imagecreate($imagewidth, $imageheight);         //創建畫布
       imagecolorallocate($numimage,240,240,240);                  //設置畫布顏色
       for($i=0; $i<strlen($num); $i++){                           //循環讀取隨機數
            $x = mt_rand(1,8)+$imagewidth*$i/4;
            $y = mt_rand(1, $imageheight/4);
       $color=imagecolorallocate($numimage, mt_rand(0,150), mt_rand(0,150), mt_rand
       (0,150));                                                   //定義圖像的顏色
            imagestring($numimage,5, $x, $y, $num[$i], $color);   //將隨機數寫入畫布中
       }
        for($i=0; $i<200; $i++){                //for循環語句生成干擾線
        $randcolor=imagecolorallocate($numimage, rand(200,255), rand(200,255), rand
        (200,255));                             //定義顏色
                //生成干擾線
                imagesetpixel($numimage, rand()%70, rand()%20, $randcolor);
        }
        imagepng($numimage);                    //生成圖像
        imagedestroy($numimage);                //釋放資源
       ?>

1.2.4 E-mail激活技術

為了防止惡意注冊,現在有很多的網站采用了E-mail激活技術。當用戶注冊成功后,并不是馬上就可以使用,而是需要先登錄郵箱。通過系統發出的E-mail上的鏈接進行激活,只有激活后,賬號才可以使用。對于找回密碼的用戶,系統會將新密碼發送到郵箱中,這在一定程度上,提高了安全性。

本模塊使用ZendFramework中的Zend_Mail組件完成郵件的發送操作,在本書的光盤中沒有提供Zend_Mail組件,如果要運行這個程序,需要讀者自己下載Zend組件,并將其復制到本模塊的根目錄下,即mr/04文件夾下。

實踐真知 說明

在執行郵件的發送時,筆者使用的是搜狐郵箱,郵箱名稱是mrsoft8888@sohu.com,密碼是mrsoft8888。讀者在完成用戶注冊之后,可以登錄這個郵箱完成注冊用戶的激活操作,否則注冊的用戶是不能夠使用的。

注冊用戶激活的原理是控制數據庫中用戶信息表(tb_member)中active字段的值,默認值注冊成功后該字段的值是0,但是此時該用戶是不能夠登錄網站的,必須通過郵箱激活,將該字段的值更新為1之后,此用戶才可以使用。激活操作的文件存儲于activation.php文件中,其關鍵代碼如下:

      <? php
      session_start();
      header(' Content-Type:text/html; charset=gb2312' );
      include_once("conn/conn.php");
      if (! empty($_GET[' name' ]) && ! is_null($_GET[' name' ])){         //激活注冊用戶
            $num=$conne->getRowsNum("select * from tb_member where name
            =' ".$_GET[' name' ]."' and password = ' ".$_ GET[' pwd' ]."' ");
            if ($num>0){
              $upnum=$conne->uidRst("update tb_member set active = 1 where name=
              '".$_GET[' name' ]."' and password = ' ".$_GET[' pwd' ]."' ");
              if($upnum > 0){
                  $_SESSION[' name' ] = $_GET[' name' ];
                  echo "<script>alert(’用戶激活成功!' ); window.location.
                  href=' main.php' ; </script>";
              }else{
                  echo "<script>alert(’您已經激活!' ); window.location.href=' main.php' ;
                    </script>";
              }
            }else{
              echo "<script>alert(’用戶激活失?。? ); window.location.href=
              'register.php' ; </script>";
            }
      }
      ?>

1.2.5 應用鍵盤響應事件驗證信息是否合法

新用戶注冊時,隨著信息輸入,系統實時顯示信息的正確性;用戶登錄時,無須使用鼠標來選擇文本框,只要按<Enter>鍵,焦點就自動下移。這些功能都是通過JavaScript腳本中的鍵盤響應事件來實現的。隨著Ajax技術的流行,JavaScript已經成為一個開發人員必須要掌握的技術。下面,就來簡單了解鍵盤事件。

用戶通過onkeydown和onkeyup事件來觸發響應事件。使用方法與onclick事件類似。onkeydown表示當鍵盤上的鍵被按下時觸發,onkeyup和它正好相反,當鍵盤上的鍵被按下又抬起時觸發。在頁面中加載事件的方式有多種,這里介紹兩種最常用的方式。

1.將事件直接添加到頁面元素中

方法最直接、簡單,格式如下:

      <script type="text/javascript">
          …
          function refer(){
            …
          }
      </script>
      <input type="text" onkeydown="refer()" />

當該用戶輸入完信息后,單擊任意鍵,onkeydown事件被觸發,并調用refer()函數。

2.通過window.onload加載

當頁面被載入時,事件被載入,格式如下:

      <script>
            window.onload = function(){
              document.getElementById(' lgname' ).onkeydown = function(){
                    …
              }`
            }
      </script>
      …
      <input id="lgname" type="text" />
      …

當用戶輸入信息時,每輸入一個字母,都將觸發該事件,在該事件調用的函數中,對用戶輸入信息進行判斷。例如用戶名必須大于等于2、密碼最短6位、E-mail必須合法等。下面看一段驗證用戶名的代碼:

      //驗證用戶名
      //為id等于regname的頁面元素添加onkeyup事件
      //用戶每按一次鍵,都會調用一次該函數
      $(' regname' ).onkeyup = function (){
            name = $(' regname' ).value;                //獲取輸入內容
          cname2 = ' ' ;
          if(name.match(/^[a-zA-Z_]*/) == ' ' ){        //判斷輸入字符是否在有效范圍之內
              $(' namediv' ).innerHTML = ' <font color=red>必須以字母或下畫線開頭</font>' ;
              cname1 = ' ' ;
          }else if(name.length < 2){                 //判斷輸入的字符長度
              $(' namediv' ).innerHTML = ' <font color=red>注冊名稱必須大于等于2位</font>' ;
              cname1 = ' ' ;
          }else{
              $(' namediv' ).innerHTML = ' <font color=green>注冊名稱符合標準</font>' ;
              cname1 = ' yes' ;
          }
          chkreg();
      }
      …

該段代碼的運行結果如圖1.6所示。

圖1.6 驗證信息合法性

使用onkeydown事件還可以實現對特定鍵的控制,包括<Enter>鍵、<Ctrl>鍵、<Alt>鍵等所有的按鍵,這是通過在onkeydown事件中使用keyCode屬性來實現的。keyCode屬性能夠知道用戶按下的是哪個鍵,例如<Enter>鍵等于13、空格鍵等于32等。使用keyCode屬性的一般格式如下:

      <script>
          window.onload = function(){
              document.getElementById(' lgname' ) = function(){
                  if(event.keyCode == 13){            //判斷用戶是否按了<Enter>鍵
                      …
                  }
              }`
          }
      </script>

在本模塊中,實現了焦點自動下移功能。當用戶按<Enter>鍵時,頁面的焦點自動移到下一個文本框中,實現后的效果如圖1.7所示。

圖1.7 焦點自動下移的運行效果

1.2.6 PHP中操作Cookie技術

Cookie的作用是當用戶第一次訪問某服務器時,服務器將一些信息保存到客戶端計算機內。在以后的一段時間內,當用戶再次訪問這個服務器時,服務器通過Cookie信息,能夠識別該用戶。在很長一段時間內,Cookie都被當做一個不安全的因素,很少再被使用,轉而使用Session。但是,Cookie的功能確實十分方便,自動登錄、網站統計等都比其他的實現方式要簡單、快捷得多。Cookie只是一個文本文件,不能訪問本地硬盤,無法傳播病毒木馬程序。唯一要注意的地方是,Cookie只能識別計算機,而不會在意誰在使用。

在PHP中操作Cookie使用setcookie()函數和$_COOKIE預定義變量。setcookie()函數的語法格式如下:

      bool setcookie ( string name [, string value [, int expire [, string path [, string
  domain [, bool secure]]]]] )

參數說明如下。

? name:設置了Cookie的名字。

? value:Cookie的值,即參數name的值。

? expire:用來設置Cookie的過期時間,該參數以時間戳的形式存在。一般設置Cookie過期時間的時候,通過time()+秒數來實現,如time()+60×10,表示Cookie將在10分鐘后失效。設置Cookie馬上失效,可以將時間設為當前日期之前,如time()-1,那么Cookie會立即失效。

? path:表示Cookie在服務器端的有效范圍。如果path設為“/”,那么Cookie在整個服務器內都有效,如果Cookie為“/05/”,那么Cookie只在服務器下的05目錄有效。

? domain:指定了Cookie有效的域名范圍,以www.mrbccd.com為例,如果domain設為“.mrbccd.com”,那么Cookie在該域的所有子域都有效;如果domain為“www.mrbccd.com”,那么Cookie只在www.mrbccd.com域內有效。

? secure:表明是否在https傳送。如果是True, Cookie僅在https連接中被設置,默認是False。

1.2.7 在JavaScript中操作Cookie技術

在JavaScript中可以通過document對象中的Cookie屬性對Cookie進行創建、讀取、刪除等操作。先來看創建Cookie的格式(代碼中加粗的部分是需要用戶設置的)。

      documen.cookie = "Name=Value; expires=time; path=URL; domain= Domain"

其中各個參數的含義與PHP中的基本相同,這里不再贅述。

在JavaScript中讀取Cookie有一點復雜。在JavaScript看來,Cookie就是一個字符串。例如一個名字為“Count”、值是“10”的Cookie,在JavaScript中的格式是

      count=10

如果有多個Cookie,那么它的格式如下:

      count=10; name=mr; …

而真正需要的值,其實只有10而已。所以,要獲取Cookie的值,就要使用split()函數將Cookie進行拆分,獲取count值的代碼為

      <script>
                 if(document.cookie==' ' ){                      //Cookie等于空時
                    document.write(' no cookie' );
                 }else{
                    //以分號為分隔符,對Cookie進行分隔
                    cookiearr = document.cookie.split(' ; ' );
                     leng = cookiearr.length;                   //獲取數組長度
                     for(i=0; i<leng; i++){
                          //判斷哪一個Cookie等于count
                          if(cookiearr[i].split(' =' )[0] == ' count' ){
                               //輸出count的值
                               document.write(cookiearr[i].split(' =' )[1]);
                         }
                    }
         }
</script>

1.2.8 用戶自動登錄技術

自動登錄的原理是:當用戶打開登錄頁面時,登錄頁面首先判斷用戶客戶端機器中的Cookie值。如果該值不存在,或者Cookie已失效,這時,將顯示登錄表單;如果Cookie值存在,則直接使用Cookie中所保存的用戶名進行登錄。

在本模塊中,用戶首先打開的是index.php頁,該頁判斷Cookie值,如果沒有,則跳轉到login.php進行登錄;如果Cookie有值,則將Cookie中的用戶名保存到Session,直接進入主頁面,實現代碼如下:

      <? php
            session_start();                                //開啟Session支持
            header(' Content-Type:text/html; charset=gb2312' );      //設置頁面編碼
            //判斷Cookie是否為空
            if(! empty($_COOKIE[' name' ]) and ! is_null($_COOKIE[' name' ])){
              $_SESSION[' name' ] = $_COOKIE[' name' ];     //將Cookie保存到Session中
                //跳轉到main.php頁
              header(' location:http://localhost/model/05/01/main.php' );
            }else{                                          //Cookie為空,說明沒有登錄
                //跳轉到login.php頁
              header(' location:http://localhost/model/05/01/login.php' );
            }
      ?>

這里$_COOKIE[' name' ]的值是在登錄成功時設置的,相關代碼如下:

      <? php
            …                                                //如果登錄成功
            setcookie(' name' , $name, time()+60*10);         //保存$name的同時設置時間
            …
      ?>
主站蜘蛛池模板: 开平市| 新宁县| 舞阳县| 敖汉旗| 隆安县| 普宁市| 吉木乃县| 金山区| 柳州市| 中牟县| 池州市| 铁岭县| 黄浦区| 来安县| 汾阳市| 龙里县| 新龙县| 广水市| 嵊泗县| 和静县| 新乐市| 麟游县| 平遥县| 金秀| 盐池县| 扶沟县| 怀安县| 肥城市| 临江市| 澄迈县| 翁牛特旗| 黎平县| 疏附县| 武强县| 大埔县| 芮城县| 新沂市| 广西| 德清县| 赣榆县| 漠河县|