程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php中strpos函數判斷字符存在誤區

php中strpos函數判斷字符存在誤區

編輯:關於PHP編程

在php中strpos是查找字符串首次出現的位置,如果存在就返回ture或相關具體數字,沒有就返回0或false了,但本人要用它做一個wordpress關鍵詞黑名單反垃圾評論時發現一些問題,下面我們來看看。

修改主題comments-ajax.php文件

在主題目錄下的comments-ajax.php文件中,大概60行左右的位置(剛取得用戶提交的評論表單中的$_POST['author']等字段)。然後在該文件中加上下面的代碼:

 代碼如下 復制代碼

    /*
    * @Author: vfhky 2013年09月21日22:13
    * @Variable string $word: 黑名單中的關鍵詞,用戶可自行按規律進行增加或減少
    * @Variable string $comment_author: 用戶提交的$_POST['author']字段值,表示昵稱
    * @Variable string $comment_content: 用戶提交的$_POST['comment']字段值,表示評論內容
    **/
    $words = "com,cn,info,net,www,http,cc,host,代理,移動,電,國,港,器,服,醫,肥,藥,農,信,貸,日,盈,網,票,域,銷,黃,司,企,機,租,人,錢,設,購,播";
    $word = explode(',', $words);
    $num = count($word);
    for($i=0;$i< $num ;$i++){
    if (strpos($comment_author,$word[$i],0) || strpos($comment_content,$word[$i],0)){
    err( __('廣告必刪,多謝理解!') );
    break;
    }
    }

4 後記

通過上面這段簡單代碼,我們就實現了提交對評論輸入的用戶昵稱、評論內容進行了黑名單中的關鍵詞的校驗。一旦匹配到了上面的任何一個詞語,例如出現了www,那麼就提示用戶“廣告必刪,多謝理解!”,效果如下圖所示。這樣算是又給博客上了一道保險,增強了wordpress反垃圾評論的免疫力,而且還是非插件的方法實現的喲!

wordpress關鍵詞黑名單:反垃圾評論再升級(非插件)上面看上沒問題,但是上午 @壞 童鞋一個邪惡測試,發現了上篇文章代碼的BUG。晚上下班回來,仔細看了下代碼,發現是自己對strpos函數的片面認識,因此做個筆記Mark一下。

2 strpos函數的原型

相信大家對strpos函數並不陌生,經常在字符串的處理中能看到它的身影。strpos函數原型是:

    /*
    * @Para string $source: 在該字符串中進行查找[*]
    * @Para mixed $target: 要查找的字符串;如若不是字符串,將被轉換為整型並被視為字符的順序值[*]
    * @Para int $offset: 查找的起始位置
    * @Return int/boolean: 成功則返回第一次出現的位置; 失敗返回 FALSE 值
    **/
    int strpos(string $source, mixed $target [, int $offset = 0 ]);
    

3 strpos函數的簡單測試

了解了strpos函數的原型之後,我們先來看一段簡單的測試代碼。

  

 代碼如下 復制代碼   /*
    * @Author: vfhky 2013年09月21日20:35
    * @Description: 通過兩個不同的測試變量$test_1和$test_2直擊關鍵
    **/
    <?php
    $words = "com,cn,info,net,www,http,cc,host,代理,移動,電,國,港,日,購";
    $word = explode(',', $words);
    $num = count($word);
    $test_1 = "購買TT";
    for($i=0;$i< $num ;$i++){
    if (strpos($test_1,$word[$i],0)){
    echo '廣告必刪,多謝理解!';
    break;
    }
    }
    echo "<br/><br/>----------This is $test_1 END----------<br/><br/>";
    
    $test_2 = "壞壞購買TT";
    for($i=0;$i< $num ;$i++){
    if (strpos($test_2,$word[$i],0)){
    echo '廣告必刪,多謝理解!';
    break;
    }
    }
    echo "<br/><br/>----------This is $test_2 END----------<br/><br/>";
    ?>

測試結果如下圖所示:

再議wordpress反垃圾評論:都是strpos函數惹的禍

再議wordpress反垃圾評論:都是strpos函數惹的禍


4 strpos函數的測試結果分析

上面這段代碼中有兩個不同的測試變量$test_1和$test_2,並且二者都包含了黑名單中的關鍵詞:購。但是從圖中顯示的測試結果來看,$test_1變量沒有別有效屏蔽,而變量$test_2卻被提示包含廣告詞。奧秘就在於變量$test_1和$test_2中的“購”字出現的位置就!當關鍵詞“購”出現在最前面時($test_1),strpos($test_1,$word[$i],0)函數的執行結果為0,因為“購”字在字符串“購買TT”的最前面。那麼for循環中的if語句變成了if(0){},從而不會被視為垃圾評論,這就造成了BUG。下面分別是繼續用strpos函數和使用PHP正則表達式,兩種方法來實現“wordpress關鍵詞黑名單:反垃圾評論再升級”。
5.1 正確使用strpos函數修正BUG

 代碼如下 復制代碼

    /*
    * @Author: vfhky 2013年09月24日20:06
    * @Description: 正確使用strpos函數,解決上一篇文章代碼的BUG
   
    **/
    $words = "com,cn,info,net,www,http,cc,host,代理,移動,電,國,港,器,服,醫,肥,藥,農,信,貸,日,購,播";
    $word = explode(',', $words);
    $num = count($word);
    for($i=0;$i< $num ;$i++){
    if ( (strpos($comment_author,$word[$i],0) !== false) || (strpos($comment_content,$word[$i],0) !== false) ){
    err( __('廣告必刪,多謝理解!') );
    break;
    }
    }

5.2 使用PHP正則表達式修正BUG

   

 代碼如下 復制代碼 /*
    * @Author: vfhky 2013年09月24日20:06
    * @Description: 使用PHP正則表達式修正BUG,實現“wordpress關鍵詞黑名單:反垃圾評論再升級(非插件)”
  
    **/
    $words = "com,cn,info,net,www,http,cc,host,代理,移動,電,國,港,器,服,醫,肥,藥,農,信,貸,日,購,播";
    $word = explode(',', $words);
    $num = count($word);
    for($i=0;$i< $num ;$i++){
    if( preg_match("/$word[$i]/i", $comment_author) || preg_match("/$word[$i]/i", $comment_content) ){
    err( __('廣告必刪,多謝理解!') );
    break;
    }
    }

6 函數strpos的重要提醒

    使用strpos函數還需要注意的一點就是:它可能返回布爾值 FALSE,但也可能返回等同於 FALSE 的非布爾值。
    例如返回整型0,浮點型值0.0,空字符串,字符串 "0",不包括任何元素的數組,不包括任何成員變量的對象,特殊類型NULL等等。
    因此,應使用會檢查返回的值的類型的恆等運算符“===”來測試此函數的返回值,而不是使用簡單的等號“==”來判別。

7Update 2013.09.26 22:27

經過 @星河大帝 的提醒,可以使用數組來代替字符串,執行效率應該差不多。
7.1 使用strpos函數+數組修正BUG

 代碼如下 復制代碼

    $words = array("com","cn","info","net","www","http","cc","host","代理","移動","電","國","港","購");
    $num = count($words);
    for($i=0;$i< $num ;$i++){
    if (strpos($comment_author,$words[$i],0) !== false || strpos($comment_content,$words[$i],0) !== false){
    err( __('廣告必刪,多謝理解!') );
    break;
    }
    }

7.2 使用正則式+數組修正BUG

  

 代碼如下 復制代碼   $words = array("com","cn","info","net","www","http","cc","host","代理","移動","電","國","港","購");
    $num = count($words);
    for($i=0;$i< $num ;$i++){
    if( preg_match("/$words[$i]/i", $comment_author) || preg_match("/$words[$i]/i", $comment_content) ){
    err( __('廣告必刪,多謝理解!') );
    break;
    }
    }

 

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