1

For the following code snippet the answer is 15.

$a = '5 USD';
$b = 10;
echo $a + $b;

But in the variable $a, if 5 is in between 'USD' or after 'USD' the output is 10. Why is it so?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
웃웃웃웃웃
  • 11,829
  • 15
  • 59
  • 91
  • 10
    It's called "loose typing" and "type juggling" http://www.php.net/manual/en/language.types.type-juggling.php – Mark Baker May 31 '13 at 06:34
  • Can you explain a little more @Mark Barker – 웃웃웃웃웃 May 31 '13 at 06:35
  • 2
    The Page I've linked says pretty much everything.... you use an addition operator with another (integer) value (10), so PHP tries to add by converting the string to an integer value that can be added to the 10 – Mark Baker May 31 '13 at 06:36
  • 2
    PHP does not have variable types defined. Therefore when you do addition operation, it tries to convert to numeric format. It converts string to a number only if string starts with digit and as soon as it finds non-digit char, it stops, thus $a becomes 5. – Evaldas Dzimanavicius May 31 '13 at 06:38

3 Answers3

13

From php.net:

When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

Literally:

  1. $a + $b means numeric + numeric.
  2. "5 USD" starts with a valid numeric data, so PHP converts it into 5.
  3. "USD 5" or "U5SD" starts with not valid numeric data, so PHP converts it into 0.

UPDv1:

<?php
header('Content-Type: text/plain');

function plus($a, $b){
    echo $a, ' + ', $b, ' = ', $a + $b, PHP_EOL;
}

plus('5 frogs', 3);   // 5 + 3 = 8
plus('frogs: 5', 3);  // 0 + 3 = 3
plus('f5rogs', 3);    // 0 (not HEX)  + 3 = 3
plus('0xF5', 3);      // 245 (HEX)    + 3 = 248
plus('0011b', 3);     // 11 (not BIN) + 3 = 14
plus('1E5', '1.2xx'); // 100000 (FLOAT) + 1.2 (FLOAT) = 100001.2
plus('true', 2);      // 0 (not BOOL)   + 2 = 2
?>

Also, check out this: php string number concatenation messed up.


UPDv2:

There is "no way" for PHP to typecast string value to octal, regardless of zero-fill effect. Still, as mentioned before, PHP able to typecast string to hexadecimal.

<?php
header('Content-Type: text/plain');

function plus($a, $b){
    echo $a, ' + ', $b, ' = ', $a + $b, PHP_EOL;
}

plus(008, 12);     // Invalid octal, PHP assumes it is 0. Result: 12.
plus('008', 12);   // Invalid octal? No, it is decimal. Result: 20.
plus(0x0F, 1);     // Valid hexadecimal. Result: 16.
plus('0x0F', 1);   // Valid hexadecimal. Result: 16.
plus('0x0X', 1);   // Invalid hexadecimal, PHP assumes it is 0. Result: 1.
?>

It is not mentioned in "string to number conversion" docs.

Community
  • 1
  • 1
BlitZ
  • 12,038
  • 3
  • 49
  • 68
6

See PHP Manual Language.types.string.conversion

String conversion to numbers

When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

Examples can be found in the manual (link above)

$foo = 1 + "bob-1.3e3";           // $foo is integer (1)
$foo = 1 + "bob3";                // $foo is integer (1)
$foo = 1 + "10 Small Pigs";       // $foo is integer (11)

Answering your question

$a = '5 USD'; // The string starts with number, so by an implicit cast to int, it will be 5
$b = 10;
echo $a + $b; // = 15

In the other example you wrote

$a = 'USD 5'; // The string does not start with a number, so by an implicit cast to int, it will be 0
$b = 10;
echo $a + $b; // = 10

For more information on this conversion, see the Unix manual page for strtod(3).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Robert
  • 19,800
  • 5
  • 55
  • 85
1

Because

php > echo (int)"a";
0

So if you feed the PHP executable with

php > "USD 5" + "10"

it will cast both operands to integers:

php > (int)"USD 5" + (int)"10"

And thus you will receive result of 0 + 10.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nemoden
  • 8,816
  • 6
  • 41
  • 65