php中strpos函数判断字符存在误区

 更新时间:2016年11月25日 17:06  点击:1584
在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;
    }
    }

 

在php中如果我们要获取毫秒就必须通过microtime()再进行转换,下面我来给各位朋友举几个实例,希望对大家会有所帮助。

问题不怕弱智…啥都记

 代码如下 复制代码

function getmicrotime() 

    list($usec, $sec) = explode(" ",microtime()); 
    return ((float)$usec + (float)$sec); 
}

其实就是处理了一下microtime()这个函数。

microtime()这个函数的返回值是这种形式:

0.06261400 1303715872

空格后面为当前的时间戳,空格前面是当前的精确时间

例,计算页面执行时间函数

 代码如下 复制代码

<?php
/**
* Simple function to replicate PHP 5 behaviour
*/
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

$time_start = microtime_float();

// Sleep for a while
usleep(100);

$time_end = microtime_float();
$time = $time_end - $time_start;

echo "Did nothing in $time secondsn";
?>

在php中header有很多的作用,这里我们给大家介绍在使用header作文件跳转时一些注意事项,希望此文章能给各位朋友带来快乐。

header("Location:login.php")应该注意的几个问题
header("Location:")作为php的转向语句。其实在使用中,他有几点需要注意的地方。

1、要求header前没有任何输出

但是很多时候在header前我们已经输出了好多东西了,此时如果再次header的话,显然是出错的,在这里我们启用了一个ob的概念,ob的意思是在服务器端先存储有关输出,等待适当的时机再输出,而不是像现在这样运行一句,输出一句,发现header语句就只能报错了。

具体的语句有: ob_start(); ob_end_clean();ob_flush();.........


2、在header("Location:")后要及时exit

否则他是会继续执行的,虽然在浏览器端你看不到相应的数据出现,但是如果你进行抓包分析的话,你就会看到下面的语句也是在执行的。而且被输送到了浏览器客户端,只不过是没有被浏览器执行为html而已(浏览器执行了header进行了转向操作)。


所以,标准的使用方法是:

 代码如下 复制代码

ob_start();

........

if ( something ){

ob_end_clean();

header("Location: yourlocation");

exit;

else{

..........

ob_flush(); //可省略

 
要想在header前有输出的话,可以修改php.ini文件

output_handler =mb_output_handler

或 output_handler =on
 
Output Control 函数可以让你自由控制脚本中数据的输出。它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况。输出控制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块有作用。

一、 相关函数简介:

1、Flush:刷新缓冲区的内容,输出。
函数格式:flush()
说明:这个函数经常使用,效率很高。
2、ob_start :打开输出缓冲区
函数格式:void ob_start(void)
说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。
3 、ob_get_contents :返回内部缓冲区的内容。
使用方法:string ob_get_contents(void)
说明:这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE 。
4、ob_get_length:返回内部缓冲区的长度。
使用方法:int ob_get_length(void)
说明:这个函数会返回当前缓冲区中的长度;和ob_get_contents一样,如果输出缓冲区没有激活。则返回 FALSE。
5、ob_end_flush :发送内部缓冲区的内容到浏览器,并且关闭输出缓冲区。
使用方法:void ob_end_flush(void)
说明:这个函数发送输出缓冲区的内容(如果有的话)。
6、ob_end_clean:删除内部缓冲区的内容,并且关闭内部缓冲区
使用方法:void ob_end_clean(void)
说明:这个函数不会输出内部缓冲区的内容而是把它删除!
7、ob_implicit_flush:打开或关闭绝对刷新
使用方法:void ob_implicit_flush ([int flag])
说明:使用过Perl的人都知道$|=x的意义,这个字符串可以打开/关闭缓冲区,而ob_implicit_flush函数也和那个一样,默认为关闭缓冲区,打开绝对输出后,每个脚本输出都直接发送到浏览器,不再需要调用 flush()

ob_start() 开始输出缓冲, 这时PHP停止输出, 在这以后的输出都被转到一个内部的缓冲里.
ob_get_contents() 这个函数返回内部缓冲的内容. 这就等于把这些输出都变成了字符串.
ob_get_ length() 返回内部缓冲的长度.
ob_end_flush() 结束输出缓冲, 并输出缓冲里的内容. 在这以后的输出都是正常输出.
ob_end_clean() 结束输出缓冲, 并扔掉缓冲里的内容.
举个例子, var_dump()函数输出一个变量的结构和内容, 这在调试的时候很有用.
但如果变量的内容里有 < , > 等HTML的特殊字符, 输出到网页里就看不见了. 怎么办呢?

用输出缓冲函数能很容易的解决这个问题.

 代码如下 复制代码

ob_start();
var_dump($var);
$out = ob_get_contents();
ob_end_clean();

这时var_dump()的输出已经存在 $out 里了. 你可以现在就输出:

 代码如下 复制代码
echo '<pre>' . htmlspecialchars($out) . '</pre>' ;

或者等到将来, 再或者把这个字符串送到模板(Template)里再输出.

php去空格有相关函数 trime,他可以去除两个空格或直接使用ltrim与rtrim函数结果与trim一样,如果要删除所有空格只有使用str_replace替换了。

平时过虑空格,一般都是用trim,今天发现,中间的空格去不掉.倒,查了说明才知道,trim只能去两头的,比如$abc =  a b c; ,用trim只能把a前面c后面的空格去掉,但是b前后的空格怎么办呢. str_replace出场了,这样就行了

 代码如下 复制代码

str_replace(' ','',$abc).

需要去空格的同学们小心了,php去空格,trim不行,str_replace行了,但是trim可以删除头空格了如下

 代码如下 复制代码

<?php

trim 去除一个字符串两端空格,
rtrim 是去除一个字符串右部空格,
ltrim 是去除一个字符串左部空格。

echo trim(" 空格www.111cn.net ")."<br>";
echo rtrim(" 空格 ")."<br>";
echo ltrim(" 空格 ")."<br>";
?>

达到的效果与str_replace是一样的

在php中数组与字符串相互转换最常用的方法就是使用explode(),implode()函数来转换了,今天我看一朋友问了一个这样的问题,下面我来整理一下分享给各位。

行看看这两个函数

implode 函数:

使用函数 implode 将数组转换为字符串

explode 函数:

使用函数 explode 将字符串转换成数组

例1.

今天在php论坛中看到以为朋友发了一个帖子请教php如何把字符串转换成数组;作为php程序员的新一第一反应是联想到explode(),implode()这两个函数。新一也是用里面的函数进行转换成数组的。

con[1]=28&selt[1]=1&con[2]=29&selt[2]=4&con[3]=26&selt[3]=4

&con[4]=30&selt[4]=2&con[5]=4&selt[5]=1&con[6]=11&con[7]=12

上面就是网友需要转换成PHP数组的字符串;下面也是新一提供PHP转换代码

 代码如下 复制代码

<?php
$str = 'con[1]=28&selt[1]=1&con[2]=29&selt[2]=4&con[3]=26&selt[3]=4&con[4]=30&selt[4]=2&con[5]=4&selt[5]=1&con[6]=11&con[7]=12';
$arr = explode('&',$str);
$arr2 = array();
foreach($arr as $k=>$v){
        $arr = explode('=',$v);
        $arr2[$k] = $arr[1];
}
print_r($arr2);
?>
//输出
Array
(
    [0] => 28
    [1] => 1
    [2] => 29
    [3] => 4
    [4] => 26
    [5] => 4
    [6] => 30
    [7] => 2
    [8] => 4
    [9] => 1
    [10] => 11
    [11] => 12
)
//第二个
<?php
$str = 'con[1]=28&selt[1]=1&con[2]=29&selt[2]=4&con[3]=26&selt[3]=4&con[4]=30&selt[4]=2&con[5]=4&selt[5]=1&con[6]=11&con[7]=12';
$arr = explode('&',$str);
$arr2 = array();
foreach($arr as $k=>$v){
        $arr = explode('=',$v);
        $arr2[$arr[0]] = $arr[1];
}
print_r($arr2);
?>
//输出
Array
(
    [con[1]] => 28
    [selt[1]] => 1
    [con[2]] => 29
    [selt[2]] => 4
    [con[3]] => 26
    [selt[3]] => 4
    [con[4]] => 30
    [selt[4]] => 2
    [con[5]] => 4
    [selt[5]] => 1
    [con[6]] => 11
    [con[7]] => 12
)


例2.
上面只支持一维数据,如果是二维或三维数据呢

 代码如下 复制代码


//将多维数组中所有的数值转换成字符串????》最多支持三维数组
function implodex( $glue, $array, $separator='' ) {
if ( ! is_array( $array ) ) return $array;
$string = array();

$count = 0;
foreach ( $array as $key => $val ) {
if ( is_array( $val ) )
$val = implode( $glue, $val );

if($count == 0){
$string[] = "{$val}";
}else{
$string[] = "{$glue}{$val}";
}
}

if(empty($separator))$separator = $glue;

return implode( $separator, $string );
}


例3.

将数组转成字符串存储及字符串取出转成数组(serialize & unserialize)

下面看一个实例:

 代码如下 复制代码

<?php
// $Id: test3.php,v 1.0 2011-6-7  goba Exp $
 
/**
 * 测试PHP存储数值
 *
 * @author Lok
 */
 
 
$config = array (
 'host' => 'localhost',
 'user_name' => 'root',
 'password' => '',
 'db_name' => 'ecshop',
 'charset' => 'utf8',
 'remark' => array ('note' => '要注意密码的安全', 'author' => 'Lok')
);
 
 
$str = serialize($config);
$arr = unserialize($str);
 
echo '--------str--------<br />';
var_dump($str);
echo '<br />-------arr----------<br />';
var_dump($arr)
?>结果:

--------str--------
string(221) "a:6:{s:4:"host";s:9:"localhost";
   s:9:"user_name";s:4:"root";
   s:8:"password";s:0:"";
   s:7:"db_name";s:8:"ecshop";
   s:7:"charset";s:4:"utf8";
   s:6:"remark";a:2:{s:4:"note";s:24:"要注意密码的安全";
                s:6:"author";s:3:"Lok";}}"
-------arr----------
array(6) { ["host"]=> string(9) "localhost"
        ["user_name"]=> string(4) "root"
        ["password"]=> string(0) ""
        ["db_name"]=> string(8) "emoishop"
               ["charset"]=> string(4) "utf8"
               ["remark"]=> array(2) { ["note"]=> string(24) "要注意密码的安全"
             ["author"]=> string(3) "Lok" } }

[!--infotagslink--]

相关文章

  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
  • PHP函数strip_tags的一个bug浅析

    PHP 函数 strip_tags 提供了从字符串中去除 HTML 和 PHP 标记的功能,该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。由于 strip_tags() 无法实际验证 HTML,不完整或者破损标签将导致更多的数...2014-05-31
  • SQL Server中row_number函数的常见用法示例详解

    这篇文章主要给大家介绍了关于SQL Server中row_number函数的常见用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08
  • PHP加密解密函数详解

    分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: /* *功能:对字符串进行加密处理 *参数一:需要加密的内容 *参数二:密钥 */ function passport_encrypt($str,$key){ //加密函数 srand(...2015-10-30
  • php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法

    最近遇到一个问题,就是在使用php的mail函数发送utf-8编码的中文邮件时标题出现乱码现象,而邮件正文却是正确的。最初以为是页面编码的问题,发现页面编码utf-8没有问题啊,找了半天原因,最后找到了问题所在。 1.使用 PEAR 的...2015-10-21
  • C#中加载dll并调用其函数的实现方法

    下面小编就为大家带来一篇C#中加载dll并调用其函数的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#虚函数用法实例分析

    这篇文章主要介绍了C#虚函数用法,实例分析了C#中虚函数的功能与基本使用技巧,需要的朋友可以参考下...2020-06-25
  • PHP编码转换函数mb_convert_encoding与iconv用法

    文章来实现一个PHP编码转换函数mb_convert_encoding与iconv用法,希望例子能帮助到各位。 将一个短信接口代码从apache迁移到nginx+php-fpm后,发现无法发出短信了,查...2016-11-25