php multiple if conditions - php

when i try to filter all these parameters php only enters in the first if conditions, ignoring all others conditions.
if($t_red<0){
$t_red=0;
}
else if($t_red>256){
$t_red=255;
}
else if($t_green<0){
$t_red=0;
}
else if($t_green>256){
$t_red=255;
}
if($t_blue<0){
$t_red=0;
}
if($t_blue>256){
$t_red=255;
}
if($t_red<0){
$t_red=0;
}

Probably best suited if ran through a filtering function.
function setParam($param) {
if($param < 0) {
$param = 0;
} elseif($param > 256) {
$param = 255;
}
return $param;
}
$t_green = setParam($t_green);
$t_red = setParam($t_red);
$t_blue = setParam($t_blue);
You could also use pass-by-reference if necessary.

It's not clear what you're trying to do, but I think that you would want to remove the else before the third if statement and add an else before the sixth if statement.

$t_red=$t_red<0?0;$t_red;
$t_red=$t_red>=256?255;$t_red;
//are you sure you're modifying t_red here? and not t_green?
$t_red=$t_green<0?0;$t_red;
$t_red=$t_green>=256?255;$t_red;
//are you sure you're modifying t_red here? and not t_blue?
$t_red=$t_blue<0?0;$t_red;
$t_red=$t_blue>=256?255;$t_red;

a successfully met condition of an if (or following else if) statement will ignore all else if/else statements that immediately follow it, but the if statements afterwards are executing - You can verify this by adding echo statement to each one . Could it perhaps be because all your variable assignments are for $t_red so no action is taken on $t_green or $t_blue?

if($t_red < 0)
{
$t_red = 0;
}
else if($t_red > 255) //Original won't catch it if it is == to 256, have to do either >= 256 or > 255
{
$t_red = 255;
}
if($t_green < 0)
{
$t_green = 0;
}
else if($t_green > 255)
{
$t_green = 255;
}
if($t_blue < 0)
{
$t_blue = 0;
}
else if($t_blue > 255)
{
$t_blue = 255;
}
Andrew Sledge's answer is the best though, but I did correct the fact that it would miss correcting the value if it was == to 256, which wouldn't be caught by just $var > 256, and thus would be in error if the value has to be between 0 and 255.

Related

Any way to shorten this if statement? PHP

I'm trying to keep my code nice and elegant. Any way to make this if statement shorter?
if(strlen($cname) > 100) {
}
if(strlen($cowner) > 100) {
}
if(strlen($cemail) > 200) {
}
if(strlen($cpassword) > 100) {
}
I can't do this because I want to print out a specific message for each if statement:
if(strlen($cname) > 100 || strlen($cowner) > 100 || strlen($cemail) > 200 || strlen($cpassword) > 100) {
// I want to print out a message like email is too long not just one of these strings is too long
}
Frankly, I think you've got the most elegant solution for what you are trying to do.
You can use a loop to reduce the number of lines. Here is an optimized solution even when you have more 10 fields to check:
Declare an array of fields and loop through it
$fields = array("cname" => 100, "cowner" => 100, "cemail" => 200, "cpassword" => 100); // key as field name and value as maximum limit - new values can be added here.
foreach($fields as $field => $length) {
if(strlen(${$field}) > $length) {
die("$field field can only contain $length characters");
}
}
Edit: You can also keep all errors in an array and then print all the errors on your page.
$errors = array();
foreach($fields as $field => $length) {
if(strlen(${$field}) > $length) {
$errors[] = "$field field can only contain $length characters";
}
}
print_r($errors);
You already using an optimized code. But you can optimize it little bit more for showing error message. Like below:
$invalidFieldName = '';
$invalidFieldLength = 100;
if (strlen($cname) > 100) {
$invalidFieldName = 'CNAME';
} elseif (strlen($cowner) > 100) {
$invalidFieldName = 'COWNER';
} elseif (strlen($cemail) > 200) {
$invalidFieldName = 'CEMAIL';
$invalidFieldLength = 200;
} elseif (strlen($cpassword) > 100) {
$invalidFieldName = 'CPASSWORD';
}
if ($invalidFieldName != '') {
echo $invalidFieldName." should be greater than ".$invalidFieldLength;
}
I am not really sure if it will help you but I hope it will help you.

How to select the next number in a loop?

The function for the primes is clear, so I omitted it.
$a=10;
$z=30;
for($prime = $a; $prime<$z; $prime++)
{ if
(Prim($prime) == TRUE)
{ echo $prime."<br/>";}}
Now I want to select the next term of the sequence as well, in order to perform an operation between the variable $prime and $next_prime, as long as the loop goes on - like for example:
$prime_gap=bcsub($next_prime, $prime);
Whatever solutions I find and I try, it's never the proper one. It's surely very simple but I am already desperate.
I would suggest you start by creating a next_prime() function. Like this, for example:
function next_prime($n) {
do {
$n++;
} while (!Prim($n));
return $n;
}
Then you can refactor your code quite easily:
$a=10;
$z=30;
for ($p1=next_prime($a),$p2=next_prime($p1); $p2<$z; $p1=$p2,$p2=next_prime($p2)) {
if (some_function($p1, $p2)) {
echo "I like $p1 and $p2\n";
}
}
The if I add in the for loop is not so nice, but if you want something simple and easy to understand, you can still use it (I switch the name from $prime & $next_prime to $prime & $previous_prime, I think it makes more sense)
$a=10;
$z=30;
$previous_prime = 0;
for($prime = $a; $prime<$z; $prime++)
{
if (Prim($prime) == TRUE)
{
echo $prime."<br/>";
if ($previous_prime == 0) {
$previous_prime = $prime
} else
{
$prime_gap = $prime - $previous_prime;
$previous_prime = $prime;
}
}
}

For a given integer Z, check if Z can be written as P^Q where Q and P are positive integers

Here is what I have tried but it is giving me wrong output. Can anyone point out what is the mistake?
function superPower($n) {
$response = false;
$n = abs($n);
if ($n < 2) {
$response = true;
}
for ($i=2;$i<$n;$i++) {
for ($j=2;$j<$n;$j++) {
if (pow($i,$j) == $n) {
$response = true;
}
}
}
return $response;
}
For example if I give it number 25, it gives 1 as output. //Correct
But if I give it 26 it still gives me 1 which is wrong.
By using superPower, you are essentially trying to put a certain defence to the power of an attack to see if it holds up. This can be done much more effectively than through the brute-force method you have now.
function superPower( $hp) { // Niet used Superpower!
if( $hp <= 1) return true;
for( $def = floor(sqrt($hp)); $def > 1; $def--) { // Niet's Defence fell
for( $atk = ceil(log($hp)/log($def)); $atk > 1; $atk--) { // Niet's Attack fell
if( pow($def,$atk) == $hp) return true;
break;
// you don't need the $atk loop, but I wanted to make a Pokémon joke. Sorry.
}
// in fact, all you really need here is:
// $atk = log($hp)/log($def);
// if( $atk-floor($atk) == 0) return true;
}
return false;
}
The maths on the accepted answer is absolutely brilliant, however there are a couple of issues with the solution:
the function erroneously returns true for all of the following inputs: monkey, -3 and 0. (Technically 0 is unsigned, so there is no way of getting it by taking a positive integer to the power of another positive integer. The same goes for any negative input.)
the function compares floating numbers with integers (floor() and ceil() return float), which should be avoided like the plague. To see why, try running php -r '$n = (-(4.42-5))/0.29; echo "n == {$n}\n".($n == 2 ? "OK" : "Surprise")."\n";'
The following solution improves on the idea by fixing all of the above issues:
function superPower($value)
{
// Fail if supplied value is not numeric
if (!is_numeric($value)) {
// throw new InvalidArgumentException("Value is not numeric: $value");
return false;
}
// Normalise numeric input
$number = abs($value);
// Fail if supplied number is not an integer
if (!is_int($number)) {
// throw new InvalidArgumentException("Number is not an integer: $number");
return false;
}
// Exit early if possible
if ($number == 1) {
// 1 to the power of any positive integer is one
return true;
} elseif ($number < 1) {
// X to the power of Y is never less then 1, if X & Y are greater then 0
return false;
}
// Determine the highest logarithm base and work backwards from it
for ($base = (int) sqrt($number); $base > 1; $base--) {
$coefficient = log($number)/log($base);
// Check that the result of division is a whole number
if (ctype_digit((string) $coefficient)) {
return true;
}
}
return false;
}

using for loop and if in php

I have loop using for which results in some values:
$value1, $value2, $value3, $value4, ...
How can I make a calculation or relation between these values?
For example, if any two values < 40 echo something?
I hope that some code will make the idea clear:
<?php
$value=$_POST['name'];
for($i=1;$i<=$value;$i++)
{
$value{$i}=$_POST['name{$i}'];
}
if($value{$i} < 40)
{
echo "you failed";
}
else
{
echo "you succeeded";
}
?>
I want to show the message "you failed" if two values are < 40.
How can I do that?
I'm struggling to make sense of what your current code is actually doing, but that could just be that my PHP is a bit rusty. Either way, it sounds like the general pattern of what you're trying to do is to keep a count of fails and successes. As an overall structure (that is, not to be copied/pasted as-is since I don't know what your $value actually is here), it might look something like this:
$fails = 0;
$successes = 0;
for ($i = 0; $i < len($values); $i++)
{
if ($values[$i] < 40)
{
$fails++;
}
else
{
$successes++;
}
}
At this point $fails contains the count of values less than 40 and $successes contains the count of values greater than 40. Then you invoke your business logic for determining the overall result:
if ($fails >= 2)
{
echo "you failed";
}
else
{
echo "you succeeded";
}
To answer your question you can use the foreach statement
$value=$_POST['name'];
$hasValue = 0;
foreach($value as $key => $dat){ // since we have the value from $_POST we use foreach statement to loop it
if($dat < 40){ // check if the data in the list is less than 40
$hasValue++; // increment it if is.
}
}
echo ($hasValue > 2)?#"You failed":#"Success"; // check if it has more than 2 less than 40 values.
something like the above
and try to read about PHP
btw haven't code much in php lately so apologies for some syntax
As soon as any two values add to less than 40, the "failed" message shows and the loops are exited. If not, the success message shows.
$x = false;
foreach ($value as $k1 => $v1) {
foreach ($value as $k2 => $v2) {
if (($v1 + $v2) < 40 && ($k1 != $k2)) {
echo "you failed";
$x = true;
break (2);
}
}
}
if (!$x) echo "you succeeded";

How to optimize an if else if statement where previous ifs are not used in loop?

This is hypothetical code, assuming I have the following:
Let's say I have an array and it has lots of data, integers in this sample question, but it can ANY type of data that's already sorted in some fashion in regards to the if statements.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,...,9,9,9);
Let's say I have a for loop with numerous if else if statements, and those can have any criteria for doing something.
for($i=0; i<count($a); i++) {
// these if statements can be anything and may or may not be related with $a
if($a[$i] == 0 && $i < 10) {
// do something
}
else if($a[$i] == 1 && $i < 20) {
// do something
}
else if($a[$i] == 2) {
// do something
}
else if($a[$i] == 3) {
// do something
}
// and so on
}
Now the question, after the first if statement iterations are done, it's never used. Once the for loop starts using the next if statement, the previous if statement(s) don't need to be evaluated again. It can use the first if statement n amount of times and so on and so forth.
Is there a way to optimize it so it doesn't have to go through all the previous if else if statements as it's looping through the data? Mind, the data can be anything, and the if statements can be any variety of conditions.
Is there a paradigm shift, that I don't see, that is required on how this should be coded up to provide optimal performance?
You could leverage call_user_func_array. You would need to build a class that stored the methods to call to perform the statements. Consider a class like this:
class MyStatements {
public function If0($a, $i) {
if($a[$i] == 0 && $i < 10) {
// do something
}
}
public function If1($a, $i) {
if($a[$i] == 1 && $i < 20) {
// do something
}
}
}
you could then do something like this:
$stmts = new MyStatements();
for($i = 0; i < count($a); i++) {
call_user_func_array(array($stmts, 'If' . strval($i)), array($a, $i));
}
I think you are spinning your wheels.
If you have a lot of data, chances are, slowness is coming from the data source not the server-side calculations.
If you do anything, you should break up your data into chunks and run portions at-a-time. And you would only need to do this if you are noticing slow load-times or bad top-load on your server.
Asynchronous connections allow you to do this with ease, using ajax you can connect to your server, pull a limited chunk of data, process it, then after that displays in the client browser, run the next chunk. Anytime you use a Web site that queries large amounts of data (ie: facebook) it does it this way.
But again, don't over-think this. You really don't need to make your procedure more complicated. If you really want a gold-star you can make an object-oriented class that processes all this for you, but I will not get into that.
PHP uses something called "short-circuit evaluation," as many other modern languages do. This means once the boolean expression has been determined to be true or false, the remaining pieces of the expression will not be evaluated.
So, you could introduce new boolean values (maybe an array of them) that tracks if a piece of code has been executed already, and if it has been, set it to false. Then use this boolean as the first condition in the "if" expression. PHP will recognize that the value of this one is set to false, and ignore the rest of the clause. This is a pretty simple route, and would keep your code mostly structured the way it is now.
Break up your for statement into multiple for statements. For your example code:
for($i=0; i<10; i++) {
if($a[$i] == 0) {
//do something
}
}
for($i=0; i<20; i++) {
if($a[$i] == 1) {
//do something
}
}
for($i=0; $i<count($a); $i++) {
if($a[$i] == 2) {
// do something
}
else if($a[$i] == 3) {
// do something
}
}
//etc...
If you are using PHP 5.3+ then you can use anonymous functions.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
$dispatch = array(
0=>function() { echo "0"; },
1=>function() { echo "1"; },
2=>function() { echo "2"; },
3=>function() { echo "3"; },
9=>function() { echo "9"; }
);
foreach ($a as $i)
{
$dispatch[$i]();
}
Before PHP 5.3 you would have to use a map to function names, but the bottom works in PHP 5.3+ as well.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
function foo0() { echo "0"; }
function foo1() { echo "1"; }
function foo2() { echo "2"; }
function foo3() { echo "3"; }
function foo9() { echo "9"; }
$dispatch = array(
0=>"foo0",
1=>"foo1",
2=>"foo2",
3=>"foo3",
9=>"foo9"
);
foreach ($a as $i)
{
$dispatch[$i]();
}
The above code is faster, but not completely efficient. To improve performance you would have to drop the key look up in the $dispatch array, and move forward each time the value of $a[#] changed. This assumes your $dispatch array matches the input array. You would only gain a performance improvement if the $dispatch array was very large.
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
function foo0() { echo "0"; }
function foo1() { echo "1"; }
function foo2() { echo "2"; }
function foo3() { echo "3"; }
function foo9() { echo "9"; }
$dispatch = array(
0=>"foo0",
1=>"foo1",
2=>"foo2",
3=>"foo3",
9=>"foo9"
);
reset($dispatch);
$foo = (string)current($dispatch);
$last = 0;
foreach ($a as $i)
{
$foo();
if($i != $last)
{
$foo = (string)next($dispatch);
$last = $i;
}
}
That should be about as efficient as it can be.
I'm not sure how different this is from The Solution's, but I'd thought I'd throw it out there.
function func1 () {
echo "hi\n";
}
function func2 () {
echo "bye\n";
}
$functionList = array (
0 => "func1",
1 => "func2"
);
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
$len = count($a);
for($i = 0; $i < $len; $i++) {
if (isset($functionList[$i])) {
call_user_func($functionList[$i]);
}
}
I set the keys of $functionList explicitly, since OP says they will not always be numeric. Perhaps the first 2-3 assignments could be wrapped into a class.
This verbose solution will prevent any if condition from being run after it has evaluated to false and will not iterate over the same $i value more than once except for when it transitions to the next loop.
for($i=0; i<count($a); i++) {
if($firstCondition) {
//do something
} else {
break;
}
}
for($i; i<count($a); i++) {
if($secondCondition) {
//do something
} else {
break;
}
}

Categories