php check if any of many characters are in one long string?

Joined
12 Feb 2006
Posts
17,673
Location
Surrey
i've got a tracking script which is working well enough to show visitors, however the bots are messing up the results.

at the moment i've got a list of what i don't want from the user agent and do a strpos for each one such as

$findme1 = 'bot';
$findme2 = 'spider';
$pos1 = strpos($mystring, $findme1);
$pos2 = strpos($mystring, $findme2);
if ($pos1 === false && $pos2 === false) {
update tracking
}

however this i know this is no good for doing many times. it's now at 10 checks so i would like a quicker way but unsure how.

thanks
 
Edit

Sorry, misread your question. I'll have a look.

So you have a one string you wish to check against?

$longstring = "thisisaverylongstringlol";

I can't think of an elegant way to do it. You need two nested loops; one to iterate through the array of chars you want to check against and a loop to check each char of the string.

Perhaps you could approach the problem with a different solution.
 
Last edited:
OK bit clearer what you want to do now but nothing springs to mind in regards to a solution. I'll have a think.

Edit

Quite sure there isn't any way round this. You have a collection of N strings you need to check against a single string. That's going to take N iterations, no way around that.
 
Last edited:
Why not use a database? Do a query against the incoming user agent and if it matches an item in the bots table then don't track it.

There are a few sites which list bot user agents so you could start by importing them.
 
Good suggestion.

Is there not any unique information in relation to real users within the useragent (excuse my ignorance)? If so that's just one check.
 
Code:
function containsAnyOf($longString, $arrayOfWords) {
  foreach ($arrayOfWords as $word) {
    if (stripos($longString, $word)) return true;
  }
  return false;
}
 
Can you not run a script that looks for something with bot OR spider OR crawler OR splurp OR yandex and then collect the results and filter them out? So it does it all at once. I dunno how to code though, just guessing!
 
There's still the problem of every condition needing to be checked if it's a real user.

Breaking out of a foreach loop? Bad practice IMO. You foreach when you need to iterate through an entire collection. That isn't always the case here so I would use a while that iterates through the array and some boolean flag to kill the loop when the word is found.
 
Code:
function containsAnyOf($longString, $arrayOfWords) {
  foreach ($arrayOfWords as $word) {
    if (stripos($longString, $word)) return true;
  }
  return false;
}

Needs a type-strict equality check:

PHP:
function containsAnyOf($longString, $arrayOfWords) {
  foreach ($arrayOfWords as $word) {
    if (stripos($longString, $word) !== false) return true;
  }
  return false;
}

There's still the problem of every condition needing to be checked if it's a real user.

Breaking out of a foreach loop? Bad practice IMO. You foreach when you need to iterate through an entire collection. That isn't always the case here so I would use a while that iterates through the array and some boolean flag to kill the loop when the word is found.

It really doesn't matter that much :confused: If anything, a while loop with a flag is less clear and more convoluted than a self-explanatory foreach loop.
 
Last edited:
Well say I need to work on his code in future. I should be able to glance at a function to see what it roughly does (yes I'm aware of comments but sometimes you want to know some finer details). I see a foreach and I assume it's going through the whole collection because, well, that's what they're for.

It's not really an issue no but it does boarder on bad practice.
 
PHP:
<?php

$words = "/bot|spider|crawler|splurp|yandex/i";

if (!preg_match($words, $mystring)) {
update tracking;
}

?>
 
Well say I need to work on his code in future. I should be able to glance at a function to see what it roughly does (yes I'm aware of comments but sometimes you want to know some finer details). I see a foreach and I assume it's going through the whole collection because, well, that's what they're for.

It's not really an issue no but it does boarder on bad practice.

That's a matter of personal interpretation to be honest. Perhaps if the code were much more complex and involved, then it would matter, but for something as trivial as this, it's utterly inconsequential.
 
Last edited:
Back
Top Bottom