Как вернуть логическое значение, если строка содержит один из массивов подстрок? - PullRequest
0 голосов
/ 16 марта 2012

Я борюсь с простой функцией, которая перебирает массив и возвращает 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 ]

2 голосов
/ 16 марта 2012

вы не прерываете цикл, если вы находите домен, так что то, что вы получаете, на самом деле является результатом только проверенной строки LAST.просто добавьте break; после $output = TRUE;

1 голос
/ 16 марта 2012

Из официального документа strpos :

Предупреждение

Эта функция может возвращать логическое значение ЛОЖЬ, но может также возвращать не-логическое значение, которое оцениваетЛОЖЬ.Пожалуйста, прочитайте раздел о логических значениях для получения дополнительной информации.Используйте оператор === для проверки возвращаемого значения этой функции.

И обязательно добавьте разрыв после того, как для $output установлено значение true.

0 голосов
/ 03 сентября 2017

Вы должны изменить свой код следующим образом:

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):

The!Оператор == также может быть использован. Использование! = не будет работать должным образом, поскольку позиция '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'";
}
?>
0 голосов
/ 03 сентября 2017

Вот два прямых / общих метода, которые имеют различные преимущества:

Метод № 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)
}

Демонстрационная ссылка

Вход / вызов функции :

$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 () в большинствеситуаций будет превосходить функции регулярных выражений.Ваш метод по умолчанию должен состоять в том, чтобы использовать строковые функции и переходить на регулярные выражения только тогда, когда строковые функции менее эффективны или слишком сложны для кодирования.Связанная страница: Что является более эффективным, строковые функции PHP или регулярное выражение в PHP?

  • Цикл $whitelist_domains в # 1 делает блок кода более неприглядным по сравнениюдо # 2 (который может быть сжат до однострочного, если вы записываете шаблон непосредственно в preg_match () ).

  • Иногда возникают простые / распространенные ошибки, когдадело с strpos().Эти ошибки могут включать:

    • не проверка false в if условии
    • запись haystack и needle в неправильном порядке
  • # 2 действительно требует некоторых знаний о регулярных выражениях (экранирование, классы символов, альтернативы и т. Д.), Которые могут быть сдерживающим фактором для неопытных программистов.В зависимости от того, как вы пишете свой шаблон регулярных выражений и сколько доменов будет занесено в белый список, обслуживание №2, вероятно, будет сложнее поддерживать, чем # 1.

  • # 2 обладает дополнительным преимуществом возможностичтобы убедиться, что подстрока domain.com появляется в конце слова через метасимвол $.По этой причине регулярное выражение предлагает более строгую проверку.

0 голосов
/ 16 марта 2012

Изменение

if ( $pos ) {

до

if ( $pos !== false) {

это потому, что strpos возвращает 0, что будет равно false, даже если строка найдена.

0 голосов
/ 16 марта 2012

Это хорошая функция для использования оператора ===, поскольку она гарантирует, что значение и тип равны (1==true, но 1!==true)

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