data types and standard library

Strings

Strings are text values. PHP applications use strings for names, emails, slugs, URLs, search terms, template output, log messages, JSON fields, file paths, and database values.

Good string handling is about boundaries: clean input when it enters, keep internal values predictable, and escape output for the place it is going.

Quoting and interpolation

Single-quoted strings are literal apart from escaped backslashes and quotes. Double-quoted strings interpolate variables.

PHP example
<?php

declare(strict_types=1);

$name = 'Sam';

echo 'Hello $name' . PHP_EOL;
echo "Hello {$name}" . PHP_EOL;

// Prints:
// Hello $name
// Hello Sam

Use whichever style makes the string clearer. For complex output, concatenation or sprintf() can be easier to read.

Trimming input

Input often contains accidental spaces. Trim at the boundary before validation or storage.

PHP example
<?php

declare(strict_types=1);

$name = trim('  Nia Stone  ');

printf("Hello %s, your initial is %s\n", $name, $initial);

That snippet has a bug: $initial has not been set. Build values in clear steps.

PHP example
<?php

declare(strict_types=1);

$name = trim('  Nia Stone  ');
$initial = substr($name, 0, 1);

printf("Hello %s, your initial is %s\n", $name, $initial);

// Prints:
// Hello Nia Stone, your initial is N

For plain ASCII names this works. For multibyte text, use mb_substr() when the mbstring extension is available.

Searching strings

Use str_contains(), str_starts_with(), and str_ends_with() for common checks.

PHP example
<?php

declare(strict_types=1);

$email = 'sam@example.com';

var_dump(str_contains($email, '@'));
var_dump(str_ends_with($email, '.com'));

// Prints:
// bool(true)
// bool(true)

These functions make intent clearer than older strpos() checks.

Replacing text

Use str_replace() for simple literal replacement.

PHP example
<?php

declare(strict_types=1);

$title = 'PHP strings basics';
$slug = strtolower(str_replace(' ', '-', trim($title)));

echo $slug;

// Prints:
// php-strings-basics

This is fine for simple ASCII examples. Production slugging often needs more rules for punctuation, repeated separators, and Unicode.

Length and multibyte text

strlen() counts bytes, not human characters.

PHP example
<?php

declare(strict_types=1);

echo strlen('Sam');

// Prints:
// 3

For multibyte strings, use mb_strlen() if the extension is available and the application needs character-aware behaviour.

PHP example
<?php

declare(strict_types=1);

if (function_exists('mb_strlen')) {
    echo mb_strlen('Sam', 'UTF-8');
}

// Prints:
// 3

Track 03 has a separate Unicode and multibyte lesson. For now, remember that byte length and character length are not always the same thing.

Empty strings

Do not treat every falsy value as the same thing. For required text input, trim first and compare to an empty string.

PHP example
<?php

declare(strict_types=1);

function requireName(string $name): string
{
    $name = trim($name);

    if ($name === '') {
        throw new InvalidArgumentException('Name is required.');
    }

    return $name;
}

echo requireName('  Sam  ');

// Prints:
// Sam

This avoids accepting spaces as a real name.

Escape output for HTML

Cleaning a string is not the same as making it safe for HTML. Escape at the output boundary.

PHP example
<?php

declare(strict_types=1);

$name = '<Sam>';

echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

// Prints:
// &lt;Sam&gt;

Use escaping for the target context: HTML, JSON, SQL, shell, URLs, and logs have different rules.

What to remember

Trim input, validate required strings after trimming, use clear search and replacement functions, know when byte length is not character length, and escape strings for the output context.

Before moving on, make sure you can build a safe display name from messy input without confusing trimming, validation, and HTML escaping.

Practice

Task: Prepare a safe display name

Create a safe display name helper for HTML output.

Requirements

  • Use strict types.
  • Trim the input.
  • Reject an empty name after trimming.
  • Return the cleaned name from one function.
  • Escape the cleaned name for HTML output at the output boundary.
  • Include one normal case and one empty-name case.
Show solution
PHP example
<?php

declare(strict_types=1);

function cleanDisplayName(string $name): string
{
    $name = trim($name);

    if ($name === '') {
        throw new InvalidArgumentException('Name is required.');
    }

    return $name;
}

function escapeHtml(string $value): string
{
    return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

$name = cleanDisplayName('  <Nia>  ');

echo 'Hello ' . escapeHtml($name) . PHP_EOL;

try {
    cleanDisplayName('   ');
} catch (InvalidArgumentException $exception) {
    echo $exception->getMessage() . PHP_EOL;
}

// Prints:
// Hello &lt;Nia&gt;
// Name is required.

The helper cleans and validates the string. Escaping is kept at the HTML output boundary.