PHP's preg_match() acts weirdly - php

I found this, when I'm working in regex validation in PHP.
I've used preg_match function to validate a string.
I've just printed that value returned by preg_match to ensure working flow.
During that I've found a thing. But can't understand their concept.
That was preg_match() returns 1 if the match found. Otherwise, it will return 0. But sometimes my print function didn't print anything.
After I went through the PHP manual to know all of its return value...
There they posted as follows...
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
And then I used var_dump to know anything is printed or not...
This helped me to know that's a Boolean false.
But I'm curious to know why it returns boolean false, when I'm just putting " ! " (not) before the preg_match()?
Following is my code,
echo preg_match("/script/", "script") // ===> this returns 1
echo !preg_match("/script/", "script") // ===> this returns Boolean false
I think it has to return integer 0 (zero)... What is its functionality? Or did I do anything wrong in syntax?
I've tried this in the OpenCart 2.0.0.0 system administrator controller module.

The ! operator will always return a Boolean value.
For a unary ! operator the type of the result is bool. The value of the operand is converted to type bool and if it is TRUE then the of the operator result is FALSE, and the result is TRUE otherwise.
Language specification reference: Expressions
The normal conversion rules to a bool are applied to the value.

You're not echoing preg_match's return value when you put a ! in front of the function. You're using PHP's operator to determine if it loosely evaluates to true or false.
!preg_match("/script/","script") is the same as preg_match("/script/","script") == false. Note the == and not the ===. 0, null, empty string, and Boolean false will evaluate loosely to false.

Related

PHP 7 strpos bug [duplicate]

This question already has answers here:
php 5 strpos() difference between returning 0 and false?
(5 answers)
Closed 1 year ago.
When using strpos() to find the following, there seems to be a bug.
$url = 'https://www.example.com';
if (strpos($url,'https')>0) the result is NOT found
if (strpos($url,'https',0)>0) the result is NOT found
if (strpos($url,'ttps')>0) the result is FOUND
Why is this happening?
Even though I indicate the starting position of 0, it is not finding it.
Is this a bug or is there something subtle I am missing?
Thanks
Per the manual: https://www.php.net/manual/en/function.strpos.php
Returns the position of [...] the needle [...] note that string positions start at 0, and not 1.
Returns false if the needle was not found
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.
You need to check for strpos === false. Otherwise PHP implicitly converts the 0 to false.
The return value 0 means that the substring was found at position 0 in the searched string.
So, the check for > 0 is wrong.
Documentation says:
Returns the position of where the needle exists relative to the
beginning of the haystack string (independent of offset). Also note
that string positions start at 0, and not 1.
Returns false if the needle was not found. 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.
https://www.php.net/manual/en/function.strpos.php

An expresstion in if statement should return TRUE or FALSE, but it runs a function. PHP

A newbie question.
Here is a function and an if statement.
<?php
function test(){
echo "somedata";
}
if(test())
?>
This code produces:
somedata
According to documentation an if expression should only return TRUE or FALSE, but apart of it, function runs. Why it happens?
PHP evaluates the if expression in order to know if the epression yields a truthy value or not. There is no other way to find out than to execute the functions that appear in the expression.
In this example it is very clear:
if (sqrt(4) > 1)
PHP must of course call the function sqrt, except that in this case it is a function without side-effects, while your function test also performs an echo. Secondly, it returns a value, while test doesn't. But that PHP can only find out by executing the function.
Note that the expression can in general return anything, but PHP has rules to what it considers truthy or falsy:
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
In case a function runs without executing a return statement, the returned value is null, so the if condition will be falsy according to the above rules.

Changing database value to false doesn't change result

I have this code
if (true == $run_user['online'] {
$result = 'Online now!';
} else {
$date = $run_user['lastloggedin'];
$result = Agotime($date);
}
$run_user is to check the database by the way
So whenever I change the value in the database to false, it will still just result "Online Now!" Instead of saying what it's supposed to say, which is for example 1 hour ago.
#John Conde had it right, but I can expound on what is actually happening.
In PHP there are certain things that will be left for interpretation. Boolean checks are one of those things. Here is a couple lists of things that will be interpreted in a Boolean check:
These will be interpreted as TRUE
Boolean true, of course
Non-empty strings
Any non-zero integer
A function, object or array
These will be interpreted as FALSE
Boolean false
The integer 0
An empty string
null
The not (!) character followed by an interpreted true or Boolean true
These might be confusing at times, but the best thing to do for checking is to make sure you know what type of variables you are passing into the conditional. Sometimes it may be useful to use a strict comparator like so:
if(true === $variable){ ... }
The third equal sign will tell PHP to only interpret this as true/false if it is EXACTLY what I am comparing it to. So $variable = true; would work, but $variable = 1; would not. Without the strict comparator, both versions would work. This issue comes into play a lot when you are working with integers where 0 needs to be interpreted as true and null should be false.

strpos issue with 0==false?

I'm using strpos to find the position of a string in another string. I first check if the string is found at all in there. Here's my line:
if (strpos($grafik['data'],$ss1)<>false && strpos($grafik['data'],$ss2)<>false && strpos($grafik['data'],$ss1) < strpos($grafik['data'],$ss2))
I check if both strings are contained and then I want the first one to be placed before the second one. In the php manual it says that strpos returns false when string is not found. However if my string starts at the zero position (strpos returns 0 since its the beginning), it seems like this statement
strpos($grafik['data'],$ss1)<>false
is false. Somehow 0==false ? How do I make the statement true when strpos returns 0 ?
From http://www.php.net/manual/en/function.strpos.php:
Warning
This function may return Boolean
FALSE, but may also return a
non-Boolean value which evaluates to
FALSE, such as 0 or "". Please read
the section on Booleans for more
information. Use the === operator for
testing the return value of this
function.
You have to use the === operator instead of ==.
In your case, instead of using <>, use !==:
strpos($grafik['data'], $ss1) !== false
This will return TRUE if $ss1 is found in $grafik['data']
You need to check with ===. This will make sure you have exact false and not 0.
This function behaves unpredictably, so to be sure it'll have deterministic behavior use either
if(strpos($text,$string)===false)
or test it using a variable
$pos=strpos($text,$string);
if($pos===false)

Find text in string in PHP

This should be pretty straightforward, but I can't seem to find an explanation anywhere on how to do it.
I have a string in PHP. That string might contain within it somewhere the substring ":ERROR:". I need to find if it has that string. strpos() has worked perfectly up to this point, until today when ":ERROR:" was the first item in the string, so strpos() returned 0, so the program kept running thinking it had no error.
I don't need to replace the string, or do any manipulation to it, I just need a simple true/false answer to "does :ERROR: exist in the string?"
strpos returns false when the string is not found, so check for false instead of making an implicit condition.
if(strpos($string, ':ERROR:') !== false) {
// Do something...
}
As Anurag said in the comments, with functions like these it's always best to do a strict comparison (=== instead of just leaving out the operator or using ==) because that's a common source of bugs, especially in PHP, where many functions can return values of different types.
The PHP Manual on strpos():
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE, such as 0 or "". Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
if (strpos($myString, ":ERROR:") !== FALSE) {
// Error!
}
You can also avoid the strpos() problems of not checking with a strict type operator by using the lesser known strstr()
if(strpos($string, ':ERROR:') !== false){
//found ':ERROR:' in string
}
"[strpos()] [r]eturns the position as an integer. If needle is not found, strpos() will return boolean FALSE."
http://php.net/manual/en/function.strpos.php
If the position is 0, then merely using == or != will evaluate 0 and false as equivalent. So use === or !== to avoid type coercion.

Categories