An underscore in a numeric literal is ignored by the parser and exists solely so a person can see how many zeros there are.
const MAX_UPLOAD = 10_485_760 // 10 MiB
const TIMEOUT_MS = 30_000
const MASK = 0b1010_0001
// legal placement is stricter than it looks:
1_000 ok
1_000.5 ok
_1000 an identifier, not a number
1000_ SyntaxError
1__000 SyntaxError
The mistake this prevents is real — a constant of 100000 read as ten thousand, in a timeout or a byte limit, is a bug that survives review because nobody counts digits. PHP has had the same syntax since 7.4, which makes it one of the few things that reads identically on both sides of a codebase. The restriction against a trailing or doubled separator is worth knowing before a linter tells you.