PHP Syntax to shorten if-statements - php

Disclaimer : the following is a bad practice (but it would be useful in a very, very specific use)
Is there a way to shorten (in a not-so-nice-way-but-shorter) if statements :
instead of :
if(5 == $foo){
$b = 98;
$c = 98 * $otherVariable;
//do something complex
doSomethingElse($b, $c);
}
This example would become shorter, even if it is formatted by an IDE.
It would become something like that (but this does not work):
(5 == $foo) && { $b = 98;
$c = 98 * $otherVariable;
//do something complex
doSomethingElse($b, $c);}

I suggest, you should opt for better readable code, but still if you want to do something different, you may go through below :
($foo == 5) && doSomethingElse(98, 98*$otherVariable);
OR
PHP Ternary Operator
($your_boolean) ? 'This is true' : 'This is false';
You can rewrite your if statement like below :
($foo == 5) ? doSomethingElse(98, 98*$otherVariable) : "";
// little shorter but not better readable
($foo != 5) ? : doSomethingElse(98, 98*$otherVariable);
Test Results:
$ cat test.php
<?php
function aa(){ echo "123\n"; }
$foo = 5;
// this will not call aa()
($foo == 4) && aa() ;
// this will call aa()
($foo == 5) && aa() ;
?>
$ php test.php
123

if(5 == $foo) doSomethingElse(98, 98*$otherVariable);
Look out! The variables $b and $c are not available for further calculations!

Related

Is this a good way of writing long conditions in PHP?

I have to evaluate a very long condition in PHP, so, to avoid errors and trying to write more readable code, I did the following:
//this returns 1 when true, and nothing when false, although expected TRUE or FALSE
$isNameValid=strlen($dataDecoded['nombre'])>=3;
$isDescriptionValid=(strlen($dataDecoded['descripcion'])>=10) && strlen($dataDecoded['descripcion'])<=300;
$isPriceValid=$dataDecoded['precio'] >0;
$isImageValid=(($dataDecoded['imagen'] != "") && ($dataDecoded['imagen'] != NULL) );
And now, I can make the following:
if($isNameValid==1 && $isDescriptionValid==1 && $isPriceValid==1 && $isImageValid==1)
{
echo "ok";
}
else{
echo "no";
}
It seems to work fine, but maybe is a weird way of doing things. I wanted to avoid the following, which I find more confusing and easy to make a mistake
if(strlen($dataDecoded['nombre'])>=3 && ... && ...)
Is there a better way to do that? Is wrong what I did? Thanks
I don't care for creating extra variables here; this makes code difficult to maintain and unreusable. I'd recommend breaking your validation logic into easy-to-read, maintainable, reusable functions:
function valid($data) {
return validName($data['nombre']) &&
validDescription($data['descripcion']) &&
validPrice($data['precio']) &&
validImage($data['imagen']);
}
function validName($name) {
return strlen($name) >= 3;
}
function validDescription($desc) {
return strlen($desc) >= 10 && strlen($desc) <= 300;
}
function validPrice($price) {
return $price > 0;
}
function validImage($image) {
return $image !== "" && $image != NULL;
}
$dataDecoded = [
"nombre" => "foo",
"descripcion" => "foo bar foo bar",
"precio" => 15,
"imagen" => "foo.png"
];
// now your main code is beautiful:
echo (valid($dataDecoded) ? "ok" : "no") . "\n";
Yes, that is acceptable. However, your variables there are all boolean, so you don't even need the ==1.
if($isNameValid && $isDescriptionValid && $isPriceValid && $isImageValid)
It really depends on how you want to handle it.
Is switch an option or a viable one?
Is ternary if prettier or handy?
From what I see, I'm guessing you have a validation purpose and a operating incoming depending on the validation. Why not create a function or a class that handles your input and validates? And in there, you can have all the dirty code you'd want. On your logical code, you'd just have to do (e.g of a class)
$someClass = new SomeClass();
$someClass->validate($fields);
if ($someClass->isValidated()) ...
This way, you'd actually follow some standards whereas the purpose of it would be to work as a validator for (all of? depends on your needs) your data
E.g of ternary ifs
$isNameValid = count($dataDecoded['nombre'])>=3 ? true : false;
$isDescriptionValid = count($dataDecoded['descripcion']) >= 10 && count($dataDecoded['descripcion']) <= 300 ? true : false;
$isPriceValid = count($dataDecoded['precio']) > 0 ? true : false;
$isImageValid = empty($dataDecoded['imagen']) === false ? true : false;
if ($isNameValid && $isDescriptionValid && $isPriceValid && $isImageValid) ...

Can ($a == 1 && $a == 2 && $a == 3) ever evaluate to true?

Similar to this question here which was intended for javascript, it has spawned off numerous spin-offs for various different languages. I'm curious if the following can ever evaluate to true in PHP:
($a == 1 && $a == 2 && $a == 3)
To follow up a bit more, it seems simply setting $a = true will yield the desired result (This was not the case for javascript, due to the way type casting works in both languages). A few answers (in javascript) worked with === as well, so in PHP with typechecking (===), can the following ever yield true?
($a === 1 && $a === 2 && $a === 3)
I just tried this:
$a = true;
echo ($a == 1 && $a == 2 && $a == 3);
and it echoed 1.
Because of the type casting and not type checking, 1, 2, 3 will be treated as true when compared to a boolean value.
Answer to the edit: No it can't be done.
Hackish method which #FrankerZ commented about:
Zero byte character = 0xFEFF
http://shapecatcher.com/unicode/info/65279
http://www.unicodemap.org/details/0xFEFF/index.html
$var  = "1";
$var = "2";
$ var = "3";
echo ($var  === "1" && $var === "2" && $ var === "3") ? "true" : "false";
This code runs with this character because the name $ var and $var  seems to be valid for the PHP compiler and with the appropiate font, it can be hidden. It can be achieved with Alt + 65279 on Windows.
Whilst not strictly in keeping with the question, this can be done if the ints are wrapped in quotes:
<?php
class A {
private static $i = 1;
public function __toString()
{
return (string)self::$i++;
}
}
$a = new A();
if($a == '1' && $a == '2' && $a == '3') {
echo 'yep';
} else {
echo 'nope';
}
I can't think of a case where strict comparison would ever yield true. === operator compares the types first, so there's no way to use any magic method wizardry.
For curiosity the closest i could get is to slightly modify the setting and hack the variable in a tick function. Since ticks are only incremeted per statement, we have to break the comparison to multiple statements for this to work.
$a = 1;
register_tick_function(function () use (&$a) {
++$a;
});
declare(ticks = 1) {
$a === 1 or exit(1);
$a === 2 or exit(1);
$a === 3 or exit(1);
}
echo "a = $a\n";
Try it online.

If statement within an if statement

How do I put an if statement within an if statement? Right now it's like this;
<?php
if($var1===$var2)
{
if($condition1 > 0)
{
*lots of code here*
}
}
else
{
*lots of code here again*
}
}
?>
Meaning that I want $condition1 to be bigger than 0 IF $var1 does not match $var2. But as it stands I am duplicating the "lots of code part" so I just want to;
if($var1!=$var2){ -apply if statement- }
*lots of code here*
if($var1!=$var2){ -close if statement- }
But how?
<?php
$a = ($var1 === $var2);
$b = ($condition1 > 0);
if (!$a || $b)
{
*lots of code here*
}
?>
You have the right way of combining two if statements. However, you want to run lots of code either when var1 equals var2 or when condition1 is bigger than 0. You can write that like this:
<?php
if ($var1===$var2 || $condition1 > 0)
{
*lots of code here again*
}
?>
The || operator means 'or'.
Maybe i don't get it but i'd do it like this:
if($var1 === $var2 || $condition1>0){
//lots of code here
}else{
}
EDIT - maybe you wan't this - it reads if var1 is equal to var 2 OR if var1 is not equal to var2 and condition1>0 do lots of code
if($var1 === $var2 || ($var1 !== $var2 && $condition1>0)){
//lots of code here
}else{
}

Checking if isset and is true?

Is there a function to check both
if (isset($var) && $var) ?
The empty() function will do the job.
Use it with the not operator (!) to test "if not empty", i.e.
if(!empty($var)){
}
You may use the ?? operator as such:
if($var ?? false){
...
}
What this does is checks if $var is set and keep it's value. If not, the expression evaluates as the second parameter, in this case false but could be use in other ways like:
// $a is not set
$b = 16;
echo $a ?? 2; // outputs 2
echo $a ?? $b ?? 7; // outputs 16
More info here:
https://lornajane.net/posts/2015/new-in-php-7-null-coalesce-operator
there you go. that should do it.
if (isset($var) && $var)
if (! empty($var))
It seems as though #phihag and #steveo225 are correct.
Determine whether a variable is considered to be empty. A variable is
considered empty if it does not exist or if its value equals FALSE.
empty() does not generate a warning if the variable does not exist.
No warning is generated if the variable does not exist. That means
empty() is essentially the concise equivalent to !isset($var) || $var
== false.
So, it seems !empty($var) would be the equivalent to isset() && $var == true.
http://us2.php.net/empty
Try the empty function:
http://us2.php.net/empty
isset($a{0})
isset AND len is not 0 seems more reliable to me, if you run the following:
<?php
$a=$_REQUEST['a'];
if (isset($a{0})) { // Returns "It's 0!!" when test.php?a=0
//if (!empty($a)) { // Returns "It's empty!!" when test.php?a=0
echo 'It\'s '.$a;
} else { echo 'It\'s empty'; }
?>
$a = new stdClass;
$a->var_false = false;
$a->var_true = true;
if ($a->notSetVar ?? false) {
echo 'not_set';
}
if ($a->var_true ?? false) {
echo 'var_true';
}
if ($a->var_false ?? false) {
echo 'var_false';
}
This way:
if (($var ?? false) == true) {
}
I am amazed at all these answers. The correct answer is simply 'no, there is no single function for this'.
empty() tests for unset or false. So when you use !empty(), you test for NOT UNSET (set) and NOT FALSE. However, 'not false' is not the same as true. For example, the string 'carrots' is not false:
$var = 'carrots'; if (!empty($var)){print 1;} //prints 1
in fact your current solution also has this type problem
$var = 'carrots'; if (isset($var) && $var){print 1;} //prints 1
as does even this
$var = '1.03'; if (isset($var) && $var == true){print 1;} //prints 1
in fact... if you want to do as you described exactly, you need:
$var = 'carrots'; if (isset($var) && $var === true){print 1;} //Note the 3 Equals //doesn't print 1
I suppose the shortest valid way to test this case is :
if (#$var === true){ print 1;}
But suppressing errors for something like this is pretty awful practice.
Don't know if an exact one already exists, but you could easily write a custom function to handle this.
function isset_and_true($var) {
return (isset($var) && $var == true) ? true : false;
}
if (isset_and_true($a)) {
print "It's set!";
}
Check if the variable is set, and true. Ignore warning message
if(#!empty($foo))

Switch case with three parameters?

Is it possible to use three parameters in switch-case, like this:
switch($var1, $var2, $var3){
case true, false, false:
echo "Hello";
break;
}
If not, should I just use if-else or is there a better solution?
The syntax is not correct and I wouldn't recommend it, even if it was. But if you really want to use a construct like that, you can put your values into an array:
switch (array($var1, $var2, $var3)) {
case array(true, false, false):
echo "hello";
break;
}
I would just use the if/else
if($var1 == true && $var2 == false && $var3 == false){
echo "Hello";
}
or
if($var1 && !($var2 && $var3)) {
echo "Hello";
}
You don't have a switch situation here. You have a multiple condition:
if($var && !($var2 || $var3)) { ...
i don't think your syntax is valid.
I'd nest the switch statements.
Another option is to create a function that maps three parameters to an integer and use that in the switch statement.
function MapBool($var1, $var2, $var3){
// ...
}
switch(MapBool($var1, $var2, $var3)) {
case 0:
echo "Hello";
break;
// ...
}
This is the sort of thing that used to be handled by bitwise operators:
if (($var1 << 2) & ($var2 << 1) & $var3) == 4) ...
...back when 'true' was 1.
That being said, the above is concise, but it's pretty hard to read and maintain. Nevertheless, if you have a lot of similar statements, shifting/ANDing might be a way to go to get things under control:
switch (($var1 << 2) & ($var2 << 1) & $var3)) {
case 0: // false, false, false
...stuff...
case 1: // false, false, true
...different stuff...
// all 8 cases if you REALLY care
}
I don't know - if you really want it this way - maybe cast them all to string, concatenate and then use the resulting string in your case condition?

Categories