Can I write this code shorter in PHP7?
if(isset($content[$i]['count']))
$content[$i]['count'] = 1;
else
$content[$i]['count'] += $content[$i]['count'];
You could use use a ternary
$content[$i]['count'] = isset($content[$i]['count']) ? 0 : += $content[$i]['count'];
Which is 3 lines less.
It also depends on your code, as the usual method is to set the initial count to 0, e.g. outside a foreach or whatever, then increment on each loop simply with $count++;
I wonder why though, as sometimes code just is what it is, and you should avoid being too terse for the sake of less code as it can make it less obvious or understandable.
Also, seems wrong setting your count to 0 if it's set, this would suggest only 1 count could happen.
I think the shortest possible way is with use of the coalesce operator:
$content[$i]['count'] = ($content[$i]['count'] ?? 0.5) * 2;
But it seems rather complex to understand quickly. :)
Related
I have to perform a big code fix in an old php project.
The issue is the following: I have a number statements where the code tries to add integers to non-initialized multimensional arrays, like this:
$array_test['first']['two']['three'] += 10;
But $array_test is declared just like this:
$array_test = array();
This situation gives me a lot of warnings in the project cause this code pattern happens like 16k times.
Is there any way to solve this like adding a statement like this:
if (!isset($array_test['first']['two']['three']))
{
$array_test['first']['two']['three']=0;
}
and then
$array_test['first']['two']['three'] += 10;
But I would like to do it in only one code line (for both statement, the if isset and the increment) in order to make a big and safe replace in my project.
Can someone help me?
Thanks and sorry for my english.
PHP does not yet (and probably won't ever) have a "null coalescing addition operator.
From PHP7.0, you can avoid the isset() call by null coalescing to 0. Demo
$array_test['first']['two']['three'] = ($array_test['first']['two']['three'] ?? 0) + 10;
If below PHP7 (all the way down to at least PHP4.3), you can use an inline (ternary) condition. Demo
$array_test['first']['two']['three'] = (isset($array_test['first']['two']['three']) ? $array_test['first']['two']['three'] : 0) + 10;
I cant seem to find any discussion about this.
In JavaScript to check if something exists, and use a default if it doesn't is like this:
var myvariable = mysetting || 3
In PHP from what I understand, the same thing can be done like this:
$myvariable = $mysetting ?: 3;
Am i completely off on this? I understand the implications of not using isset() and not_empty() and all that, but if I just want to know if the variable exists and is truthy otherwise use a default - this should work I think. Does this syntax have any hidden bad things about it?
Because it doesn't work. That code will still throw a notice Notice: Undefined variable: mysetting in C:\wamp\www\x.php on line, which might be visible to the user, depending on the PHP settings. Apart from that, it will work. If notices are suppressed, then the end result is correct.
So, to get around that, you can either use isset, which isn't really a function, but a language construct, and is specifically designed to do this check:
$myvariable = isset($mysetting)? $mysetting: 3;
Or you can suppress the notice using the # operator:
$myvariable = #$mysetting ?: 3;
For this specific case, maybe it's acceptable, but in general the use of # is frowned upon by many. Personally, I would rather use a couple more characters and make it feel less 'dirty', but it's a matter of opinion.
Another reason why people may not use it, is that it's relatively new (PHP 5.3). Not everyone might know of this new syntax or be comfortable with it. They have been used to isset for years, and old habits die hard.
Those statements are not equivalent. From what I have found the javascript is equivalent to:
if (!mysetting) {
myvariable = 3;
} else {
myvariable = mysetting;
}
Whereas the equivalent PHP statement using the ternary operator would be:
$mysetting = isset($myvariable) ? $myvariable : 3;
aka:
if( isset($myvariable) ) {
$mysetting = $myvariable;
} else {
$mysetting = 3;
}
The ternary operator is essentially a shorthand for and if/else statement, and the first operand is interpreted as a logical expression.
Is there a way to do the following, but in short if/then syntax:
if($method->isAbstract()) {
$details['abstract'] = true;
}
If I do:
$details['abstract'] = $method->isAbstract() ? true : null;
It is not quite the same, because the array key abstract is always set. I only way the array key set if isAbstract() is true. To clarify, if isAbstract() is false, don't set the key in the array.
Thanks.
I don't have a PHP interpreter at hand, but I guess this will work:
$method->isAbstract() && $details['abstract'] = true;
Update: yes, it works → http://codepad.org/lW23FR0j
I wouldn't worry too much about trying to shorten three lines of code, which in all honesty could be written in one line anyway:
if ( $obj->method() ) $data['key'] = 'value' ;
However, as #Mischa's answer demonstrated, there are shorter ways. You could use the logical operator && to perform assignment as well:
$obj->method() && $data['key'] = 'value' ;
In this method, the expression on the right is evaluated if the expression on the left is "true".
Another method is the new shorter ternary operator which excludes the second expression. While you presented the long-form ternary as an alternative in your original question, you could also consider the new format provided since PHP 5.3
!$obj->method() ?: $data['key'] = 'value' ;
Since we're not using the second expression, we invert our test in the first expression. No longer checking for a positive, we are now looking for a negative. When the negative is found, our assignment takes place.
I don't provide this answer to encourage you to avoid 3-line solutions, but only to encourage you to feel free to explore shorter solutions from time to time as they often times lead to parts of the language you may not have otherwise discovered.
I'm curious is there a way to write a shorthand setter in PHP. My primary quest when writing code is to make it as tight as possible and I think the following is kind of cumbersome:
$value = "Which array do I go in?";
if(true)
$arr_1[] = $value;
else
$arr_2[] = $value;
Is there a better way to write that? I tried to use the shorthand if:
(true)?$arr_1[]:$arr_2[] = "Which array do I go in?";
But that doesn't seem to work. Anyone have any cool tricks for this type of situation?
Thanks!
There is no shorthand for what you are trying to do. Also you should realize that making code "as tight as possible" often comes at the cost of readability.
EDIT: There is some ugly hacks to do what you want, but I would strongly recommend against. E.g.:
$GLOBALS[cond ? 'varname1' : 'varname2'] = $value;
Another hack would be:
$arr = ($cond ? &$arr_1 : &$arr_2);
$arr[] = 'Which array do I go in';
it's two lines but it doesn't require global and would work in a function. However for readability it is probably better to use an if statement. (Note: the & is making a reference to the variable, which is why this works). Another (which might make you understand HOW the ternary operator works) would be:
$cond ? $arr_1[] = $value : $arr_2[] = $value;
You see the ternary operator only evaluates (runs the code path) of the successful evaluation (on the right side of the ? if true, on the right side of : if false). However if you think this is faster than using 'if' you are wrong, your less 'tight' code will actually perform better.
Another option (e.g. if you can't/don't want to use globals).
${$cond?'arr_1':'arr_2'}[] = $value;
Is there difference between ternary operator and if condition in php ?
if yes, kindly provide.
The ternary operator is an operator, so it forms an expression. So it will have a value that you can assign to a variable or use however you want. It is used for simple situations where a variable can take two possible values depending on a condition.
For example: $status = $age > 18 ? 'adult' : 'child';
Although possible, you should not nest the ternary operator.
The control structure if is something absolutely different. The only thing they have in common that both evaluate a condition (true/false). if is used to execute code fragments based on the result of that condition. You will find yourself using if most of the time (in fact, you can live without the ternary). In certain situations, it is less code and more readable if you replace certain types of ifs with the ternary, like this one:
if ($age > 18) {
$status = 'adult';
} else {
$status = 'child';
}
Personally, I only use the ternary operator if it fits on one line. If it need to span, then it's time for the good old
$value = ($a < 0) ? 'minus' : 'plus';
also you can see one interesting question how multiple ternary works :
unusual ternary operation
If statements are faster than ternary, but in most cases it doesn't matter.
Here is a post on the performance of If statements vs ternary.
Summary: It's basically the same unless you are evaluating large objects because ternary copies the objects being evaluated. This was using PHP 5.3 I'm not sure if it has been changed in current versions.
The ternary operator can do anything that an if/else statement can. In some cases it can provide brevity and expressiveness, but beware: it is easily abused.
One thing I like it for is checking for null:
$foo = (is_null($bar)) ? 0 : $bar->someNumber();
If my PHP memory serves me correctly, then it can also be used on an lvalue:
((is_null($foo)) ? $bar : $foo) = $quux;
It can be easily overdone though, such as in this C++ example, where it is used in place of loops and if/else statements:
while( ( ! printingStars) ?
( ( ! reachedMax) ?
( ( ++numberOfStars == n - 1) && (reachedMax = 1) )
: --numberOfStars ), printingStars = 1, starsLeft = numberOfStars
: ( ( ! starsLeft ) ?
printingStars = 0, (std::cout<< std::endl), 1
: --starsLeft, (std::cout<< "*"), 1 ) );
Use with caution.
Maybe another point of view: Performance.
A while ago I noticed that the ternary operator is faster than an if(). I don't know if this still applies to the latest versions of PHP.
< wild guess >
The reason may be that an if() allows more flexibility like using code blocks ({ }). A ternary operator basically is just testing an expression and grabbing a value depending on the result of the test.
Going back into my Assembler-days I'd say that an if() has to jump in memory and, therefore, takes a bit more time to do things.
< /wild guess >
However, this may be become noticeable only if the code is executed a decent number (1k+) of times.
There is a big difference in maintenance, if you use none trivial logic.
If you have a difficult problem you need under circumstances much more time, to sove it, as if you have an 'if ... then' in your code. And be sure: it's happen!
The time is not a friend of ternary operator. Fast to write, but not fast to understand, if the years gone!