I'm trying to store expression in variable and then use it in array_filter to return data based on this value for example
$condition = '== 100';
$test = array_filter($last,function ($data)use ($condition){
return $data['rating'] .$condition;
});
var_dump($test);
I tried to use html_entity_decode($condition, ENT_QUOTES); preg_replace( ) str_replace() as well as trim in order to remove the single quotes but it didn't work
I have many condition and I don't want to write array_filter many times is there a way to do this ? or better way then the one I'm trying to achieve.
I assumed that you have a limited number of comparison operators you are considering. For reasons of simplicity I numbered them 0,1,2,.... They will trigger different kinds of comparisons inside your filter callback function:
funcion myfiltarr($arr,$operator,$value){
$test = array_filter($last,function ($data) use ($operator, $value){
$v=$data['rating'];
switch($operator) {
case 0: return $v == $value;
case 1: return $v < $value;
case 2: return $v > $value;
case 9: return preg_match($value,$v);
// to be extended ...
default: return true;
}
});
return $test
}
$test=myfiltarr($last,0,100); // test: "== 100"
var_dump($test);
$test=myfiltarr($last,9,'/^abc/'); // test: "match against /^abc/"
var_dump($test);
Edit: I extended the original answer by a preg_match() option (comparison code: 9). This option interprets the given $value as a regular expression.
Related
If I have:
$compare = "5<6";
How do I look at the compare variable and return the value true. The input needs to be a string so taking away the " won't help. The string could be very complex so I'm looking for a function already in PHP which can run this, or something that someone has written before which can do this. I've tried the eval() function but that doesn't work, so:
$compare = "5<6";
echo eval($compare);
just errors. Thanks for your help in advance.
Using code evaluation functions are something that should be discouraged, because it may lead to a lot of security problems, but if you want to keep your logic that way, you must evaluate a valid code:
<?php
$compare = "5 > 6";
eval("\$result = $compare;");
var_dump($result);
Your comparing stringmust be used inside the eval function like it would be done in the normal code, not expecting a return value. So what I changed in this sample code is that I used a variable named $result to store the value from the evaluated code.
As you will see when running this code, the $result will be a boolean value (false in this sample, because 5 is not greater than 6, obviously).
Try this:
<?php
$compare = "5<6";
eval('$output = '.$compare.';');
echo $output;
?>
From PHP documentation: http://php.net/manual/en/function.eval.php
Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged.
If you have carefully verified that there is no other option than to
use this construct, pay special attention not to pass any user
provided data into it without properly validating it beforehand.
You can display with echo directly:
<?php
$compare = '5<6';
echo $compare. "\n";
echo eval("return $compare;");
?>
Or You can store result in variable to display later:
<?php
$compare = '5<6';
echo $compare. "\n";
$result = eval("return $compare;");
echo $result;
?>
Be careful ;)
If you wanted to avoid eval it's easy enough to parse comparison expressions. Just split the string on a comparison operator and return the result of the corresponding comparison.
function compare($expr) {
$expr = preg_split('/(>=|<=|<|>|=)/', $expr, -1, PREG_SPLIT_DELIM_CAPTURE);
list($lhs, $op, $rhs) = $expr;
switch ($op) {
case '<': return $lhs < $rhs;
case '<=': return $lhs <= $rhs;
case '>': return $lhs > $rhs;
case '>=': return $lhs >= $rhs;
case '==': return $lhs == $rhs;
}
}
Apparently I missed the bit about "the string could be very complex" when I read the question initially, so this may not be helpful in your case, but I'll leave it here for future reference.
Basically what I'm wondering if there is a way to shorten something like this:
if ($variable == "one" || $variable == "two" || $variable == "three")
in such a way that the variable can be tested against or compared with multiple values without repeating the variable and operator every time.
For example, something along the lines of this might help:
if ($variable == "one" or "two" or "three")
or anything that results in less typing.
in_array() is what I use
if (in_array($variable, array('one','two','three'))) {
Without the need of constructing an array:
if (strstr('onetwothree', $variable))
//or case-insensitive => stristr
Of course, technically, this will return true if variable is twothr, so adding "delimiters" might be handy:
if (stristr('one/two/three', $variable))//or comma's or somehting else
$variable = 'one';
// ofc you could put the whole list in the in_array()
$list = ['one','two','three'];
if(in_array($variable,$list)){
echo "yep";
} else {
echo "nope";
}
With switch case
switch($variable){
case 'one': case 'two': case 'three':
//do something amazing here
break;
default:
//throw new Exception("You are not worth it");
break;
}
Using preg_grep could be shorter and more flexible than using in_array:
if (preg_grep("/(one|two|three)/i", array($variable))) {
// ...
}
Because the optional i pattern modifier (insensitive) can match both upper and lower case letters.
I have 3 variables :
$a = 5;
$b = 3
$o = "*";
The $o variable contains a string value. This value can also be "/", "+", "-".
So when I concatenate $a.$o.$b :
$result = $a.$o.$b;
echo $result;
The result is 5*3 (a string) instead of 15.
So how to convert operator string into real operator ?
You can't, you'd need to make a function or a switch statement to check each of the operators.
Read this question and its answers so you'll understand how to do it.
Actually you can do it, by using eval. But it hurts to recommend using eval, so I just give you a link to another question with a good answer: calculate math expression from a string using eval
You can use eval. For example:
eval('echo 5*3;')
will echo the number 15.
Simple, short and save solution:
$a = 5;
$b = 3
$o = "*";
$simplecalc = function($a,$b,$op) {
switch($op):
case "*":
return $a*$b;
case "+":
return $a+$b;
case "-":
return $a-$b;
case "/";
return $a/$b;
default:
return false;
endswitch;
};
$result = $simplecalc($a,$b,$o);
I believe this is what you are looking for.
$a = 5;
$b = 3;
$o = "*";
$result = eval( "echo $a$o$b;" );
echo $result;
Please note that using eval() is very dangerous, because it allows execution of arbitrary PHP code.
Basically what I'm wondering if there is a way to shorten something like this:
if ($variable == "one" || $variable == "two" || $variable == "three")
in such a way that the variable can be tested against or compared with multiple values without repeating the variable and operator every time.
For example, something along the lines of this might help:
if ($variable == "one" or "two" or "three")
or anything that results in less typing.
in_array() is what I use
if (in_array($variable, array('one','two','three'))) {
Without the need of constructing an array:
if (strstr('onetwothree', $variable))
//or case-insensitive => stristr
Of course, technically, this will return true if variable is twothr, so adding "delimiters" might be handy:
if (stristr('one/two/three', $variable))//or comma's or somehting else
$variable = 'one';
// ofc you could put the whole list in the in_array()
$list = ['one','two','three'];
if(in_array($variable,$list)){
echo "yep";
} else {
echo "nope";
}
With switch case
switch($variable){
case 'one': case 'two': case 'three':
//do something amazing here
break;
default:
//throw new Exception("You are not worth it");
break;
}
Using preg_grep could be shorter and more flexible than using in_array:
if (preg_grep("/(one|two|three)/i", array($variable))) {
// ...
}
Because the optional i pattern modifier (insensitive) can match both upper and lower case letters.
i am trying to get a php if statement to have the rule where if a set variable equals "view-##" where the # signifies any number. what would be the correct syntax for setting up an if statement with that condition?
if($variable == <<regular expression>>){
$variable2 = 1;
}
else{
$variable2 = 2;
}
Use the preg_match() function:
if(preg_match("/^view-\d\d$/",$variable)) { .... }
[EDIT] OP asks additionally if he can isolate the numbers.
In this case, you need to (a) put brackets around the digits in the regex, and (b) add a third parameter to preg_match().
The third parameter returns the matches found by the regex. It will return an array of matches: element zero of the array will be the whole matched string (in your case, the same as the input), the remaining elements of the array will match any sets of brackets in the expression. Therefore $matches[1] will be your two digits:
if(preg_match("/^view-(\d\d)$/",$variable,$matches)) {
$result = $matches[1];
}
You should use preg_match. Example:
if(preg_match(<<regular expression>>, $variable))
{
$variable1 = 1;
}
else
{
$variable2 = 2;
}
Also consider the ternary operator if you are only doing an assignment:
$variable2 = preg_match(<<regular expression>>, $variable) ? 1 : 2;