4

Consider the following line of code:

<?php
$x = 10;
$y = 7;

echo '10 - 7 = '.$x-$y;
?>

The output of that is 3, which is the expected result of the calculation $x-$y. However, the expected output is:

10 - 7 = 3

My question therefore is, what happened to the string that I'm concatenating with the calculation? I know that in order to produce the result I expected, I need to enclose the arithmetic operation in parenthesis:

<?php
$x = 10;
$y = 7;

echo '10 - 7 = '.($x-$y);
?>

outputs

10 - 7 = 3

But since PHP does not complain about the original code, I'm left wondering what the logic behind the produced output in that case is? Where did the string go? If anyone can explain it or point me to a location in the PHP manual where it is explained, I'd be grateful.

Jens Wegar
  • 4,147
  • 4
  • 29
  • 34

4 Answers4

4

Your string '10 - 7 = ' is being concatenated with $x. Then that is being interpreted as an int which results in 10 and then 7 is subtracted, resulting in 3.

For more explanation, try this:

echo (int) ('10 - 7 = ' . 10); // Prints "10"

More information on string to number conversion can be found at http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion

If the string starts with valid numeric data, this will be the value used

Rusty Fausak
  • 7,355
  • 1
  • 27
  • 38
  • -1 because this answer is not correct. The result he is getting is `3`, not `10`, and your explanation is explaining the wrong thing. – FtDRbwLXw6 Sep 27 '11 at 19:43
  • Err.. Are you sure I am explaining the wrong thing? I know he's getting `3` as a result. I was explaining why. – Rusty Fausak Sep 27 '11 at 19:45
  • You were explaining why incorrectly. Running your code - `echo (int) ('10 - 7 = ' . 10);` - will output `10`. His outputs `3`. – FtDRbwLXw6 Sep 27 '11 at 19:46
  • Well obviously! It was sample code to explain implicit `int` casting. You'll note I prefixed it with "For more explanation.." – Rusty Fausak Sep 27 '11 at 19:47
  • I removed the -1, but I think it's very confusing to use that example, which has some parts of the original code, but not all of it. You should either provide an exact example, or one significantly different than the code so that it's not misinterpreted :) – FtDRbwLXw6 Sep 27 '11 at 19:53
  • Thanks! The minute I read your answer I realized that it makes perfect sense. The one thing that threw me off track was that the string was interpreted as the value 10. I was under the impression that a string would always be interpreted as 0 unless it contains only numeric values. But apparently PHP reads the beginning of the string up until a character it doesn't recognize as a number and then uses everything it's read so far as the interpreted value. – Jens Wegar Sep 27 '11 at 20:39
  • More information on string to number conversion can be found at http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion – Rusty Fausak Sep 27 '11 at 20:46
4

In this code:

echo '10 - 7 = '.$x-$y;

The concatenation takes precedence, so what you're left with is this:

echo '10 - 7 = 10'-$y;

Because this is trying to perform integer subtraction with a string, the string is converted to an integer first, so you're left with something like this:

echo (int)'10 - 7 = 10'-$y;

The integer value of that string is 10, so the resulting arithmetic looks like this:

echo 10-$y;

Because $y is 7, and 10 - 7 = 3, the result being echoed is 3.

FtDRbwLXw6
  • 27,774
  • 13
  • 70
  • 107
  • Wish I could accept more than one answer as the correct one. But thumbs up for a clear step by step explanation of why the code behaved the way it did. – Jens Wegar Sep 27 '11 at 20:41
2

. and - have the same precedence, so PHP is reinterpreting '10 - 7 = 10' as a number, giving 10, and subtracting 7 gives 3.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • Thumbs up for the link talking about precedence, which together with the other answers gave me a good understanding of what happened in the code. – Jens Wegar Sep 27 '11 at 20:44
0

PHP runs operations in the order defined here ; https://www.php.net/manual/en/language.operators.precedence.php

Take a look at this example ;

$session_period = 30;    
new \DateTime('now -' . $session_period+1 . ' minutes');

Beware! This will NOT give you the time 31 minutes ago. In this case PHP just interprets starting from the leftmost part of an expression so this simple-looking expression returns the wrong result;

Because ;

  • 'now -' . $session_period => 'now -30'
  • then PHP will cast the string to 0 and add 1 to that => 1
  • and 1 . ' minutes' => '1 minutes'

That's why the expression above will give you the result of

new \DateTime('1 minutes')

To avoid this kind of confusion, use () like this ;

new \DateTime('now -' . ($session_period+1) . ' minutes');
Erdinç Çorbacı
  • 1,187
  • 14
  • 17