Would someone give an explanation of this PHP switch block? - php

I'd like to ask what this code is doing, and if someone could explain to me with comments?
I am trying to understand what it is doing. I am guessing it switches between them depending on the result of the statements E.g. 2 < 1 and 2 > 1. Then it is setting the dates in a year month day format?
Am I on the right track?
switch (true) {
case ($UserBirthday < $CurrentDate2) :
$CurrentDate->setDate($UserBirthday->format('Y'), $CurrentDate->format('m'), $CurrentDate->format('d'));
break;
case ($CurrentDate2 < $UserBirthday) :
$UserBirthday->setDate($CurrentDate->format('Y'), $UserBirthday->format('m'), $UserBirthday->format('d'));
break;
}
$interval = $UserBirthday->diff($CurrentDate);
$difference = $interval->format('%R%a')-1;
Also, can I change it to an if/else statement like this?
if ($UserBirthday < $CurrentDate2) {
$CurrentDate->setDate($UserBirthday->format('Y'), $CurrentDate->format('m'), $CurrentDate->format('d'));
}
else if ($CurrentDate2 < $UserBirthday) {
$UserBirthday->setDate($CurrentDate->format('Y'), $UserBirthday->format('m'), $UserBirthday->format('d'));
}
$interval = $UserBirthday->diff($CurrentDate);
$difference = $interval->format('%R%a')-1;

While there doesn't appear to be any benefit from using switch over if..elseif..else statements in your code example, switch is often used in place of long, ugly if..elseif..elseif..elseif..etc. statements. I suspect this is what the author of your code example was modeling.
You can read about switch's many uses at http://phpswitch.com/.

Actually, I've changed my mind, there is nothing wrong with this code, albeit maybe a bit confusing.
Normally you would pass a variable into the switch statement and compare its values in the cases:
switch($a) {
case 1:
// some code
break;
}
In this case, they are basically only checking if something is true, so they pass true into the switch and then each case is a logic statement.
Either way, whatever is passed into the switch is compared with a == against what is in each case. Since switch is useful for large sets of if/else it is valid to use in this case if they wanted to.
However, since they used it in a way that most developers may not be familiar with, it can be confusing and some additional commenting might be wise.
But again, I was wrong, there actually isn't anything wrong with this code.

Related

switch statement having only one case

I only have one case in switch statement
switch ($coreName) {
case 'stock':
$result['website'] = ($result['website']) ? $websiteStatus[$result['website']] : "";
break;
}
My question is this a good practice or shall I use an if statement for this? Any performance differences or anything?
Use if else Only when :
1. you have only 2 or more conditions OR You have multiple conditions in single if else.
And use switch when
1. You have to compare `ONE` variable value against multiple.
In your case if else is better
Nothing speaks against this from a technical point of view.
So the question to answer is: why did you implement a switch statement instead of an if conditional?
I'd say the default should be an "normal" if condition, unless special reasons point to a switch instead. The two primary reasons might be:
extensibility (for later additions)
readability (for other coders)
Especially the first case should be considered here. If it might become necessary to extend the handling, then certainly using a switch right away is a good practice.
If you go to phpBench.com and scroll down to see the results between if and case, you can see that using an if statement is slightly faster, but the results aren't too different. (Screenshot below)
You may as well use an if as it is easier to read, less code and is still faster (even by only a tiny amount).
if($corename === "stock") {
$result['website'] = ($result['website']) ? $websiteStatus[$result['website']] : "";
}
case should only be used when you compare multiple values rather than just one. This is the same as using elseif. Using if is the most suited for this specifically.
Why not simply do a simple if, like this :
if($coreName == 'stock')
{
$result['website'] = ($result['website']) ? $websiteStatus[$result['website']] : "";
}
Hope this helps.

If a switch matches multiple cases will all matching cases run?

I'm attempting to go through a large number bitwise tests, 32 to be exact, where there could be multiple matches. The only method I can think of that would work is to use a whole long list of if statements, e.g.
$test = 3;
if(($test & 1) == 1) {
do something...
}
if(($test & 2) == 2) {
do something else...
}
The other possibility I was thinking of to cut down on the code, although probably not by much is a switch statement. That said, I'm not even sure if what I am thinking of will even work:
$test = 3;
switch($test) {
case ((1 & $test) == 1):
do something...
break;
case ((2 & $test) == 2):
//Will this run?
do something else...
break;
}
Will the break end the switch? Or will the switch continue and each case run that the bitwise operation returns true?
I ask because my actual program will have 32 different tests, and I don't want to write all 32 just to find it doesn't work and Google hasn't turned up anything on this.
If this doesn't work is there a solution that will, or am I relegated to a large number of if statements?
No this is not the case. Only one of the switch cases will run in your example. As soon as break is encountered the switch processing ends. Only one branch will match. In PHP I think (but you might want to double check) the first matching case will run.
With multiple possible matches you will need to use a set of if statements (note do not use if...elseif)
I would convert to
if($test & 1) {
// do stuff
}
if(test & 2) {
// do stuff
}
Well first, using switch with int this way is not really recommended. It's not a good practice / not really readable / not comfortable. I would say it does not even work, although I have a doubt now... depending on versions and stuff, I'm not aware enough of these things.
Then, to answer your question, you only go inside the first matching case... then the break makes you leave the switch. However, you can omit the break and it will go through the second case.
Anyway, you should make more use of OOP to characterize better what you intend to do, and things will probably get more simple and clearer.

Which is Faster and better, Switch Case or if else if?

Which is the better and fastest methods : if or switch ?
if(x==1){
echo "hi";
} else if (x==2){
echo "bye";
}
switch(x){
case 1
...
break;
default;
}
Your first example is simply wrong. You need elseif instead of just else.
If you use if..elseif... or switch is mainly a matter of preference. The performance is the same.
However, if all your conditions are of the type x == value with x being the same in every condition, switch usually makes sense. I'd also only use switch if there are more than e.g. two conditions.
A case where switch actually gives you a performance advantage is if the variable part is a function call:
switch(some_func()) {
case 1: ... break;
case 2: ... break;
}
Then some_func() is only called once while with
if(some_func() == 1) {}
elseif(some_func() == 2) {}
it would be called twice - including possible side-effects of the function call happening twice. However, you could always use $res = some_func(); and then use $res in your if conditions - so you can avoid this problem alltogether.
A case where you cannot use switch at all is when you have more complex conditions - switch only works for x == y with y being a constant value.
According to phpbench.com, if/elseif is slightly faster, especially when using strict comparison (===).
But it'll only really matter if you want to shave off microseconds on a function that'll be called thousands of times.
General rule is use switch whenever the number of conditions is greater than 3 (for readability).
if / else if / else is more flexible (hence better), but switch is slightly faster because it just computes the condition once and then checks for the output, while if has to do this every time.
EDIT: Seems like switch is slower than if after all, I could swear this was not the case...
When using ==, performance of if ... elseif compared to switch is almost identically. However, when using ===, if ... elseif is about 3 times faster (according to: phpbench).
Generally, you should go with what is most readable and use switch when making more than 3 comparisons. If performance is a major concern and you don't need to make any type conversions, then use if ... elseif with ===.
It's depending on usage. If you have fxp status (online, away, dnd, offline...) its better use switch.
switch(status)
{
case 'online':
...
}
But if you wanna something like this
if ((last_reply.ContainsKey(name)) && (last_reply[name] < little_ago))
or
if (msg.ToString()[0] == '!')
its better use if else.
I found this post: https://gist.github.com/Jeff-Russ/2105d1a9e97a099ca1509de1392cd314 which indicates switch/case to be faster than if/elseif with ===.
They also indicate nested if statements which makes a lot more sense and also provide far better results.
Their times:
nested if/elseif === : 0.25623297691345 (NESTED IF)
switch/case : 0.33157801628113 (SWITCH CASE)
if/elseif with === : 0.45587396621704 (FLAT IF)
only if with === : 0.45587396621704 (ONLY IF)
Switch is faster than if because switch uses jump table and jump table is made by compiler during compile time and run by cpu/os. For ex if you have 100 cases and you will get your value in 100 th one so what do you think it will run all 99 conditions...no..it will directly jump to 100th one with the help of jump table..so how can we prove this?...if you write default statement at start and then run the program will you get default value,since it is at start? No..you will get your desired answer because of jump table..it knows where is default and where is your assigned value and it will directly take you to your desired answer..
Talking about which is better...
Every work that can be done in if can be done in switch..
But for lesser condition if is better and for more conditions switch..like upto 3 conditions if is good.. after that a good programmer uses switch..that's all
I belive the compiler will turn them into very similar, or maybe even identical code at the end of the day.
Unless you're doing something weird, don't try and do the optimisation for the compiler.
Also, developer time is generally more important than runtime (with the exception of games), so it'sbbetter to make its more readable and maintainable.
in my opinion the "if/else" is faster but not better than switch
but i prefer this:
echo ($x==1?"hi":($x==2?"bye":""));
if you have to do 1,2 cases like if/else if/else

PHP Coding styles return; in switch/case

we're trying to implement new coding style guidelines for our team, the php codesniffer is printing an warning on switch case statements when no "break" is found like:
switch ($foo) {
case 1:
return 1;
case 2:
return 2;
default:
return 3;
}
is there any good reason to use :
switch ($foo) {
case 1:
return 1;
break;
}
?? the break is never reached ?
It's perfectly valid to leave out the break when you return from a switch.
But it's fairly common practise to add explicit breaks to every case as a defensive programming practise.
switch ($foo) {
case 1:
return 1;
break;
case 2:
return 2;
break;
}
The idea is that should you later change your code in case 1 and remove the return statement, you could forget to add a break.
That would accidentally cause program flow to fall through to case 2.
switch ($foo) {
case 1:
somethingDifferent();
case 2:
return 2;
break;
}
Falling through case statements is slightly unusual and you should add a comment to your code when you do it to show that it's intentional.
switch ($foo) {
case 1:
somethingDifferentAndWeWantToDoCase2AsWell();
// fallthrough
case 2:
return 2;
break;
}
As with many defensive programming practises you've got to balance whether the code bloat - which potentially clutters your code and make it less readable - is worth it or not.
If your "php codesniffer is printing a warning" try to get another better codesniffer and don't forget to try to use the last PHP stable version. You can, of course, write a breakafter one return, but it doesn't make sense, because it will never be read at all. Your code is OK.
Look at this:
$fun = function(int $argument): string {
switch ($argument) {
case 1:
return "one";
case 2:
return "two";
default:
return "more than two";
}
};
$str = $fun(4); // return "more than two"
In my opinion, this is simpler and better: fewer lines => less code to maintain :-)
To answer your question, no there's no good reason to have something that does nothing. Think about it this way, a comment after the return instead of a break saying "don't forget" will have the same affect - none. And put that way it sounds silly, right?
Unless you need to set a var to use later, I'd suggest the approach you have is perfectly fine. I knew the code's intent within 2 seconds from looking at it. Having a break just creates confusion.
There is no one size fits all really. The correct approach depends on whichever fits the scenario. Set a variable in each case and having a break may be the right way, or perhaps just return makes sense.
Some observations on other suggestions made in answers:
1) Not having a break after return means problems could arise if code is later changed
Whenever possible, code should be explicit, as well as readable and clear. We can also code in a way to make future changes easier. But in something as simple as a switch it should be no problem and need no safety net to refactor a case later to add or remove a return or break.
In fact, if you removed a return and "didn't notice there was no break" then that's a poor mistake and could be made in any part of coding. No gotcha checking will save you from that. And one should be very careful coding for future potentials, as that potential may never happen, or something else may happen, and you just end up maintaining obsolete code for years.
In the same vein this was argued to be a safety net for future changes - What if you remove the return and accidentally left in that safety net break when you should have removed it?
Even if this switch statement was a life or death scenario, really serious code, I would be against adding the "pointless" break after the return. Just make sure whoever was working on the code knew what they were doing, and it was code reviewed by enough eyes and tested fully.
If it was that serious, then you'd have additional checks in place better than a proposed safety net to catch sloppy devs.
To argue that break after return adds a safety net, means you're not coding or testing properly. If this is a safety net deemed useful then it's likely there are tons of bugs in the code in potentially more serious places.
The wiki article of "Defensive Programming" was linked to, but it's not relevant here:
Defensive programming is a form of defensive design intended to ensure
the continuing function of a piece of software under unforeseen
circumstances.
Leaving a safety net break in is not a scenario of unforeseen circumstances, nor defensive programming. It's just bad coding, and you can't litter your code with back up code just in case you don't code correctly when you change something. That's such a bad approach to coding. The argument that "if someone removed return it won't work", well you could also have a typo in the case var, or forget to write the case, or...
The return returns, and you don't code "defensively" to avoid a return failing. That would mean PHP is broken, and you aint gonna fill your code with safety nets to cater for that. That's something you have on a much higher level up.
2) break after return keeps it explicit
But it's explicitly wrong. The return returns, so the break won't happen. To me that is scratch head time wondering if I've missed the intent - not for long as it's clear what will happen, but there will be a moment where I ponder it to make sure I've not missed something.
While it's not invalid or error to have a return and then break in the same case, it's just entirely pointless as the break does nothing. It's pointless code that needs to be seen, maintained, and figured out as it's not logical.
If explicit is the core goal and having a break after a return urks you because it's pointless, then I'd say it'd be better to set a variable and break, then return the variable after breaking from the switch.
Like #RageZ answer https://stackoverflow.com/a/1437476/2632129
3) Set a variable and return after the switch statement is completed
There's nothing wrong with this approach at all, but if there's no reason to store the value in a variable (later use etc) then it's good to return immediately when there's no need to hang around to do anything else.
That shows clear intent - return a value as soon as the case is matched.
I have much better solution.Please follow below code for above switch statment:
$result = 3; // for default case
switch ($foo) {
case 1:
$result = 1;
break;
case 2:
$result = 2;
break;
default:
// do nothing
}
return $result;
It will not result in any error and code is also fine with concepts.
I am not an expert in perfect coding but I think the validator would prefer something like that
switch ($foo) {
case 1:
$ret = 1;
break;
case 2:
$ret = 2;
break;
default:
$ret = 3
}
return $ret
I think using return in case statement to break the flow of the code is not really a best practice. So that's why the validator say there is no break ...
For your question about at category, I don't know ... sorry
From the PHP manual (http://us3.php.net/manual/en/control-structures.switch.php) :
PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case. For example:
<?php
switch ($i) {
case 0:
echo "i equals 0";
case 1:
echo "i equals 1";
case 2:
echo "i equals 2";
}
?>
Here, if $i is equal to 0, PHP would execute all of the echo statements! If $i is equal to 1, PHP would execute the last two echo statements. You would get the expected behavior ('i equals 2' would be displayed) only if $i is equal to 2. Thus, it is important not to forget break statements (even though you may want to avoid supplying them on purpose under certain circumstances).

Does the order of cases matter in PHP switch statements?

In PHP switch statements, does placing more common cases near the top improve performance?
For example, say the following function is called 1,000 times:
<?php
function foo_user ($op) {
switch ($op) {
case 'after_update':
//Some Stuff
case 'login':
//Some other Stuff
}
}
If in 990 of the 1,000 of the times the function is called the $op argument is 'login', would performance improve by having case: 'login' above case 'after_update': in the switch statement? For example, would the code after case 'after_update': be ignored if $op = login was passed?
I've run some informal tests on this idea, but the difference has been negligible -- perhaps because the code after case: 'login' and case 'after_update': are both trivial. I'd prefer to avoid setting up a more extensive test with non-trivial operations if someone knows the answer outright.
This is specifically a Drupal question, but I imagine it could be addressed by anyone who is familiar with optimizing PHP.
This is likely going to be called a micro optimisation. I don't believe there would be a large difference.
However, order does mean a lot to the logic of the switch case if you allow the cases to fall through, example
switch ($var) {
case 0:
case 1:
do_it();
break;
case 2:
do_it_else();
break;
}
The order is important, the case will fall through and execute any code until it hits a break.
I wouldn't be concerned about the speed of the switch case, unless you had say 100 possible cases. But if then, it'd be likely you should refactor your code.
You will need a whole lot more than 1000 cases to notice a difference, but yes, there is a difference. I wrote up a test:
function test_switch($value) {
$startTime = time() + microtime();
for ($i = 0; $i < 10000000; $i++) {
switch($value) {
case "abcdefg":
$j = $j + 1;
break;
case "hijklmno":
$j = $j + 1;
break;
}
}
$endTime = time() + microtime();
echo "Total time for argument $value: " . ($endTime - $startTime) . "<br>\n";
}
test_switch("abcdefg");
test_switch("hijklmno");
That is 10 million executions of the switch statement. The output is:
Total time for argument abcdefg: 3.99799704552
Total time for argument hijklmno: 5.38317489624
So there is a difference, but it won't be noticeable until you reach on the order of 10 million executions, depending on your processor of course.
If you do not use break; to close each statement PHP will continue to evaluate cases until the end of the switch block which may impact performance in a large enough block. The order then becomes important for getting the behavior you are looking for.
From PHP.Net:
The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case. For example:
<?php
switch ($i) {
case 0:
echo "i equals 0";
case 1:
echo "i equals 1";
case 2:
echo "i equals 2";
}
?>
I would caution against relying on this behavior though and use break; for each case as that will remove some ambiguity when you revisit the code later.
Usually, it's recommended to write the most likely case first, the second one next...
but like Alex wrote,
This is likely going to be called a
micro optimisation. I don't believe
there would be a large difference.

Categories