Is there any way to simplify this PHP code? - php

$a = $_POST['year'];
$b = $_POST['mileage'];
$c = is_numeric($a);
$d = is_numeric($b);
if ($c == False && $d == False) {
echo = "$c & $d variables are not numeric";
} else {
echo = "$c & $d variables are numeric";
}
This is a code that I whipped while learning PHP. Is there anyone that can help me simplify them. I don't like how it looked. I feel that it is too long. Beginner here (",)

Sometimes breaking down the way you set values can be useful, especially with complex calculations as it helps to debug the code.
But with simple assignments it is better (IMHO) to try and reduce the number of extra steps you make in your code. Setting a variable to then use it in another step is an overhead for both the computer (although negligible) but also adds extra lines of code. So assuming you just want to show if they are both numeric or not you can roll up all of those variables into the if statement...
if (is_numeric($_POST['year']) == False && is_numeric($_POST['mileage']) == False) {
echo "variables are not numeric";
} else {
echo "variables are numeric";
}
This does assume you have already checked that $_POST['year'] and $_POST['mileage'] are set (as does your code), you can use $_POST['mileage'] ?? '' if you want to make it more flexible.
Also the code only says the variables are not numeric if both values are not numeric. Change the && to || for either values not being numeric.

Related

PHP compare strings error

I am a beginner in PHP and I am trying to separate the input based on the argument. Following is my code but it seems that my $arg variables is never set. Can someone point out my error?
$sender = $_GET['sender'];
$receiver = $_GET['receiver'];
$message = $_GET['message'];
$temp = explode( '.', $message);
$tempcnt = count($temp);
echo $temp[$tempcnt - 1];
if($tempcnt > 2)
{
if($temp[$tempcnt-1] === 'mp4')
{$arg = 3;}
elseif($temp[$tempcnt-1]==='jpg')
{$arg = 2;}
else
{$arg = 1;}
}
echo "Value of arg is" . $arg;
I have even tried with == and === and strcmp in if but still same issue.
Try This:
<?php
$temp strrchr("foo.jpg",".");
if($temp==".mp4")
$arg = 3;
elseif($temp==".jpg")
$arg = 2;
else $arg = 1;
?>
See also the other answers, but one possibility that hasn't been mentioned is that == and === and strcmp all compare case sensitively. So they won't find extensions like .MP4.
The solution in that case would be to use strcasecmp.
However, the first thing to do with problems like this is to output some more diagnostics, so that you can see for yourself what goes wrong. In this example, echo $tempcnt; after its assignment, or else echo "did nothing" after the outer if {..} block.
That way you'll be able to follow what the program flow is.
Issue was caused since i didn't realize i had compared for args > 2. Made it >=2 and viola it done!!
Thanks to #barmar for pointing that out!

PHP - is this syntax possible and is it safe

I have some code that isn't working yet, before I debug I want to make sure that this syntax or method can indeed work and actually only execute the mysql_query if the last condition is true.
Also, is this a relatively safe practice?
I couldn't find anything relating to this, I figured someone putting it in English would help clear this up for me.
if($var1 == $var2) {$new = 1;}
if($vara == $varb) {$old = 1;}
if($new = 1 && $old = 1) { mysqli_query($somequery);}
This won't work because of the single =.
Go for:
if($var1 == $var2) {$new = 1;}
if($vara == $varb) {$old = 1;}
if($new == 1 && $old == 1) { mysqli_query($somequery);}
Or, ideally:
if ($var1 == $var2 && $vara == $varb) {
mysqli_query($somequery);
}
Top hint to stop things like if ($var = 1) typos - switch the comparisons around and put the constant first.
If you write if ($var = 1) then $var becomes 1 and is always true, but if you write if (1 = $var) you get an error, which is exactly what you want (and the same happens if your use a string if ("yes" = $var).
It been hammered into us to put the variable first since forever, but you're far better off doing it the other way around.

Does PHP have short-circuit evaluation?

Given the following code:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
If is_valid($string) returns false, does the php interpreter still check later conditions, like up_to_length($string)?
If so, then why does it do extra work when it doesn't have to?
Yes, the PHP interpreter is "lazy", meaning it will do the minimum number of comparisons possible to evaluate conditions.
If you want to verify that, try this:
function saySomething()
{
echo 'hi!';
return true;
}
if (false && saySomething())
{
echo 'statement evaluated to true';
}
Yes, it does. Here's a little trick that relies on short-circuit evaluation. Sometimes you might have a small if statement that you'd prefer to write as a ternary, e.g.:
if ($confirmed) {
$answer = 'Yes';
} else {
$answer = 'No';
}
Can be re-written as:
$answer = $confirmed ? 'Yes' : 'No';
But then what if the yes block also required some function to be run?
if ($confirmed) {
do_something();
$answer = 'Yes';
} else {
$answer = 'No';
}
Well, rewriting as ternary is still possible, because of short-circuit evaluation:
$answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';
In this case the expression (do_something() || true) does nothing to alter the overall outcome of the ternary, but ensures that the ternary condition stays true, ignoring the return value of do_something().
Bitwise operators are & and |.
They always evaluate both operands.
Logical operators are AND, OR, &&, and ||.
All four operators only evaluate the right side if they need to.
AND and OR have lower precedence than && and ||. See example below.
From the PHP manual:
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f before the "or" operation occurs
// Acts like: (($f = false) or true)
$f = false or true;
In this example, e will be true and f will be false.
Based on my research now, PHP doesn't seem to have the same && short circuit operator as JavaScript.
I ran this test:
$one = true;
$two = 'Cabbage';
$test = $one && $two;
echo $test;
and PHP 7.0.8 returned 1, not Cabbage.
No, it doesn't anymore check the other conditions if the first condition isn't satisfied.
I've create my own short-circuit evaluation logic, unfortunately it's nothing like javascripts quick syntax, but perhaps this is a solution you might find useful:
$short_circuit_isset = function($var, $default_value = NULL) {
return (isset($var)) ? : $default_value;
};
$return_title = $short_circuit_isset( $_GET['returntitle'], 'God');
// Should return type 'String' value 'God', if get param is not set
I can not recall where I got the following logic from, but if you do the following;
(isset($var)) ? : $default_value;
You can skip having to write the true condition variable again, after the question mark, e.g:
(isset($super_long_var_name)) ? $super_long_var_name : $default_value;
As very important observation, when using the Ternary Operator this way, you'll notice that if a comparison is made it will just pass the value of that comparison, since there isn't just a single variable. E.g:
$num = 1;
$num2 = 2;
var_dump( ($num < $num2) ? : 'oh snap' );
// outputs bool 'true'
My choice: do not trust Short Circuit evaluation in PHP...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
The second part in the condition 1 || saySomething() is irrelevant, because this will always return true. Unfortunately saySomething() is evaluated & executed.
Maybe I'm misunderstood the exact logic of short-circuiting expressions, but this doesn't look like "it will do the minimum number of comparisons possible" to me.
Moreover, it's not only a performance concern, if you do assignments inside comparisons or if you do something that makes a difference, other than just comparing stuff, you could end with different results.
Anyway... be careful.
Side note: If you want to avoid the lazy check and run every part of the condition, in that case you need to use the logical AND like this:
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
This is useful when you need for example call two functions even if the first one returned false.

php variable assignment inside if conditional

The following two ifs produced different results(first if echos hi, second does not), why? why didn't the variable assignment on $t work? is this due to $t's local scope inside the if conditional?
if(isset($_REQUEST["test"]) && $t=trim($_REQUEST["test"]) && !empty($t)){
echo 'hi'
}
if(isset($_REQUEST["test"]) && $t=trim($_REQUEST["test"])){
if(!empty($t))echo 'hi'
}
&& has a higher precedence than =, hence the first expression is evaluated as:
isset($_REQUEST['test']) && $t = (trim($_REQUEST['test']) && !empty($t))
Since !empty($t) is evaluated before anything is assigned to $t, the expression is false. You could fix this by explicitly setting parentheses, or by using a less awkward way to write it:
if (isset($_REQUEST['test']) && trim($_REQUEST['test'])) {
echo 'hi';
}
trim($_REQUEST['test']) will evaluate to true or false just by itself, no empty necessary. If you actually need the trimmed value later, you can save it like so:
if (isset($_REQUEST['test']) && ($t = trim($_REQUEST['test']))) {
echo 'hi';
}
If you make minor modification like this in your code:
if(isset($_REQUEST["test"]) && ($t=trim($_REQUEST["test"])) && !empty($t)){
echo '1: hi<br/>';
}
if(isset($_REQUEST["test"]) && $t=trim($_REQUEST["test"])){
if(!empty($t))
echo '2: hi<br/>';
}
Then both 1: hi and 2: hi will be printed. Difference is parenthesis around first $t assignment.

Strange IF Statement behaviour

I have an IF statement that consists of two separate function calls
passing values to two variables. Obviously if neither value is 'FALSE'
then the code block is executed:
<?php
class MyValidater {
static function validateString($string) {
if (preg_match("/[A-Za-z]+/", $string)) {
return $string;
} else {
return false;
}
}
}
$firstName = "Daniel";
$surname = "Simmons";
// Dodgy IF statement
if ($first = MyValidater::validateString($firstName) && $second = MyValidater::validateString($surname)) {
print("Success: $first $second");
} else {
print("Fail: $first $second");
}
?>
As you can see both the $first and $second variables should contain
the values held in $firstName and $surname after successfully being
validated by the Static method validateString.
However, the values of the two variables end up: $first = '1' and
$second = "Simmons".
The '1' should be "Daniel" but for some reason $first is being passed
the value '1' or TRUE. If you swap the two assignment statements over
so that $second is evaluated first, you end up with the opposite
outcome as before. $second = '1' and $first = "Daniel"
Can anyone explain why the String value "Daniel" being returned from
the class method is being changed into the int '1' for the first part
of the conditional statement only? I have had a quick look though the
PHP documentation but cannot find an explanation.
For the moment the workaround is to change the return value from the
static method to be true/false and then make $first = $firstName,
etc... upon success. But this involves more code and I would rather
find out why this way does not work.
You need to bracket your expressions:
if (($first = MyValidater::validateString($firstName)) && ($second = MyValidater::validateString($surname)))
What's actually happening is this:
if ($first = (MyValidater::validateString($firstName) && $second = MyValidater::validateString($surname)))
It would be much clearer to just do this (note this code isn't identical to what you have):
$first = MyValidater::validateString($firstName);
$second = MyValidater::validateString($surname);
if ($first && $second)
&& is higher then = in the operator precedence. add brackets and it will work.
http://www.php.net/manual/en/language.operators.precedence.php
you can read about operator precedence here.
Also, setting values inside of an if condition is usually bad practice. If you add the brackets, you will most probably see why (let $first set to false and $second set to a string) => the first will be evaluated, but since it is false then, it won't process further since it will go to the else anyways. => second will not be set correct if first = false.
Try using parenthesis
($first = MyValidater::validateString($firstName)) && ($second = MyValidater::validateString($surname)))
First is getting the result of the first function call AND the second function having a value.
= is for attributions
== is for comparisons, the data type doesn't matter
=== is for comparisons, the data type matters
What is happening is that PHP is assigning $first with “MyValidater::validateString($firstName)) && $second = MyValidater::validateString($surname)”
You need brackets around first compare and second, like this.
if ( ($first = MyValidater::validateString($firstName)) && ($second = MyValidater::validateString($surname))) {

Categories