Pattern for preventing a lot of if else - php

please provide some example or pattern name to avoid a lot of if else constructions. Maybe some design pattern exists for more clean and readable code?
public function process(CreditNotificationInterface $obj)
{
$this->creditNotification = $obj;
if ($obj->isAccepted()) {
return $this->accept();
} else {
if ($obj->isDeclined()) {
return $this->decline();
} else {
if ($obj->isError()) {
return $this->error();
} else {
if ($obj->isAbandoned()) {
return $this->abandoned();
}
}
}
}
return false;
}

If you really want to use design pattern strategy pattern looks to me like best solver for lot of if/else's. http://www.phptherightway.com/pages/Design-Patterns.html

The switch statement was conceived to solve exactly this problem. It allows you to check values serially in an attempt to reduce nested ifs and condense serial if-elses. Take a look here for examples on how to apply the switch statement in PHP. Then apply it to your problem.
https://www.w3schools.com/php/php_switch.asp

Related

When explicit "else" is necessary in control structures?

What should one use?
This, without else:
function($condition) {
if($condition) {
return true;
}
return false;
}
Or this, with an else:
function($condition) {
if($condition) {
return true;
} else {
return false;
}
}
What are potential drawbacks?
Note: I understand that right solution for this very example would be
function($condition) {
return (boolean)$condition;
}
I like this approach:
function($condition) {
$retValue = false;
if($condition) {
$retValue = true;
}
return $retValue;
}
This way you know where this function will return, (always at the end) which is good for later analyzing. You set a default value and only change it if the condition is right.
With else there is a better readability. However, both the functions are doing the same as the function is terminated by the return function. I find it also safer to use the else if in some cases you can forget using the return function which then go further to return the false.
I would use the else too, for these reasons:
Your code is better readable
In complex code, like when you use if/else within other if/else's, debugging will be much easier.
In some cases it is possible to increase readability by setting "else" aside. Two examples below are eqiuvalent. Second produces less code, though it will suit only when we return values without complex calculations in that block, but again, we can utilize functions to make it usable.
function($a, $b) {
if($a) {
if($a > $b) {
return true;
} else {
return false;
}
} else {
return false;
}
}
function($a, $b) {
if($a) {
if($a > $b) {
return true;
}
}
return false;
}
Note: if not speaking about general cases with more complex conditions assumption, this should fold to:
function($a, $b) {
return ($a and $a > $b);
}
In the first one both true and false will be returned, as when the if statement finishes, it will go and do the very next thing, return false. In the second one, one true OR false will be returned, depending on the condition. Draw backs for the first one would be that you get both true and false returned, which could confuse a function that's only asking for one parameter, and receiving two instead. This is assuming that you include this inside a larger function. I'm not sure why you would want to use the first one though. Hopefully this helps!

returning from multiple points in a function

This is more or less a readability, maintainability and/or best practice type question.
I wanted to get the SO opinion on something. Is it bad practice to return from multiple points in a function? For example.
<?php
// $a is some object
$somereturnvariable = somefunction($a);
if ($somereturnvariable !== FALSE) {
// do something here like write to a file or something
}
function somefunction($a) {
if (isset($a->value)) {
if ($a->value > 2) {
return $a->value;
} else {
return FALSE;
} else {
// returning false because $a->value isn't set
return FALSE;
}
}
?>
or should it be something like:
<?php
// $a is some object
$somereturnvariable = somefunction($a);
if ($somereturnvariable !== false) {
// do something here like write to a file or something
}
function somefunction($a) {
if (isset($a->value)) {
if ($a->value > 2) {
return $a->value;
}
}
return FALSE
}
?>
As a matter of practice, I always try to return from ONE point in any function, which is usually the final point. I store it in a variable say $retVal and return it in the end of the function.It makes the code look more sane to me.
Having said that, there are circumstances where say, in your function as the first line you check if a var is null and if yes you are returning. In this case, there is no point in holdin on to that variable, then adding additional checks to skip all the function code to return that in the end.
So...in conclusion, both ways works. It always depends on what the situation is and what you are more comfortable with.

Nested if statements, any possible way of cleaning?

I have checked a few other questions but they don't really give me the answer I expect..
My code is a like this..
private function handle()
{
if()
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
if(!condition))
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
if(!condition)
{
code
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
return;
}
}
In my opinion it is readable but messy, sadly I haven't found really a way of making it look 'pretty'. Any ideas?
EDIT: Each return is different.
EDIT2: Gave an answer of my own, thanks everybody!
Conditions can be merged by a && operator..It works form left to right, which means, as soon as the any one starting from left fails, it stops evaluating the condition..
if($a) {
if($b) {
}
}
can be replaced by
if($a && $b) {
}
Use a variable check, or combine the conditions into fewer IF statements.
Variable check like so:
$execute = TRUE;
// Opposite of what you want, e.g. if you want $a only to be TRUE, do $a !== TRUE
if (condition) {
$execute = FALSE;
}
...
// If all the conditions were met, then everything is OK
if($execute === TRUE) {
// code
}else {
// return
}
Edit:
Variable check can be preferably to combining IF statements if you want more control on what returns, e.g. something specific happens if a certain condition fails, which combining conditions can not always allow for.
Like already posted use
if(condition1&&condition2){}
or if this will not work, you can also use function which stops as soon as a condition is true
function some(){
if(!conditon 1){return 0;}
if(condition 2) {return 1;}
}
this provides more power as second if works only if first doesn't satisfy.
You must choose based on your requirements. Sometimes though nested loops are unavoidable.
I thought it out and have found a nice way of doing it, basically I'll make a method for each basic condition, and I'll call them in an if statement with the bitwise AND operator (&), which don't short-circuit.
/**
* nonsql_condition - It means it doesn't check with the database
*
* sql_condition - It means it does check with the database.
*/
if(!$this->nonsql_condition() & !$this->nonsql_condition() & !$this->nonsql_condition() & !$this->nonsql_condition())
{
if(!$this->sql_condition())
{
return error;
}
if(!$this->sql_condition())
{
return error;
}
code;
}
This allows me to use fewer lines of code in my method, plus also not doing unnecessary queries to my database.

function return code block query

Quick question to do with php functions, it may sound silly to some of you but I dont want to get in to bad habits. Is there anything wrong with doing the following?
function do_something($val)
{
$a = 1;
if ($val==$a)
{
return true;
}
return false;
}
Instead of;
function do_something($val)
{
$a = 1;
if ($val==$a)
{
return true;
}
else
{
return false;
}
}
Sorry guys I think my example isn't great. Basically the function could insert data into a database or send an email etc. With these functions I may only need to now whether it was successful or not by returning true or false. I wanted to know whether its suitable that I can use the shorter method instead of the if-else block.
I hope that makes it clearer.
Not really. Both works the same. However, it would be much cleaner to write it like this:
function do_something($val)
{
$a = 1;
return ($val==$a) ? true : false;
}
That's totally cool, because when returning a value, the function is left and it doesn't matter what follows.
But you could shorten this with
function do_something($val)
{
$a = 1;
return $val == $a; // this condition will be evaluated to true/false
}
The shortest way to do it:
function do_something($val)
{
return ($val==1) ;
}
No, that is perfectly fine, and in fact advised in multiple cases. :)

Should I use methods or constant flags?

If I have a database table containing a flag that can have multiple states, should I do this
if ($Object->isStateOne()) {
// do something
}
else if ($Object->isStateTwo()) {
// do something else
}
else if ($Object->isStateThree()) {
// do yet something else
}
or this
switch ($Object->getSomeFlag()) {
case ObjectMapper::STATE_ONE:
// do something
break;
case ObjectMapper::STATE_TWO:
// do something else
break;
case ObjectMapper::STATE_THREE:
// do yet something else
break;
}
?
Whichever makes sense, of course.
The switch looks much cleaner. But, what is this 'state' you are checking? If you're translating a string, use an array, for example.
The if has different behavior from switch. The method calls MAY have side effects. The if is better if multiple states may be active on the object at once, though.
From an OO perspective, both are discouraged. If you have different state, you may want to create a virtual methods, and override it in inherited class. Then based on polymorphism, you can avoid the if, and switch statement.
The second option just seems to be the better solution. IMHO, the unsightly duplication of the comparison code that would accompany the methods of the first solution would be the show-stopper for me, for example:
public function isStateOne() {
if(strcmp(ObjectMapper::STATE_ONE, '1') == 0) {
return true;
}
}
public function isStateTwo() {
if(strcmp(ObjectMapper::STATE_TWO, '2') == 0) {
return true;
}
}
public function isStateThree() {
if(strcmp(ObjectMapper::STATE_THREE, '3') == 0) {
return true;
}
}
Of course, others might disagree. I just don't like having classes cluttered up with 'almost the same' methods.

Categories