0

Apologies, I screwed up on title and question, I believe both are now fixed. It looked like I was looking for "OR", whereas I am looking for "AND".

I have several files in a folder:

this-is-big-needle1.jpg

a-big-long-needle1.jpg

this-file-is-needle2.jpg

needle3-is-this-file.jpg

The current code && strpos($file,"needle1") is used to search a folder and inlcude all files that that match the strops value eg "needle1" and include these images in an AMP HTML carousel.

So current code searches for "needle1" and will correctly return the first 2 files above but ignore the others.

I have searched and found several general solutions for finding if needle1 OR needle2 are present in filename, but found nothing were both "big" and "needle1" are found in the same filename.

I have tried adding a second strops && strpos($file, "needle1") && strpos($file, "big") but my php skills are very lacking so get easily tripped up with syntax and were to put eg '..' etc

php
$Count5Image5 = 0;
$Image5;
$handle = opendir(dirname(realpath(__FILE__)).'/images/');
while($file = readdir($handle)){

    if($file !== '.' && $file !== '..' && strpos($file,"needle1")) 
{
        Image5[$Count5Image5] = $file;
        $Count5Image5++;
    }
}
sort($Image5);
for($i=0; $i<$Count5Image5; $i++)
  echo '<amp-img src="images/'.$Image5[$i].'" class="xs-12" width="353" height="210" layout="responsive"></amp-img>';
?>

If someone could suggest an edit of my code to find "big" & "needle1" in the same filename (to return top two files) it would be appreciated.

========== A litte side issue (in case there is an obvious solution) - for some reason existing code will not find any file if the strops value is at the start of the file name eg if I enter value "this-" it will not find any files or if I enter needle3 it will not find any files (string must be after character1 in the string)

ColinK
  • 31
  • 6

2 Answers2

1

Maybe you can replace:

if($file !== '.' && $file !== '..' && strpos($file,"needle1"))

With:

if($file !== '.' && $file !== '..' && ( strpos($file,"needle1") !== false || strpos($file,"needle2") !== false )

This would match all files having needle1 or needle2 in the name.

Please note the !== false I added after each strpos(). This helps you with the side issue you mentioned. strpos returns false if needle is not found and 0 in case the filename starts with the needle. They both evaluate as false in an if statement context ( you can read more here ).

Preg_match alternative

This would be another nice way to match both big and needle no matter the order in which they appear in the filename.

if(preg_match("/(big|needle1)/i", $file) !== 0) {

} 

This would match both: this-is-big-needle1.jpg and this-needle1-is-big.jpg as can be seen here: regex test

Alternative

Another nice way of doing it would be to use the glob() function:

That way you could only get the files that match those filenames:

foreach (glob("{*needle1*,*needle2*}.*", GLOB_BRACE) as $filename) {
    echo $filename."<br />";
}

Hope that helps.

Cornel Raiu
  • 2,758
  • 3
  • 22
  • 31
  • Cornel.raiu Apologies I just realised I screwed up my question. (I have edited) I want to find files that contain "big" AND "needle". I realise my wording was asking for OR. I will look at your reply when on my desktop to see if it helps. – ColinK Sep 07 '19 at 17:27
  • if you want to only get the ones with "big" and "needle" for example "the big needle" you can just do: `if($file !== '.' && $file !== '..' && ( strpos($file,"needle1") !== false && strpos($file,"needle2") !== false )` – Cornel Raiu Sep 07 '19 at 17:49
  • Great that works. You had included my original incorrect needle1 & needle2 but amended to "big" and "needle1" works fine. First two files are found, others are ignored. if($file !== '.' && $file !== '..' && ( strpos($file,"this") !== false && strpos($file,"needle") !== false ) – ColinK Sep 07 '19 at 19:56
  • For some reason my previous additional issue of the initial character not working is now OK. So if I include "this" and "needle" then files 1, 3 & 4 are found. – ColinK Sep 07 '19 at 19:58
  • Due to getting thrashed with every previous question I have less than 15 points so cannot up-vote the revised answer from cornel.raiu. Even though I screwed up on the original question (twice) I really appreciate your patience and working answer. Still keen to read other suggestions, particularly using preg_match which might be useful in another situation. – ColinK Sep 07 '19 at 20:02
  • @ColinK I also added a preg_match alternative. Let me know if that helped. If it did, please mark the answer as accepted :) Thanks! – Cornel Raiu Sep 08 '19 at 15:04
1

The issue you are running into is the one the manual references,

This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.

-https://www.php.net/manual/en/function.strpos.php

So !== is what you should use for the comparison.

Since you are doing pattern matching though I would just use a regex with preg_match.

preg_match('/needle[12]/', $file)

The [] is a character class and allows all characters listed inside it, with some exceptions, https://www.regular-expressions.info/charclass.html.

user3783243
  • 5,368
  • 5
  • 22
  • 41
  • I assume you answered the question around the time I fixed to show that I want to find "needle1" and "big" in ther same filename. I have done some reading on preg_match and see the benefits. If you could edit your code suggestion to match my revised question it would be appreciated. – ColinK Sep 07 '19 at 19:39
  • Is `needle2` also still needed to be matched? Is the location of `big` always after `needleX`? – user3783243 Sep 08 '19 at 13:09
  • @user3783243 it does not matter. You need to match both in whatever the order. Also, it might have the case when it needs to match 10 substrings. We can't know that. – Cornel Raiu Sep 08 '19 at 15:06