PHP strpos() Equivalent in JavaScript

JavaScript's String.prototype.indexOf() returns the same kind of index as PHP's strpos(), using -1 (not false) to signal "not found" — and includes() is the idiomatic choice for a plain yes/no check.

Requires review Works only under specific conditions — read the caveats before relying on it.

PHP source
strpos()
Closest JavaScript API
String.prototype.indexOf()
Idiomatic JavaScript
String.prototype.includes() (for a boolean check)

Main limitation: PHP's `strpos()` uses `false` as its "not found" sentinel, which collides with a valid match at index `0` under loose comparison; JavaScript's `indexOf()` uses `-1`, which never collides with a real index, making truthy checks slightly safer but still not recommended over an explicit comparison.

How to use each function

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

PHP: strpos()

strpos(string $haystack, string $needle, int $offset = 0): int|false

Finds the position of the first occurrence of a substring, searching from an optional starting offset. Returns false — not -1 — when the substring isn't found, so a match at position 0 must be checked with !== rather than a plain truthy check.

Returns: The zero-based integer offset of the first match, or false if not found.

PHP
strpos("hello world", "world"); // 6
strpos("hello world", "xyz"); // false

JavaScript: String.prototype.indexOf()

str.indexOf(searchValue, fromIndex = 0)

Returns the index of the first occurrence of searchValue, or -1 if not found — never a boolean sentinel, so a match at index 0 stays unambiguous compared with a plain truthy check. For a plain yes/no answer, use str.includes(searchValue) instead.

Returns: The zero-based index of the first match, or -1.

JavaScript
"hello world".indexOf("world"); // 6
"hello world".includes("xyz");  // false

Quick mapping

PHP strpos()
Closest JavaScript API String.prototype.indexOf()
Idiomatic JavaScript String.prototype.includes() (for a boolean check)

How it differs

  • PHP's strpos() uses false as its "not found" sentinel, which collides with a valid match at index 0 under loose comparison; JavaScript's indexOf() uses -1, which never collides with a real index, making truthy checks slightly safer but still not recommended over an explicit comparison.
  • For a pure boolean "does this string contain that substring" check, String.prototype.includes() is the idiomatic JavaScript equivalent — clearer than comparing indexOf() against -1.
  • Both PHP's strpos() and JavaScript's indexOf() search case-sensitively by default; PHP's stripos() is the case-insensitive sibling, matching JavaScript's pattern of lowercasing both sides manually (.toLowerCase().includes(...)) since there's no case-insensitive indexOf variant.

Examples

Finding a substring position

PHP
strpos("hello world", "world"); // 6
JavaScript
"hello world".indexOf("world"); // 6
Both return the zero-based index of the first match.

Idiomatic boolean check

PHP
strpos("hello", "x") !== false; // false (not found)
JavaScript
"hello".includes("x"); // false (not found)
`.includes()` avoids the sentinel-value comparison entirely and directly answers the yes/no question, matching the intent of PHP's strict `!== false` check.

Edge cases

Edge case

Never write if (str.indexOf(needle)) in JavaScript expecting it to mean "found" — a match at index 0 is falsy, exactly like PHP's 0 == false trap. Always compare against -1 explicitly, or use .includes().

References

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

Last verified 2026-07-29.