PHP substr() Equivalent in JavaScript

JavaScript's String.prototype.slice() is the modern equivalent of PHP's substr() — note that JavaScript also has its own substr(), but it's deprecated and should be avoided in new code.

Close equivalent Covers the common case, but has documented behavioral differences.

PHP source
substr()
Closest JavaScript API
String.prototype.slice()

Main limitation: PHP's `substr($str, $start, $length)` third argument is a *length*; JavaScript's `.slice(start, end)` second argument is an *end index* — `substr($s, 2, 3)` becomes `s.slice(2, 5)`, not `s.slice(2, 3)`.

How to use each function

Before comparing the two, here's how substr() and String.prototype.slice() work on their own.

PHP: substr()

substr(string $string, int $offset, ?int $length = null): string

Extracts a portion of a string starting at $offset (negative counts from the end) and continuing for $length characters (negative trims that many characters off the end instead). Never raises an error for out-of-range offsets — it returns an empty or truncated string instead.

Returns: The extracted substring.

PHP
substr("hello world", 6, 5); // "world"
substr("hello world", -5); // "world"

JavaScript: String.prototype.slice()

str.slice(start, end)

Extracts a substring from start up to, but not including, end — an end position, not a length like PHP's substr() third argument. Negative indices count from the end of the string. JavaScript also has a same-named .substr(start, length), but it's deprecated — prefer .slice().

Returns: The extracted substring.

JavaScript
"hello world".slice(6, 11); // "world"
"hello world".slice(-5);    // "world"

Quick mapping

PHP substr()
Closest JavaScript API String.prototype.slice()

How it differs

  • PHP's substr($str, $start, $length) third argument is a *length*; JavaScript's .slice(start, end) second argument is an *end index* — substr($s, 2, 3) becomes s.slice(2, 5), not s.slice(2, 3).
  • JavaScript also ships a same-named String.prototype.substr(start, length) that *does* take a length like PHP, but it's marked deprecated (legacy) in the spec — prefer .slice() for new code even though .substr() looks like a more direct name match.
  • Both substr() and .slice() support negative start indices to count from the end of the string, with matching semantics.

Examples

Basic substring by length

PHP
substr("hello world", 6, 5);
// "world"
JavaScript
"hello world".slice(6, 11);
// "world"
PHP's length (5) becomes JavaScript's end index (6 + 5 = 11).

Negative start (from the end)

PHP
substr("hello world", -5);
// "world"
JavaScript
"hello world".slice(-5);
// "world"
Negative start indices behave identically in both languages.

Edge cases

Edge case

Don't reach for JavaScript's .substr() just because the name matches PHP's substr() — it's deprecated; use .slice() and adjust the second argument from a length to an end index.

Edge case

.slice() with a negative end argument means "stop that many characters from the end" — e.g. "hello".slice(1, -1) is "ell" — this has no direct PHP substr() parallel using a single call, since PHP's negative length works differently (counts back from the end for where to *stop*, similar in effect but derived differently).

References

  • PHP Manual — substr — checked 2026-07-29
  • MDN Web Docs — String.prototype.slice() — checked 2026-07-29

Last verified 2026-07-29.