Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 10-07-2012, 10:20 PM   PM User | #1
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 640
Thanks: 20
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Problem with !==

I am having trouble with the code below...

PHP Code:
<?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?!

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


According to the PHP Manual...

Quote:
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
doubledee is offline   Reply With Quote
Old 10-07-2012, 10:57 PM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,750
Thanks: 4
Thanked 2,468 Times in 2,437 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Old 10-07-2012, 11:18 PM   PM User | #3
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 640
Thanks: 20
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Quote:
Originally Posted by Fou-Lu View Post
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...

PHP Code:
    if (preg_match('~([0-9-]+)~'$body) !== false){ 
versus

PHP Code:
    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...
PHP Code:
if (preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/'$body$matchesPREG_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...
PHP Code:
if (preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/'$body$matchesPREG_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
doubledee is offline   Reply With Quote
Old 10-07-2012, 11:23 PM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,750
Thanks: 4
Thanked 2,468 Times in 2,437 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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:
PHP Code:
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.
Fou-Lu is offline   Reply With Quote
Old 10-07-2012, 11:29 PM   PM User | #5
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 640
Thanks: 20
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Quote:
Originally Posted by Fou-Lu View Post
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:
PHP Code:
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
doubledee is offline   Reply With Quote
Old 10-07-2012, 11:34 PM   PM User | #6
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,750
Thanks: 4
Thanked 2,468 Times in 2,437 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Old 10-07-2012, 11:49 PM   PM User | #7
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 640
Thanks: 20
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Quote:
Originally Posted by Fou-Lu View Post
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...
PHP Code:
    // Find all Cross-Links in Article.
    
if (preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/'$body$matchesPREG_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...
PHP Code:
    if (($result preg_match_all('/\\{url=([a-zA-Z0-9-]+)\\}/'$body$matchesPREG_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
doubledee is offline   Reply With Quote
Old 10-08-2012, 03:37 AM   PM User | #8
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,750
Thanks: 4
Thanked 2,468 Times in 2,437 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 06:52 PM.


Advertisement
Log in to turn off these ads.