Что-то похожее на strpos() для массивов?

В последнее время я получаю много спама из моей контактной формы, поэтому я решил добавить немного проверки в часть «сообщение» формы. Я написал функцию, которая, как я думал, будет работать, чтобы отсеять наиболее часто используемые слова, которые я вижу в своих спам-сообщениях, из формы, но она всегда возвращает false, когда я ее запускаю.

Вот функция:

function spamCheck($input) {
    $flags = array('cialis', 'viagra', 'erection', 'pharmac', 'porn', 'anal', 'bondage', 'insurance', 'ringtone', 'poker', 'casino', 'gambl', 'whore', 'nipple', 'shit', 'realt', 'shemale', 'valium');
    $input = explode(' ', $input);
    foreach($input as $word) {
        $word = trim($word, '",.!?\';:*');
        foreach($flags as $flag) {
            if(strpos(strtolower($word), $flag)) {
                return $word;
                exit;
            }
        }
    }
    return false;
}

Вы заметите, что некоторые слова в черном списке не заполнены. Например, «gambl», которое может быть отправлено по электронной почте как «gambling», или «gamble», или «gambler», или «gambles», или «gambled». Вот почему я использовал strpos() внутри цикла foreach, чтобы он соответствовал частичным строкам, а не только точным строкам.

Любые идеи, что вызывает этот сбой?


person Amygdala    schedule 06.01.2014    source источник
comment
Вы уверены, что $input это массив? Кроме того, вам не нужно exit после return.   -  person    schedule 06.01.2014
comment
Думаю, я должен упомянуть, что я не хочу, чтобы он просто возвращал true, если было найдено совпадение. Я хочу, чтобы было возвращено исходное слово, которое было сопоставлено, чтобы я мог сообщить пользователю, что оно было помечено как спам, если это был законный вариант использования.   -  person Amygdala    schedule 06.01.2014
comment
Нет, input — это строка, которую я превращаю в массив внутри функции.   -  person Amygdala    schedule 06.01.2014
comment
Ох, простите. Строку $input = explode(' ', $input); не заметил, поэтому и задал глупый вопрос.   -  person    schedule 06.01.2014
comment
strpos вернет позицию. Если ваша строка существует на первом месте, она вернет 0. Итак, если в этом случае условие ложно.   -  person Kumar V    schedule 06.01.2014
comment
Измените седьмую строку вашего кода на if(strpos(strtolower($word), $flag) !== false) и посмотрите, работает ли это.   -  person    schedule 06.01.2014


Ответы (4)


Следующее должно работать:

function spamCheck($input){
    $flags = array('cialis', 'viagra', 'erection', 'pharmac', 'porn', 'anal', 'bondage', 'insurance', 'ringtone', 'poker', 'casino', 'gambl', 'whore', 'nipple', 'shit', 'realt', 'shemale', 'valium');
    $input = explode(' ', $input);
        foreach($input as $word){
        $word = trim($word, '",.!?\';:*');
            foreach($flags as $flag){
                if(strpos(strtolower($word), $flag) !== false){
                return $word;
                }
            }
        }
    return false;
}

$spam = spamCheck("Download free ringtones for your mobile phone.");
print($spam); // will print "ringtones"

Узнайте больше о возвращаемых значениях strpos.

Обновление: Эквивалент вашей функции в регулярном выражении:

function spamCheck($input){
    $flags = array('cialis', 'viagra', 'erection', 'pharmac', 'porn', 'anal', 'bondage', 'insurance', 'ringtone', 'poker', 'casino', 'gambl', 'whore', 'nipple', 'shit', 'realt', 'shemale', 'valium');
    $pattern = "/\\b[a-z]*(?:".implode("|", $flags).")[a-z]*\\b/i";
        if(preg_match($pattern, $input, $matches)){
        return $matches[0];
        }
    return false;
}
person Community    schedule 06.01.2014
comment
Это работает на данный момент. Думаю, я собираюсь углубиться в создание регулярного выражения для сопоставления, так как это, кажется, и есть шумиха, которую я здесь получаю. Но я буду использовать это, пока не разработаю шаблон, который будет выполнять эту работу. - person Amygdala; 06.01.2014
comment
Эй, большое спасибо, чувак! Большинство людей не стали бы тратить время на добавление дополнительных деталей после того, как их ответ был принят! - person Amygdala; 07.01.2014

Вам лучше использовать регулярное выражение здесь с preg_replace. Выполнение ручного поиска строк повлияет на эффективность и оставит нерешенными многие пограничные случаи.

person Rohan    schedule 06.01.2014

Попробуй это

function spamCheck($input) {
$flags = array('cialis', 'viagra', 'erection', 'pharmac', 'porn', 'anal', 'bondage', 'insurance', 'ringtone', 'poker', 'casino', 'gambl', 'whore', 'nipple', 'shit', 'realt', 'shemale', 'valium');
$input = explode(' ', $input);
foreach($input as $word) {
    $word = trim($word, '",.!?\';:*');
     foreach($flags as $fl){
      if(strpos($word,$fl) !== false ){ // edited as user requested
          return $word;
     }
}
}
return false;

}

person Nouphal.M    schedule 06.01.2014
comment
Я знаю, что in_array был бы лучшим выбором, но для его использования мне пришлось бы добавлять все варианты слова в массив черного списка. pharmac не будет соответствовать аптеке или фармацевтической продукции и т. д. - person Amygdala; 06.01.2014
comment
Спасибо. @Sharanya Dutta опередила тебя. - person Amygdala; 06.01.2014
comment
Если вы не упомянули свой комментарий в своем вопросе :) - person Nouphal.M; 06.01.2014

Несколько модификаций и все работает:

    function spamCheck($input) {
    $flags = array('cialis', 'viagra', 'erection', 'pharmac', 'porn', 'anal', 'bondage', 'insurance', 'ringtone', 'poker', 'casino', 'gambl', 'whore', 'nipple', 'shit', 'realt', 'shemale', 'valium');

    $input = preg_replace('/[",.!?\';:*]/', '', $input);

    $input = explode(' ', $input);

    foreach($input as $word) {
      foreach($flags as $flag) {
        if(strpos(strtolower($word), $flag) !== false) {
          return $word;
        }
      }   
    }
    return false;
}
person Pierre Emmanuel Lallemant    schedule 06.01.2014
comment
Да, это работает для точных совпадений. Однако неполные слова в черном списке, такие как gambl и pharmac, не совпадают. Вот почему я сначала не использовал in_array, потому что он выполняет только точные совпадения. - person Amygdala; 06.01.2014
comment
для тестирования strpos вам нужны операторы === и !=, проблема, вероятно, была во мне. - person Pierre Emmanuel Lallemant; 06.01.2014