...

View Full Version : Problem with !==



doubledee
10-07-2012, 11:20 PM
I am having trouble with the code below...



<?php
$body = 'xxx';

if (preg_match('~([0-9-]+)~', $body) !== false){
echo 'Image Found';

}else{
echo 'Image Not Found';

}
?>

Regardless of the value I put in for $body, my code is resolving to the THEN branch?! :confused:

('xxx' should not yield a match, and so the ELSE branch of my code should fire.)


According to the PHP Manual (http://php.net/manual/en/function.preg-match.php)...


preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
Warning

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.


So 'xxx' should return '0' and since I am using '!==' shouldn't things resolve to the ELSE branch?? :-/

Thanks,


Debbie

Fou-Lu
10-07-2012, 11:57 PM
I don't follow you here.
If I enter a body of 'ok', then this works as expected. If I enter a body of 'ok ' then it still enters the if branch even though there is no match. That is correct; regardless of of a match has occurred, your code only checks if it fails outright which is from a bad pattern.

So according to the PHP manual and the code you have here, it is functioning as expected. You only get to the else branch if the pattern fails to compile.

doubledee
10-08-2012, 12:18 AM
I don't follow you here.
If I enter a body of 'ok', then this works as expected. If I enter a body of 'ok ' then it still enters the if branch even though there is no match. That is correct; regardless of of a match has occurred, your code only checks if it fails outright which is from a bad pattern.

So according to the PHP manual and the code you have here, it is functioning as expected. You only get to the else branch if the pattern fails to compile.

Sorry, I haven't eaten since yesterday and my brain is fading!!!


Okay, so a few follow up questions...

1.) What are the benefits of using...



if (preg_match('~([0-9-]+)~', $body) !== false){


versus



if (preg_match('~([0-9-]+)~', $body)){



If I use the second - which I always have - am I opening myself up to problems?



2.) If you say "Yes, you should use !== false in the above code", then how do I check for a failure but also make it so both my THEN and ELSE fire??


3.) On another issue, someone helped me this code...


if (preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/', $body, $matches, PREG_SET_ORDER) !== false){
// Loop through array.
foreach ($matches as $match){
$body = str_replace($match[0], generateArticleCrossLink($dbc, $match), $body);
}

}



And I unknowingly changed my code to this...


if (preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/', $body, $matches, PREG_SET_ORDER) !== false){
// Cross-Links Found.

// Loop through array.
foreach ($matches as $match){
$body = str_replace($match[0], generateArticleCrossLink($dbc, $match), $body);
}

}else{
// Cross-Links Not Found.
// Do nothing...
}


So it looks like my code won't work like I thought it would, right?

Again, any suggestions there to do what I intended?

Thanks,


Debbie

Fou-Lu
10-08-2012, 12:23 AM
The only reason to check beyond a loose true and false is to determine if the pattern failed (or as of 5.3.6, that the offset is > the length provided). There's no reason why you cannot make use of an elseif should you need to know if the pattern is bad:


if (($result = preg_match('...', $var, $matches)) === false)
{
// bad pattern
}
else if ($result)
{
// matches
}
else
{
// no matches.
}


Although realistically you should catch a bad failure during development as it will trigger a warning.

doubledee
10-08-2012, 12:29 AM
The only reason to check beyond a loose true and false is to determine if the pattern failed (or as of 5.3.6, that the offset is > the length provided). There's no reason why you cannot make use of an elseif should you need to know if the pattern is bad:


if (($result = preg_match('...', $var, $matches)) === false)
{
// bad pattern
}
else if ($result)
{
// matches
}
else
{
// no matches.
}


Although realistically you should catch a bad failure during development as it will trigger a warning.

What do you mean by a "bad pattern"?

Do you mean invalid Regex syntax?

Or is it like a "logical error" with my Regex?

If it deals with bad syntax, then is that really necessary, even in development?

Thanks,


Debbie

Fou-Lu
10-08-2012, 12:34 AM
Bad pattern as in invalid syntax; the pattern failed to compile (or as mentioned 5.3.6 introduced a false return if the offset > strlen of the subject). Pattern logic will only fail if it fails to compile (bad recursion, impossible case scenarios, etc). These are still syntactical failures, but only because the pattern is detected as uncompilable due to logical evaluation issues.

Well, its necessary in the sense that you need to fix a bad pattern. If you don't, it will always return false which if used loosely would give the appearance of no match.

doubledee
10-08-2012, 12:49 AM
Bad pattern as in invalid syntax; the pattern failed to compile (or as mentioned 5.3.6 introduced a false return if the offset > strlen of the subject). Pattern logic will only fail if it fails to compile (bad recursion, impossible case scenarios, etc). These are still syntactical failures, but only because the pattern is detected as uncompilable due to logical evaluation issues.

Well, its necessary in the sense that you need to fix a bad pattern. If you don't, it will always return false which if used loosely would give the appearance of no match.

So put another way, a Regex syntax error will fail to compile but not cause my script to fail or throw any errors that would let me know I have a syntactically invalid Regex?

If that is the case, then it sounds like your suggestion above would be the way to go, huh?


So if I wanted to fix my earlier code which was this...


// Find all Cross-Links in Article.
if (preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/', $body, $matches, PREG_SET_ORDER) !== false){
// Cross-Links Found.

// Loop through array.
foreach ($matches as $match){
$body = str_replace($match[0], generateArticleCrossLink($dbc, $match), $body);
}

}else{
// Cross-Links Not Found.
// Do nothing...
}



Would this do it...


if (($result = preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/', $body, $matches, PREG_SET_ORDER)) === FALSE){
// Bad Pattern.
// Now what do i do???

}else if ($result){
// Cross-Links Found.

// Loop through array.
foreach ($matches as $match){
$body = str_replace($match[0], generateArticleCrossLink($dbc, $match), $body);
}

}else{
// Cross-Links Not Found.
// Do nothing...

}


Thanks,


Debbie

Fou-Lu
10-08-2012, 04:37 AM
The second one does make more sense logically. If you fail to match, $matches would still have one item of nothing within it (at least I think it does), so you would end up iterating once with a non-functional result. The problem with it is that you would replace any instance of "" with whatever the content is (which is no replacement because you cannot match to anything but empty).
Although if you are planning on replacing anyway, you may as well skip the preg_match and just use a preg_replace. Using the 'e' modifier will let you write code that can be called with eval to replace at runtime what the variables of a backreference would be.

BTW, if a pattern fails to compile it will issue an E_WARNING. I'm not sure why the API doesn't specify this, although the return result doesn't guarantee that it will raise this as the length versus the offset isn't an actual error.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum