如果字符串包含子串数组之一,如何返回布尔值?

时间:2012-03-15 21:50:32

标签: php if-statement foreach boolean strpos

我正在努力使用一个循环遍历数组的简单函数,只有当它在一个数组的元素中找到给定的子字符串时才返回true

出于某种原因,即使false参数包含一个有效域,我也总是得到$email ...例如:scoobydoo@domain1.com

function check_email($email) {
    $whitelist_domains = array(
        '@domain1.com',
        '@domain2.com',
        '@domain3.com'
    );
    $output = FALSE;
    foreach ($whitelist_domains as $domain) {   
        $pos = strpos( $email, $domain ); 
        if ( $pos ) {
            $output = TRUE;
        }
    }
    return $output;
}

6 个答案:

答案 0 :(得分:2)

如果找到域名,你不会破坏循环,所以你得到的实际上只是检查LAST字符串的结果。 只需在break;

之后添加$output = TRUE;即可

答案 1 :(得分:1)

来自strpos的官方文件:

  

警告

     

此函数可能返回布尔值FALSE,但也可能返回a   非布尔值,其值为FALSE。请阅读有关的部分   布尔值获取更多信息。使用===运算符进行测试   返回此函数的值。

确保在将$output设置为true后添加中断。

答案 2 :(得分:0)

这是使用===运算符的一个很好的函数,因为它确保值和类型相等(1==true,但是1!==true

if (strpos( $email, $domain )!==false) {
    $output = TRUE;
}

答案 3 :(得分:0)

更改

if ( $pos ) {

if ( $pos !== false) {

这是因为strpos返回0,即使找到了字符串,也会等于false。

答案 4 :(得分:0)

以下是两种具有不同优势的直接/常用方法:

方法#1 :非正则表达式

function check_email1($email){
    $whitelist_domains=['@domain1.com','@domain2.com','@domain3.com'];
    foreach($whitelist_domains as $domain){
        if(strpos($email,$domain)!==false){
            return true;  // allow quick return (exit loop & function asap)
        }
    }
    return false;  // default response
}

方法#2 :正则表达式方法

function check_email2($email){
    $whitelist_pattern='/@(?:domain1\.com|domain2\.com|domain3\.com)$/';  // condense if possible /@domain[123]\.com$/
    return (bool)preg_match($whitelist_pattern,$email);  // convert 0 or 1 output to boolean (false/true)
}

Demo Link

输入/函数调用

$emails=['user@domain1.com','bad@bad.com'];
foreach($emails as $email){
    echo "$email\n";
    var_export(check_email1($email));
    echo "\n";
    var_export(check_email2($email));
    echo "\n\n";
}

<强>输出

user@domain1.com
true
true

bad@bad.com
false
false

<强>优点/缺点

    在大多数情况下,
  • strpos()将胜过正则表达式函数。您的默认方法应该是使用字符串函数,并且只有在字符串函数效率低或编码太复杂时才更改为正则表达式。相关页面:Which is more efficient, PHP string functions or regex in PHP?

  • 与#2相比,#1中的循环$whitelist_domains使得看起来更笨重的代码块(如果将模式直接写入preg_match(),则可以将其压缩为单行代码)。

  • 处理strpos()时有时会出现简单/常见错误。这些错误可能包括:

    • 未在false条件
    • 中检查if
    • 以错误的顺序撰写haystackneedle
  • #2确实需要一些关于正则表达式(转义,字符类,替代等)的知识,这对于没有经验的编码员来说是一种威慑。根据您编写正则表达式模式的方式以及将列入白名单的域数,#2可能比#1更难维护。

  • #2的另一个好处是能够通过domain.com元字符检查$子字符串是否出现在单词的末尾。出于这个原因,正则表达式提供了更强的验证。

答案 5 :(得分:0)

您应该更改以下代码:

function check_email($email) {
    $whitelist_domains = array(
        '@domain1.com',
        '@domain2.com',
        '@domain3.com'
    );

    foreach ($whitelist_domains as $domain) {   
        if ( strpos( $email, $domain ) !== false ) {
            return true;
        }
    }
    return false;
}

strpos

的文档

从手册(http://php.net/manual/en/function.strpos.php)引用:

  

也可以使用!==运算符。使用!=将无法正常工作   因为'a'的位置是0.语句(0!= false)计算   为假。

示例代码

<?php
$mystring = 'abc';
$findme   = 'a';
$pos = strpos($mystring, $findme);

// The !== operator can also be used.  Using != would not work as expected
// because the position of 'a' is 0. The statement (0 != false) evaluates 
// to false.
if ($pos !== false) {
     echo "The string '$findme' was found in the string '$mystring'";
         echo " and exists at position $pos";
} else {
     echo "The string '$findme' was not found in the string '$mystring'";
}
?>