I am making very simple program in PHP . Tryig to addition first ..
But dont know ..
Here is code
<?php
$a=12;
$b=10;
$c="+";
$res=$a."$c".$b;
echo $res;
?>
it output 12+10 as it is concecate..
$c is anything.
Any idea how to do this
$c is now a string and not a expression "+" is not equal to +.
So:
$res=$a + $b;
If you would really need your structure you would have to do something evil like using eval() or you could do:
$a=12;
$b=10;
$operator='+';
switch($operator) {
case '+':
$res=$a + $b;
break;
case '-':
$res=$a - $b;
break;
}
What do you want to do exactly?
If you have the operator as a string, you could try a switch statement:
<?php
$a=12;
$b=10;
$c="+";
switch($c) {
case '+':
$res = $a + $b;
break;
case '-':
$res = $a - $b;
break;
}
var_dump($res);
?>
Yes, also PHP has an eval(uate) function:
$res = eval($a . $c . $b);
Be sure that $a, $b and $c do not stem from form input, as eval can delete and so on.
Related
The problem I have is the following: I have a variable number of array items, so I can not have a fix number of if then else. In any case, it can not exceed 50 items.
This is the main-standard body. How to build as many if then else conditions as the count of an array on the fly ?
$number = count($array);
if (($a > $b) && ($a <= $b)) {
} else
You are trying to use Switch in fact, please read : http://php.net/manual/fr/control-structures.switch.php
switch ($number) {
case 0:
echo "a";
break;
case 1:
echo "b";
break;
case 2:
echo "c";
break;
}
This is a bit of a guess, as we don't precisely know what you are trying to achieve, but to answer your question "How to build as many if then else conditions as the count of an array on the fly?":
<?php
$array = array(1,2,5,8,10,15);
$number = count($array);
$b = 7; // we don't know yet what $a and $b could be
for ($i=0;$i<$number;$i++) {
if($array[$i]>$b) { // what ever condition you want here
// do smth
} else {
// do smth else or nothing
}
}
?>
I am trying to avoid duplicating my code by checking the variable if it is a certain operator.
Basically..
$op = $_POST['operator'];
$x = 5;
$y = 2;
$result = $x /* $op instead of '+'/'-'/'*'/'/'/'%' */ $y;
Is this possible or will I have to send the operator as a String and duplicate the code per operator type?
It's a lot safer to do something like this:
$x = 5;
$y = 2;
switch($_POST['operator']){
case '+':
$result = $x + $y;
break;
case '-':
$result = $x - $y;
break;
case '*':
$result = $x*$y;
break;
case '/':
$result = $x/$y;
break;
case '%':
$result = $x % $y;
break;
default:
$result = 'Operator not supported';
}
Something along those lines.
Ahem. You can eval.
$result = eval("$x $op $y");
But this is DANGEROUS and you should sanitize your variables with great care. There is a saying that goes something like "If your problem requires use of eval, then the problem is wrong." Something like that. It's almost certainly preferable to do something like this:
function apply_op($x, $y, $op) {
switch ($op) {
case '+': return $x + $y;
...
}
}
you can make this:
$operators = array("+", "-","*","%","/");
$op = $_POST["operator"];
if(in_array($op, $operators)) {
echo eval("$x $op $y");
} else {
echo "Operator not supported";
}
I'm writing a function which will be used to limit too long strings. I want to avoid duplicated code so I thought that putting almost whole function "logic" into return expression will be better than checking condition in every switch's case. But let's see code:
function test($mode, $string) {
$x = strlen("...");
$overThr = function($x, $y){strlen($string) >= $y + $x + 1;};
switch ($mode) {
case 'artist_week':
$y = 29;
break;
case 'songs_week':
$y = 31;
break;
}
return (substr($string, 0, $overThr($x, $y) ? $y : strlen($string))) . ($overThr($x, $y) ? "..." : "");
}
as you can see I want to use $overThr as a flexible condition in a ternary operator. But I can't figure out why every time $overThr is executed in "return" expression it's always returns false.
$a = test('songs_week', 'razdwatrzyczterypiecszescsiedemrazdwatrzyczterypiecszescsiedem');
echo $a;
//razdwatrzyczterypiecszescsiedemrazdwatrzyczterypiecszescsiedem
does somebody know? :)
$string is not defined within the closure and you forgot the return statement
function ($x, $y) use ($string) {
return strlen($string) >= $y + $x + 1;
};
You're using $string in the lambda, but not passing it in as a parameter or definining it as global within the lambda, so it's null/empty.
if (foo >= bar) baz();
But let's say sometimes baz(); needs to be run when foo <= bar, or foo == bar... and let's say that this comparison operator is grabbed from, say, a db table, and placed into a variable: $param = ">=".
Is there any way you could modify the first line to use $param, besides a switch-case with multiple if statements?
In my code, baz(); spans about a whole bunch of lines, and would become an organizational nightmare were I to manage it by hand.
function lt($a, $b)
{
return $a < $b;
}
...
$relops = Array(
'<' => 'lt',
...
);
echo $relops['<'](2, 3);
I solved this using:
function doComparison($a, $operator, $b)
{
switch ($operator) {
case '<': return ($a < $b); break;
case '<=': return ($a <= $b); break;
case '=': return ($a == $b); break; // SQL way
case '==': return ($a == $b); break;
case '!=': return ($a != $b); break;
case '>=': return ($a >= $b); break;
case '>': return ($a > $b); break;
}
throw new Exception("The {$operator} operator does not exists", 1);
}
Use eval()?
$param = ">=";
eval ("if (foo $param bar ) baz();");
Read more on the documentation page for the eval function.
EDIT:
Indeed, as others have mentioned, if there are alternatives, they are almost always better than eval(). If used, it must be used with care.
elaborating on my comment:
function variableOpComparison($v1, $v2, $o) {
if ($o == '!=') return ($v1 != $v2); // could put this elsewhere...
$operators = str_split($o);
foreach($operators as $operator) {
switch ($operator) { // return will exit switch, foreach loop, function
case '>': if ($v1 > $v2) return true; else continue; break;
case '<': if ($v1 < $v2) return true; else continue; break;
case '=': if ($v1 == $v2) return true; else continue; break;
default: throw new Exception('Unrecognized operator ' . $operator . ' in ' . $o);
}
}
return false;
}
I wrote this:
$num1 = mt_rand(1,5);
$num2 = mt_rand(1,5);
$operators = array(
"+",
"-",
"*",
"/"
);
$result = $num1 . $operators[array_rand($operators)] . $num2;
(My best guess is) This doesn't work as I expected because in the array the operator is a string which makes everything a string:
var_dump($result);
Gives:
string(3) "4+3"
So my question would be how would you recommend approaching this* without changing the logic it too much?
Thanks in advance!!
*Making random operation among random numbers, and if possible, the operators should be stored in an array.
I have the feeling my title is not correctly describing the situation but I could not come up with a better idea, I'm open to suggestions :)
Of course, you could use eval to do this, but I certainly won't settle for such a solution.
I'd suggest defining a bunch of functions that take in two params and return a result, then use call_user_func_array on the result of array_rand.
function add($x, $y) { return $x + $y; }
function subtract($x, $y) { return $x - $y; }
function multiply($x, $y) { return $x * $y; }
function divide($x, $y) { return $x / $y; }
$operators = array('add', 'subtract', 'multiply', 'divide');
//...
$result = call_user_func_array($operators[array_rand($operators)], array($x, $y));
<?php
$num1 = mt_rand(1, 5);
$num2 = mt_rand(1, 5);
$operators = array(
"+",
"-",
"*",
"/"
);
switch ($operators[array_rand($operators)]) {
case "+":
$result = $num1 + $num2;
break;
case "-":
$result = $num1 - $num2;
break;
case "*":
$result = $num1 * $num2;
break;
case "/":
$result = $num1 / $num2;
break;
}
var_dump($result);
The clean solution would be to have a code branch for each operator, e.g.
function do_something($num1, $num2, $operator) {
switch ($operator) {
case '+':
return $num1 + $num2;
case '-':
return $num1 - $num2;
case '*':
return $num1 * $num2;
case '/':
return $num1 / $num2;
default:
throw new Exception('Unknown operator: '.$operator)
}
}
If you have more operators, you should create a map of operator => function and dynamically call the functions, for example:
$ftable = array(
'+' => 'fn_add',
'-' => 'fn_sub',
'*' => 'fn_mul',
'/' => 'fn_div'
);
function fn_add($a, $b) { return $a + $b; }
function fn_sub($a, $b) { return $a - $b; }
function fn_mul($a, $b) { return $a * $b; }
function fn_div($a, $b) { return $a / $b; }
function do_something($num1, $num2, $operator) {
global $ftable;
if (array_key_exists($operator, $ftable)) {
return call_user_func($ftable[$operator], $num1, $num2);
}
else {
throw new Exception('Unknown operator: '.$operator)
}
}
And of course, the unclean (slow, potentially dangerous) solution would be to use eval().
Create a function for each operation, then store operator => function name in an array.