Types7 min readExamples run on PHP 8.5.10

is_string()

Learn how PHP 8.4 is_string() tests whether a value has the string type, with examples, edge cases such as numeric strings and objects, and common mistakes.

Signature

is_string(mixed $value): bool

Purpose

is_string() answers one narrow question: is the type of this value exactly string? It looks only at the type, never at what the characters mean. The text '23' is a string, and so is an empty string or a single space. Integers, floats, booleans, null, arrays and objects are not.

This makes it a good guard at the edge of your code, where input may arrive as a mix of types, such as decoded JSON, configuration arrays or loosely typed function arguments.

Signature

The function is available in PHP 4 and later, including PHP 8.4.

Parameters and defaults

  • $value: any value you want to inspect. It accepts mixed, so no type is rejected, and there are no optional parameters or default values.

Return value and failure cases

The function returns true when the value is of type string and false for everything else. It never throws a TypeError because of the argument you pass, and it does not convert the value first. Because the parameter is mixed, declare(strict_types=1) does not change the result.

One practical note: if you pass a variable that was never defined, PHP raises its usual undefined-variable warning and the function receives null, so the result is false. The warning comes from the variable access, not from is_string().

Example 1: Which values are strings?

The loop below checks a mix of text, numbers and empty-ish values. Only the values written in quotes are strings, even when they look numeric or falsy.

Example
<?php
$values = ['abc', '23', 23, 23.5, '', '0', null, false];
$results = [];
foreach ($values as $value) {
    $results[] = is_string($value);
}
echo json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[true,true,false,false,true,true,false,false]

The empty string and '0' are both strings, even though they are falsy in a boolean context.

Example 2: Guarding a string operation

A function that works on text can check its input first and return a safe fallback otherwise.

Example
<?php
function shout(mixed $value): string
{
    if (!is_string($value)) {
        return 'not a string';
    }
    return strtoupper(trim($value)) . '!';
}

echo json_encode([shout('  hello '), shout(42), shout(null)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["HELLO!","not a string","not a string"]

The guard keeps 42 and null away from trim(), so the function handles them predictably.

Example 3: Filtering and objects

Because is_string() takes one argument and returns a boolean, you can pass its name to array_filter(). The example also shows that an object with __toString() is still an object until you cast it.

Example
<?php
class Label
{
    public function __toString(): string
    {
        return 'label';
    }
}

$items = ['a', new Label(), ['x'], 12, '12', 'b'];
$strings = array_values(array_filter($items, 'is_string'));
echo json_encode($strings, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode([is_string(new Label()), is_string((string) new Label()), is_string(['x'])], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["a","12","b"]
[false,true,false]

Edge cases

  • Numeric strings such as '23' and '23.5' return true. Use is_numeric() if you need to know whether text looks like a number.
  • Empty and whitespace strings return true. A string check says nothing about whether there is useful content.
  • Stringable objects return false. Casting with (string) produces a real string, after which the check passes.
  • Callable strings such as 'strlen' are strings, so is_string() returns true even though they can also be called as functions.
  • Encoding is not examined. A string holding bytes that are invalid in UTF-8 is still a string.

Common mistakes

  1. Treating it as a content validator. is_string($input) does not prove the input is non-empty, trimmed, numeric, or safe for output or SQL.
  2. Expecting numbers to be converted. is_string(23) is false. If integers are acceptable input, cast or check them separately.
  3. Forgetting objects. A class that implements __toString() is not accepted. Check for Stringable explicitly if you want to allow such objects.
  4. Using truthiness instead. Code like if ($value) treats '0' and '' as false, but both are strings. Use is_string() when the question is about type.
  5. Confusing it with a type declaration. A string parameter type may coerce values in non-strict mode, while is_string() only reports the current type.
  • is_int() checks for an integer.
  • is_float() checks for a float.
  • is_bool() checks for a boolean.
  • is_array() checks for an array.
  • is_object() checks for an object.
  • is_numeric() checks whether a value is a number or a numeric string.

Recap

is_string() accepts any value and returns true only when that value already has the string type. It does not convert, validate or throw for the argument. Remember that numeric text, empty text and '0' are strings, while numbers, null, arrays and Stringable objects are not. Combine it with content checks when you need more than the type.

Tested examples

Which values are strings?
<?php
$values = ['abc', '23', 23, 23.5, '', '0', null, false];
$results = [];
foreach ($values as $value) {
    $results[] = is_string($value);
}
echo json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[true,true,false,false,true,true,false,false]
Guarding a string operation
<?php
function shout(mixed $value): string
{
    if (!is_string($value)) {
        return 'not a string';
    }
    return strtoupper(trim($value)) . '!';
}

echo json_encode([shout('  hello '), shout(42), shout(null)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["HELLO!","not a string","not a string"]
Filtering and objects
<?php
class Label
{
    public function __toString(): string
    {
        return 'label';
    }
}

$items = ['a', new Label(), ['x'], 12, '12', 'b'];
$strings = array_values(array_filter($items, 'is_string'));
echo json_encode($strings, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode([is_string(new Label()), is_string((string) new Label()), is_string(['x'])], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["a","12","b"]
[false,true,false]