If logic (predicate expression) in a variable - php

I'm passing the comparison operator as a variable to the PHP Cli:
./test.php -k "command" -c ">0"
The command in -k products a result and I've stored it in $result
The problem I'm getting is I want to pass the logic and comparison operator as variables, is this possible?
$result = 2;
$logic = ' >0';
if ( $result $logic ) echo "true";
But I get:
PHP Parse error: syntax error, unexpected '$logic' (T_VARIABLE)
Any ideas?

It's not possible to do it that way, but you can do it using the eval method, like this:
$result = 2;
$logic = ' >0';
eval('$logicResult = ' . $result . $logic .';');
if ( $logicResult ) echo "true";
The eval method is not recommended, as it might introduce security flaws in your app.

While eval does the trick, it is generally considered harmful.
If the universe of possible operator instances in $logic is limited, better work with a switch statement or a cascaded if:
$result = 2;
$logic = trim(' <0');
$op2 = substr($logic, 0, 2);
$op1 = substr($logic, 0, 1);
if ( $op2 == '>=') {
$operand = substr($logic, 2);
if ($result >= (int)$operand) { echo "true"; }
} elseif ( $op1 == '>' ) {
$operand = substr($logic, 1);
if ($result > (int)$operand) { echo "true"; }
} elseif ( $op1 == '=' ) {
$operand = substr($logic, 1);
if ($result == (int)$operand) { echo "true"; }
} elseif ( $op2 == '<=') {
$operand = substr($logic, 2);
if ($result <= (int)$operand) { echo "true"; }
} elseif ( $op1 == '<' ) {
$operand = substr($logic, 1);
if ($result < (int)$operand) { echo "true"; }
} else {
echo "operator unknown: '$logic'";
}

As #treyBake notice, you can use eval() - Evaluate a string as PHP code:
<?php
$result = 2;
$logic = 'if(' . $result . '>0){echo "true";};';
eval($logic);

Related

Multiple lines if statements

I am checking around 20 variables like the following and I was wondering if there is a faster way (less lines) to do the same:
if ($data1 == 1) {
$res1 = "Yes";
} else {
$res1 = "No";
}
if ($data2 == 1) {
$res2 = "Yes";
} else {
$res2 = "No";
}
if ($data3 == 1) {
$res3 = "Yes";
} else {
$res3 = "No";
}
etc..
There are a few ways:
1) foreach loop:
$array = [$data1, $data2, $data3];
foreach ($array as $key => $value)
{
${'res'. $key} = ($value == 1 ? 'yes' : 'no');
}
Although as Qirel pointed out, this probably isn't the best thing to do. If you need to name new values $name. $x then it's probably better as an array:
$array = [$data1, $data2, $data3];
$res = [];
foreach ($array as $key => $value)
{
$res[$key] = ($value == 1 ? 'yes' : 'no');
}
2) function:
function checkVal($value)
{
return ($value == 1 ? 'yes' : 'no');
}
$res1 = checkVal($data1);
3) ternary - not necessarily not repeating code, but it's shorter:
$res1 = ($data1 == 1 ? 'yes' : 'no')
$res2 = ($data2 == 1 ? 'yes' : 'no')
$res3 = ($data3 == 1 ? 'yes' : 'no')
This should also work -
// number of variables to check
$num = 3;
// Loop for checking all the variables as per naming convnetions followed
for ($i = 1; $i <= $num; $i++) {
// set yes/no depending on the data set
${'res' . $i} = ${'data' . $i} == 1 ? 'yes' : 'no';
}
I don't know the context but from what I can see my advice is to create an array of $data1, $data2, $dataN and loop all these values to create another array with all checks
$values = [$data1, $data2, $data3, $data4];
$responses = array_reduce($values, function ($a, $b) {
$a[] = 1 === $b;
return $a;
}, []);

PHP empty variable inside condition

I have a condition in which it is using a variable to pull either a number through 0-17, the string "MAKEUP", or the variable will be empty. I would like it to output the text "WIN" if the variable is greater than the number 8 and "LOSS" if the variable is less than the number 9. I would also like it to out "MAKEUP" if the variable consist of the string MAKEUP, and to display nothing if the variable is empty. Seems pretty simple to me, but I'm having issues particularly with the empty part. Can anyone let me know what I am doing wrong here? Code below
<?php
$t1w8 = '';
$result = $t1w8;
if ($result > 8 && !empty($result)) {
echo 'WON';
} elseif ($result < 9 && !empty($result)) {
echo 'LOSS';
} elseif ($result == 'MAKEUP') {
echo '-';
} else {
echo 'yooo';
}
?>
Make some changes in your conditions like this
<?php
//$result = "MAKEUP";
$result = 0;
if ($result === 'MAKEUP') {
echo '-';
}else if (is_numeric($result) && $result < 9 ) {
echo 'LOSS';
}else if (is_numeric($result) && $result >= 9 ) {
echo 'WON';
} else{
echo 'yooo';
}
?>
Live demo : https://eval.in/897120
try with this code
<?php
//$result = "MAKEUP";
$result = "";
//$result = "9";
//$result = "-";
if ($result == 'MAKEUP' && !empty($result) ) {
echo '-';
} elseif ($result > 8 && !empty($result)) {
echo 'WON';
} elseif ($result <= 8 && !empty($result)) {
echo 'LOSS';
} else {
echo 'yooo';
}
?>
for demo :demo code here
You have explained that your number range is from 0-17.
You have also explained that you could get the word MAKEUP.
Based upon those constraints we could use something like this
$output = "";
// Do we have something?
if(strlen($result) > 0) {
if (strtolower($result) == "makeup") {
$output = "MAKEUP";
}
// assumes a single digit string
else if ($result < 9) {
$output = "LOSS";
} else if ($result <= 17) {
$output = "WIN";
}
}
echo $output;

PHP: Assign multiple variables in if statement

I don't seem to be able to assign multiple variables in an "if" statement. The following code:
<?php
function a ($var)
{
if ($var == 1)
{
return 'foo';
}
return false;
}
function b ($var)
{
if ($var == 1)
{
return 'bar';
}
return false;
}
if ($result1 = a(1) && $result2 = b(1))
{
echo $result1 . ' ' . $result2;
}
?>
Returns "1 bar" rather than "foo bar". If I remove the second condition/assignment it returns "foo".
Is there a way to assign multiple variables in an "if" statement or are we limited to just one?
This is all about operator precedence
<?php
function a ($var)
{
if ($var == 1)
{
return 'foo';
}
return false;
}
function b ($var)
{
if ($var == 1)
{
return 'bar';
}
return false;
}
if (($result1 = a(1)) && ($result2 = b(1)))
{
echo $result1 . ' ' . $result2;
}
?>
https://repl.it/IQcU
UPDATE
assignment operator = is right-asscoiative, that means, evaluation of operand on rhs has precedence over the lhs operand.
thus,
$result1 = a(1) && $result2 = b(1)
is equivalent of,
$result1 = (a(1) && $result2 = b(1))
which evaluates
$result1 = ("foo" && [other valild assignment] )
which will result that,
$result1 becomes true
and echo true/string value of boolean true (strval(true)) outputs/is 1
you can also check that revision, https://repl.it/IQcU/1
to see that below statement
$result1 = a(1) && $result2 = b(1)
is equivalent of this one.
$result1 = (a(1) && $result2 = b(1))
Need to add parentheses() in each assignment like below:-
if (($result1 = a(1)) && ($result2 = b(1)))
{
echo $result1 . ' ' . $result2;
}
Output:- https://eval.in/804770
Correct explanation is given by #marmeladze here:-
Why 1 bar is coming through OP's code
The last if statements need some brackets, it should have been:
if (($result1 = a(1)) && ($result2 = b(1)))
{
echo $result1 . ' ' . $result2;
}
This ensures that things in the bracket are executed first and it will help.
You have to add == to check a condition.
Try this,
if ($result1 == a(1) && $result2 == b(1))
{
echo $result1 . ' ' . $result2;
}
Checked with belo example
<?php
function a ($var)
{
if ($var == 1)
{
return 1;
}
return false;
}
function b ($var)
{
if ($var == 1)
{
return 2;
}
return false;
}
if (1 == a(1) && 2 == b(1))
{
echo 'success';
}
?>

Using PHP write an anagram function?

Using PHP write an anagram function? It should be handling different phrases and return boolean result.
Usage:
$pharse1 = 'ball';
$pharse2 = 'lbal';
if(is_anagram($pharse1,$pharse2)){
echo $pharse1 .' & '. $pharse2 . ' are anagram';
}else{
echo $pharse1 .' & '. $pharse2 . ' not anagram';
}
There's simpler way
function is_anagram($a, $b) {
return(count_chars($a, 1) == count_chars($b, 1));
}
example:
$a = 'argentino';
$b = 'ignorante';
echo is_anagram($a,$b); // output: 1
$a = 'batman';
$b = 'barman';
echo is_anagram($a,$b); // output (empty):
function is_anagram($pharse1,$pharse2){
$status = false;
if($pharse1 && $pharse2){
$pharse1=strtolower(str_replace(" ","", $pharse1));
$pharse2=strtolower(str_replace(" ","", $pharse2));
$pharse1 = str_split($pharse1);
$pharse2 = str_split($pharse2);
sort($pharse1);
sort($pharse2);
if($pharse1 === $pharse2){
$status = true;
}
}
return $status;
}
function check_anagram($str1, $str2) {
if (count_chars($str1, 1) == count_chars($str2, 1)) {
return "This '" . $str1 . "', '" . $str2 . "' are Anagram";
}
else {
return "This two strings are not anagram";
}
}
ECHO check_anagram('education', 'ducatione');
I don't see any answers which have addressed the fact that capital letters are different characters than lowercase to count_chars()
if (isAnagram('Polo','pool')) {
print "Is anagram";
} else {
print "This is not an anagram";
}
function isAnagram($string1, $string2)
{
// quick check, eliminate obvious mismatches quickly
if (strlen($string1) != strlen($string2)) {
return false;
}
// Handle uppercase to lowercase comparisons
$array1 = count_chars(strtolower($string1));
$array2 = count_chars(strtolower($string2));
// Check if
if (!empty(array_diff_assoc($array2, $array1))) {
return false;
}
if (!empty(array_diff_assoc($array1, $array2))) {
return false;
}
return true;
}
here is my variant :
public function is_anagram($wrd_1, $wrd_2)
{
$wrd_1 = str_split ( strtolower ( utf8_encode($wrd_1) ) );
$wrd_2 = str_split( strtolower ( utf8_encode($wrd_2) ) );
if ( count($wrd_1)!= count($wrd_2) ) return false;
if ( count( array_diff ( $wrd_1 ,$wrd_2) ) > 0 ) return false;
return true;
}
Heheh little large but work as well :)
public static function areStringsAnagrams($a, $b)
{
//throw new Exception('Waiting to be implemented.');
$a = str_split($a);
$test = array();
$compare = array();
foreach ($a as $key) {
if (!in_array($key, $test)) {
array_push($test, $key);
$compare[$key] = 1;
} else {
$compare[$key] += 1;
}
}
foreach ($compare as $key => $value) {
if ($value !== substr_count($b, $key)) {
return false;
}
}
return true;
}

Filtering by PHP

I have a $data at a column1 shows me:
"AAA123"
"ABC1234"
"ABD123"
"BAC12"
"CAB123"
"DA125"
and so on..
I would like to show $data starting with only "AB" which shows me at column1 like :
"ABC1234"
"ABD123"
not the others but also other rows and columns related to "ABC1234" and "ABD123"
Thanx in advance.
Sample structure http://img706.imageshack.us/img706/8994/34310422.jpg
If $data is an array of strings, you can use array_filter.
PHP 5.3 or later:
$AB = array_filter($data, function($str) {
return 'AB' == substr($str, 0, 2);
});
before PHP 5.3:
$AB = array_filter($data,
create_function('$str',
'return "AB" == substr($str, 0, 2);'
) );
Or:
function create_prefix_tester($prefix) {
return create_function('$str',
"return '$prefix' == substr(\$str, 0, " . strlen($prefix) . ');'
);
}
$AB = array_filter($data, create_prefix_tester('AB'));
Or you could use a loop:
foreach ($data as $str) {
if ('AB' == substr($str, 0, 2)) {
// do stuff
...
}
}
Edit
From the sample code, it looks like you'll want the loop:
while (FALSE !== ($line = fgets($fp))) {
$row = explode('|', $line); // split() is deprecated
if ('AB' == substr($row[0], 0, 2)) {
switch($sortby) {
case 'schools': // fallthru
default:
$sortValue = $row[0];
break;
case 'dates':
$sortValue = $row[1];
break;
case 'times':
$sortValue = $row[2];
break;
}
array_unshift($row, $sortValue);
$table[] = $row;
}
}
or:
function cmp_schools($a, $b) {
return strcmp($a[0], $b[0]);
}
function cmp_dates($a, $b) {
return $a['datestamp'] - $b['datestamp'];
}
function cmp_times($a, $b) {
return $a['timestamp'] - $b['timestamp'];
}
while (FALSE !== ($line = fgets($fp))) {
$row = explode('|', $line); // split() is deprecated
if ('AB' == substr($row[0], 0, 2)) {
$when = strtotime($row[1] + ' ' + $row[2]);
$row['timestamp'] = $when % (60*60*24);
$row['datestamp'] = $when - $row['timestamp'];
$table[] = $row;
}
}
usort($table, 'cmp_' + $sortby);
I would simply use substr(), as in the following snippet:
if (substr($str, 0, 2) == 'AB') {
// The string is right.
}
Use strpos (http://www.php.net/manual/en/function.strpos.php), like
if (strpos($my_string, "AB") === 0) {
<do stuff>
}
Be very sure to use === instead of ==, because if "AB" is not found then the function will return false, which will equate to 0 using ==.

Categories