Forum Moderators: coopster

Message Too Old, No Replies

IF with OR hurting my head

I'm probably looking right past the answer.

         

ianevans

3:25 am on Aug 8, 2003 (gmt 0)

10+ Year Member



The following code is failing me:

In this example, $file="example.jpg"

if ( (strpos($file, '.jpg') === false) ¦¦ (strpos($file, '.JPG') === false)) {
//pass
} else {
//fail
}

In my eyes it should pass the test.

If I just use this statement:

if ( strpos($file, '.jpg') === false) {
//pass
} else {
//fail
}

it works...but I need to be able to test for .JPG as well. Why is my 'or' causing the expression to fail?

Thanks.

MWpro

4:00 am on Aug 8, 2003 (gmt 0)

10+ Year Member



First thing you should do is change the === to == (two equal signs test for equality, not three ;) )

ianevans

7:26 am on Aug 8, 2003 (gmt 0)

10+ Year Member



In the user comments for the strpos function it was suggested that three were necessary...will give it a whirl.

Ross

8:14 am on Aug 8, 2003 (gmt 0)

10+ Year Member



Haha, at last a programming question that I THINK I know the answer to.

Going back 100 years to my COBOL programming days I've seen many of the beginners make the same mistake. You have to be very careful when linking two "not equal" conditions and it's almost always an AND needed in the middle not an OR. Thus :

If we're testing for a value of "X" or "x"

IF VALUE NOT = "X" OR VALUE NOT = "x" - Will always pass the test since VALUE will always not be one of those. If we change the expression to :
IF VALUE NOT = "X" AND VALUE NOT = "x" then we trap both possible X values .

Incidentally, it's much easier to read the code if you remove the double negatives entirely and change your logic to use something like :

IF VALUE = "X" OR VALUE = "x" etc

Ross

adamas

10:42 am on Aug 8, 2003 (gmt 0)

10+ Year Member



Alternatively convert $file to lowercase with strtolower and catch '.jpg' in a single clause whatever the original capitalisation.

vincevincevince

12:21 pm on Aug 8, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Don't use strpos() when a regex is needed!


if (preg_match("/\.jp[e]?g$/i",$file))
{
//pass
} else {
//fail
}

That will give you a case insenstive match which will find .jpg .jpeg .JPG .JPEG .jPg .JpEG etc, and only at the end of the string.

First thing you should do is change the === to == (two equal signs test for equality, not three ;) )

Incorrect. strpos() gives the location of the start of needle within haystack. If we are looking for "test" within "testing" then we will get strpos("testing","test")=0 - and as you know, 0 is == to false. This is why we use the ===. If we do strpos("testing","not") we get a value equal exactly to False - and this is what the === will distinguish.

aspdaddy

12:46 pm on Aug 8, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



if ( (strpos($file, '.jpg') ==false) ¦¦ (strpos($file, '.JPG') == false) )

isnt that the same as:

if (!(strpos($file, '.jpg'==true)) && (strpos($file, '.JPG'==true)))

(de morgans law [lc.brooklyn.cuny.edu])

It cant be lower and upper case at the same time!

vincevincevince

12:50 pm on Aug 8, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




if (!(strpos($file, '.jpg'==true)) && (strpos($file, '.JPG'==true)))

(de morgans law)

It cant be lower and upper case at the same time!

Wrong. Try:


$file = "file.JPG.jpg";


vincevincevince 12:21 pm on Aug. 8, 2003 (utc 0)
Don't use strpos() when a regex is needed!

aspdaddy

1:01 pm on Aug 8, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Of course a regex is better, I agree. It avoids the problem of OR'ing two conditions - by replacing them with one.

But are you saying it cannot be done with an OR?

>$file = "file.JPG.jpg";

So how does your regex help here, should it pass or fail? :)

vincevincevince

1:04 pm on Aug 8, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



aspdaddy - my point with

$file = "file.JPG.jpg";

was that YOUR point "It cant be lower and upper case at the same time!" referring to:

if (!(strpos($file, '.jpg'==true)) && (strpos($file, '.JPG'==true)))

is incorrect - as using the $file I gave as an example, it is passing BOTH the lower case AND the upper case tests.

btw
using my regex:

if (preg_match("/\.jp[e]?g$/i",$file))

it will pass, because it can detect .jpg at the end, and hence all is happy :-)

ianevans

7:12 am on Aug 9, 2003 (gmt 0)

10+ Year Member



if (preg_match("/\.jp[e]?g$/i",$file))

Thanks for the tips. I've used it for a custom 403 page. If the person was trying to access an image directly it looks the image up in the database, finds the page it was on and redirects them to the full page.

Right now I present them with a link, because with the original referer I couldn't do a header:Location as the image wouldn't show because of the hotlinking block.

I tried having the script change the referer variable, but it wouldn't stick.

Still, even with them having to click it beats then seeing the photo without context.

Xuefer

2:07 am on Aug 10, 2003 (gmt 0)

10+ Year Member



if ( (strpos($file, '.jpg') === false) && (strpos($file, '.JPG') === false)) {
//pass
} else {
//fail
}

if ( (strpos(strtolower($file), '.jpg') === false)) {
//pass
} else {
//fail
}

in English:
if (('.jpg' not in $file) and ('.JPG' not in $file)) {
//pass
} else {
//fail
}

by the way, u should FAILed the test when
$file="example.jpg"

i suppose u need
if (('.jpg' is in $file) or ('.JPG' is in $file)) {
//pass
} else {
//fail
}

so:

if ( (strpos($file, '.jpg')!== false) ¦¦ (strpos($file, '.JPG')!== false)) {
//pass
} else {
//fail
}

vincevincevince

10:51 am on Aug 10, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Xuefer, you forgot about .jpeg ;-)
and in your final proposed solution, you forgot about .Jpg as well

aspdaddy

11:10 am on Aug 10, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Its hard to say which solution is *best* when the original post diddnt say exactly what the test should do.

Personally, I'd raher use a single test that just says what passes and then everything else fails.

last 3 digits is jpg or JPG
4th from last is a '.'
first digit is a-z or A-Z or
all others are a-z ¦¦ A-Z ¦¦ '_' ¦¦ 0-9

VinceX3 - Is ther a regex that will do something along those lines?

Xuefer

11:16 am on Aug 10, 2003 (gmt 0)

10+ Year Member



vincevincevince: he said nothing about jpEg :P

if (preg_match("![a-z]\\.jpg!i", $file)) {
// match
}
else {
// not match
}

vincevincevince

11:48 am on Aug 10, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




last 3 digits is jpg or JPG
4th from last is a '.'
first digit is a-z or A-Z or
all others are a-z ¦¦ A-Z ¦¦ '_' ¦¦ 0-9

VinceX3 - Is ther a regex that will do something along those lines?

"/^[a-z][a-z0-9_]*\.jpg$/i"

I'd however add in support for .jpeg as well:

"/^[a-z][a-z0-9_]*\.jp[e]?g$/i"

Xuefer

12:11 pm on Aug 10, 2003 (gmt 0)

10+ Year Member



vincevincevince

you're right, i wa thinking about how to reply you, forgotten what he need :P

ianevans

4:49 pm on Aug 10, 2003 (gmt 0)

10+ Year Member



first digit is a-z or A-Z or all others are a-z ¦¦ A-Z ¦¦ '_' ¦¦ 0-9

Just checking unix file name rules on Google and I couldn't see anything re: the first digit having to be a letter. Am I mistaken?

vincevincevince

5:00 pm on Aug 10, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ian, you are quite right, the filename does not have to start with a letter.

.htaccess