0

I want to write some text Year: X | percentage: $percentage%, where X is based on the value contained in $year.

$year can be 2010, 2011... but also 0. In this case, we have to write the word "All"; otherwise, the year itself.

Year: 2011 | percentage: 2%    // case $year not 0
Year: All | percentage: 2%     // case $year == 0

This code seems very long for what is required:

echo "year: ";
if ($year==0)
     echo "All";
else
     echo $year;

echo " | Percentage: $percentage%";

So I wonder: how can we make this code shorter and clearer?

Note I posted my own answer because I wanted to share the way I found after spending some time working on it. Anyway, I see there are other ones that look quite good.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 1
    I'd use brackets and make it longer and easier to read. The answer below is incredibly hard to read. – Jessedc Feb 19 '13 at 12:56
  • You should have posted your 'answer' in your original question and asked for other ways of doing what you were looking at doing. Your answer is the least readable. – Jessedc Feb 19 '13 at 13:08
  • @mickmackusa aren't there any better canonical for ternary operators? The answer there is not very generic – fedorqui Apr 09 '22 at 08:02
  • There will be tens of duplicates between SO's birth and the date of your question. If you find a better one, I am happy to change the dupe or add it to the list. – mickmackusa Apr 09 '22 at 08:06
  • @mickmackusa there is no need for the duplicate to be older than mine, just one that is better. – fedorqui Apr 09 '22 at 08:23
  • @fed I agree. My offer stands. Find a better one and I'll fix it up. On the other hand, do we actually need one hunder signposts for this operation? Anyhow, I am busy down a rabbit hole -- whistle blowing the `echo sprintf()` antipattern. `SELECT a.Id as [Post Link], a.CreationDate FROM Posts a INNER JOIN posts q ON q.id = a.parentid WHERE q.tags LIKE '%<##tag?php##>%' AND a.PostTypeId = 2 AND LEN(a.Body) < 300 AND a.Body LIKE '%echo sprintf(%' ORDER BY a.CreationDate ASC` – mickmackusa Apr 09 '22 at 08:29

4 Answers4

3

You can use a ternary operator:

echo ( condition ? "if condition true" : "otherwise")

For this specific case:

echo "Year: ". ((0==$year) ? "All" : $year) ." | Percentage: $percentage%";
fedorqui
  • 275,237
  • 103
  • 548
  • 598
2

Might not be a direct answer to you questions, but IMHO you should do something like:

$renderedYear = $year;
if ($year == 0) {
    $renderedYear = 'All';
}

echo 'Year: ' . $renderedYear . ' | Percentage: ' . $percentage . '%';

Always prefer readability over shortness of code. Pixels on screen are waaaay cheaper than debugging time.

Also instead of concatenating you may want to use *printf.

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
1

I would style it using sprintf() as it's far easier to read.

echo sprintf("year: %s | Percentage: %s %%", ($year == 0) ? "All" : $year, $percentage);
Jessedc
  • 12,320
  • 3
  • 50
  • 63
  • I was going to recommend the same. However, don't use `echo sprintf` when you have `printf` for the purpose :) (also, since you commented on the ease of reading, params might be easier to understand on separate lines - and further, `===` instead of `==`) – eis Feb 19 '13 at 13:01
  • Updated with printf. The use of `===` is up to the OP. – Jessedc Feb 19 '13 at 13:05
  • printf replaces the combination of echo + sprintf, now you replaced only sprintf. – eis Feb 19 '13 at 13:08
  • moved back to using sprint as I originally intended it. – Jessedc Feb 19 '13 at 13:13
  • This is a way I find interesting. I will take a look, thanks. – fedorqui Feb 20 '13 at 09:35
  • `echo sprintf()` is an "antipattern". There is absolutely no reason that anyone should ever write `echo sprintf()` in any code for any reason -- it should be `printf()` without `echo` every time. – mickmackusa Apr 09 '22 at 02:49
1

I am sorry if this doesnt work (cant test it right now) but in C (which is somewhat similar to php) you can negate numbers directly, i belive you could also use:

echo "Year: ". (!$year ? "All" : $year) ." | Percentage: $percentage%";
Kyborek
  • 1,519
  • 11
  • 20
  • 1
    It worked, @Kyborek! I think it is a very nice way of showing it. In fact, could also be writen like `($year ? $year:'All')`, as someone exposed in a comment above. – fedorqui Feb 20 '13 at 09:33
  • We can meta think your sentence "no negation == afirming"! : ) – fedorqui Feb 20 '13 at 14:06