skip to content

In PHP, what does an (int) cast return for strings such as '42', ' 42 ', '42abc', '1e3', '0x1A' and 'abc'?

level: juniorimportance: must knowfreq 64%

answer

  1. a cast never fails
  2. leading numeric part is used
  3. exponent strings parsed as a whole
  4. no hex or octal from strings
  5. garbage becomes 0 silently

basics

~20 s

(int) takes the leading numeric part of a string and never fails: '42', ' 42 ' and '42abc' give 42, '1e3' gives 1000, while '0x1A' and 'abc' give 0. No warning is raised for the leading-numeric or non-numeric cases.

solid answer

~40 s

An `(int)` cast reads a string the way PHP reads **numeric strings**: optional surrounding whitespace, an optional sign, digits, an optional decimal part and an optional exponent. So `'42'` and `' 42 '` give `42`, and `'1e3'` gives `1000` because the whole numeric part, exponent included, is parsed before truncating. If the string only **starts** like a number, the cast uses that leading part: `'42abc'` gives `42`, `'1,200'` gives `1`, `'2.9kg'` gives `2`. A string with no leading number gives `0`: `'abc'`, `''`, and also `'0x1A'`, because casts never read hexadecimal or octal from strings. The cast itself never throws and, unlike arithmetic, raises no warning for trailing garbage. That makes it convenient and dangerous at once: bad input turns into a plausible number, so validate before you cast.

code

php · 10 lines
php
<?php
declare(strict_types=1);

$samples = ['42', ' 42 ', '1e3', '2.9', '42abc', '1,200', '0x1A', 'n/a', ''];

foreach ($samples as $raw) {
    printf("%-7s => %d\n", var_export($raw, true), (int) $raw);
}
// '42' => 42, ' 42 ' => 42, '1e3' => 1000, '2.9' => 2, '42abc' => 42,
// '1,200' => 1, '0x1A' => 0, 'n/a' => 0, '' => 0

go deeper

for a junior

Know that (int) keeps the leading number of a string and gives 0 when there is none, without any error.

for a middle

Explain the numeric-string grammar behind the cast, including whitespace, sign and exponent, and why hex strings and '1,200' do not convert the way people expect.

for a senior

Show where silent casts corrupt data, such as imports and form fields, and insist on validation before casting at every input boundary.

for a principal

Set a team rule that raw input is validated with explicit functions before any cast, and that casts appear only where the value is already known to be well formed.

## What an explicit cast does Writing `(int)` before an expression converts the value to an integer. For strings, PHP applies its **numeric string** rules, which the manual defines formally for PHP 8.0 and later: - optional **leading whitespace**; - an optional `+` or `-` sign; - digits, optionally with a decimal point and an **exponent** (`e` or `E`); - optional **trailing whitespace** (accepted since PHP 8.0). A string matching that whole pattern is a **numeric string**. A string that merely *starts* like one and then has other characters is a **leading-numeric string**. Anything else is **non-numeric**. ## The results, case by case | Input | `(int)` result | Why | |---|---|---| | `'42'` | `42` | integer numeric string | | `' 42 '` | `42` | whitespace on both sides is allowed | | `'+42'` / `'-42'` | `42` / `-42` | a sign is allowed | | `'042'` | `42` | leading zeros are decimal, not octal | | `'1e3'` | `1000` | the exponent is parsed as part of the number | | `'2.9'` | `2` | parsed as a float, then truncated toward zero | | `'42abc'` | `42` | leading-numeric: the numeric prefix is used | | `'1,200'` | `1` | the comma ends the numeric prefix | | `'0x1A'` | `0` | hex is not recognised; only the leading `0` counts | | `'abc'` | `0` | non-numeric | | `''` | `0` | empty string | Two rows surprise people most. `'1e3'` becomes `1000`, not `1`: the manual's `intval()` page notes that strings in scientific notation are parsed as numbers first, so the result is not just the leading digits. And `'0x1A'` becomes `0`: hexadecimal and octal notations are only understood in source-code literals, not in strings. `intval()` with an explicit base is the tool for those. ## No error, no warning The explicit cast is the **most permissive** conversion in PHP: 1. It **never throws**. There is no input string for which `(int)` fails. 2. It does **not warn** about trailing characters. php-src has a test named after this rule: explicit casts of leading-numeric strings "must work without warning". Arithmetic on the same string does warn; an `(int)` cast does not. 3. Garbage becomes **`0`**, which is a perfectly plausible value for a quantity, a price or an ID. That silence is why `(int)` is fine for data you have already validated and risky for raw input. ## A warehouse example A CSV export lists quantities, and one supplier writes them with thousands separators: ```php $qty = (int) $row['qty']; // '1,200' becomes 1, 'n/a' becomes 0 ``` Nothing fails; the stock level is simply wrong. The fix is to validate first, for example with `filter_var($raw, FILTER_VALIDATE_INT)`, which returns `false` for `'1,200'`, and to decide explicitly how thousands separators should be handled. ## (int) versus the other conversions - `(int)` and `intval($value)` with the default base 10 give the same result; `intval()` additionally accepts a **base** argument for hex, octal or binary strings. - `(float)` follows the same prefix rules but keeps the fraction: `(float) '2.9kg'` is `2.9`. - Passing a string to an `int` **parameter** is a different mechanism with stricter rules: non-numeric strings are rejected, and strict mode rejects strings altogether. That belongs with type declarations. ## How to answer in an interview State the rule first (numeric prefix, whitespace allowed, exponent parsed, no hex from strings, never fails), then give one example of each category, and finish with the consequence: an `(int)` cast is a conversion, not a validation, so input from users or files must be checked before it is cast.

  • What does intval('0x1A', 16) or intval('0x1A', 0) return, compared with (int) '0x1A'?
    `(int) '0x1A'` is `0`, because casts read strings only as decimal. `intval('0x1A', 16)` is `26`: with base 16 the `0x` prefix is accepted. With base `0`, `intval()` detects the base from the prefix (`0x` hex, a leading `0` octal), so `intval('0x1A', 0)` is also `26`. The base only has an effect when the value is a string.
  • Why is (int) '1e3' equal to 1000 rather than 1?
    Because `'1e3'` is a complete numeric string in scientific notation. PHP parses the whole numeric part first, which gives the float `1000.0`, and then converts it to an integer. Only when the characters after the digits are not part of valid number syntax, as in `'1abc'`, does the cast stop at the leading digits.
  • Does an (int) cast of '42abc' raise a warning in PHP 8.5?
    No. Explicit casts accept leading-numeric strings silently and return the numeric prefix, `42`. The warning "A non-numeric value encountered" belongs to arithmetic and other implicit numeric contexts, such as `'42abc' + 1`, not to explicit casts.

saying these in an interview costs you the question

  • Says (int) 'abc' throws a TypeError in PHP 8.
  • Believes (int) '0x1A' returns 26 because the string is hexadecimal.
  • Thinks (int) '1e3' returns 1 because only leading digits count.
  • Claims (int) '042' is read as octal and gives 34.
  • Treats an (int) cast as validation of user input.