PHP Strings

La Lakshmi Priya Updated 29 Oct 2026
9 min read

What Is a String?

In simple terms: A string is a piece of text — a name, a sentence, an email address, an HTML snippet, or even an entire file's content.

Technically: In PHP, a string is an ordered sequence of bytes. PHP does not store an encoding with the string; it simply stores bytes. When text is saved as UTF-8 (the standard for the web), English letters take one byte each, while characters such as é, ₹, த, or emoji take two to four bytes.

Why Strings Matter

Almost everything a web application handles is text at some point:

  • Form input ($_POST), URL parameters ($_GET), and cookies always arrive as strings
  • HTML output sent to the browser
  • JSON sent to and received from APIs
  • SQL queries, file paths, email bodies, log messages

Understanding how strings are written, stored, and compared prevents a large class of bugs.


Creating Strings

PHP has four ways to write a string literal:

SyntaxNameVariables Interpolated?Escape Sequences?
'text'Single-quotedNoOnly \' and 0
"text"Double-quotedYesYes (\n, \t, \$, …)
<<<ID ... IDHeredocYesYes
<<<'ID' ... IDNowdocNoNo

This lesson focuses on single and double quotes. Heredoc and nowdoc are covered in Heredoc and Nowdoc, escape sequences in Escape Characters, and interpolation in String Interpolation.

Single-Quoted Strings

<?php
$language = 'PHP';

echo 'I am learning $language\n';

Output

I am learning $language\n

Single-quoted strings are literal. $language is not replaced, and \n is printed as a backslash followed by n. The only special sequences are \' (a single quote) and 0 (a backslash).

Double-Quoted Strings

<?php
$language = 'PHP';

echo "I am learning $language\n";

Output

I am learning PHP

Double-quoted strings replace variables with their values and interpret escape sequences such as \n (newline).

Which Quotes Should You Use?

  • Use single quotes for fixed text with no variables: array keys ($user['email']), SQL with placeholders, file paths, regular expression patterns. What you see is exactly what you get.
  • Use double quotes when you need variables or escape sequences inside the text.

The performance difference between the two is negligible in modern PHP. Choose based on clarity.

Quotes Inside Strings

<?php
echo 'It\'s a "great" day' . "\n";
echo "It's a \"great\" day" . "\n";
echo "It's a 'great' day" . "\n";

Output

It's a "great" day
It's a "great" day
It's a 'great' day

A quote of the same type as the delimiter must be escaped with a backslash. A quote of the other type needs no escaping. Choosing the right delimiter often avoids escaping altogether.


Multiline Strings

Strings can span several lines. The line breaks become part of the string.

<?php
$address = "Gocourse Learning Centre
12 Anna Salai
Chennai 600002";

echo $address;

Output

Gocourse Learning Centre
12 Anna Salai
Chennai 600002

In a browser, line breaks inside text are displayed as spaces. To show them as visible line breaks in HTML, use nl2br() (which inserts <br> tags) or wrap the text in a <pre> element.


String Length

strlen() Counts Bytes

<?php
echo strlen("Hello") . "\n";
echo strlen("Hello World") . "\n";
echo strlen("") . "\n";

Output

5
11
0

Spaces count as characters, and an empty string has length 0.

mb_strlen() Counts Characters

<?php
$price = "₹500";
$greeting = "Héllo";

echo strlen($price) . " bytes, " . mb_strlen($price) . " characters\n";
echo strlen($greeting) . " bytes, " . mb_strlen($greeting) . " characters\n";

Output

6 bytes, 4 characters
6 bytes, 5 characters

Why the Results Differ

In UTF-8, ₹ is stored as 3 bytes and é as 2 bytes. strlen() counts every byte; mb_strlen() decodes UTF-8 and counts actual characters.

FunctionCountsUse For
strlen()BytesBinary data, storage limits measured in bytes, ASCII-only identifiers
mb_strlen()CharactersAnything a human reads: names, messages, form validation ("max 50 characters")

For user-facing text, use the mb_* functions. They are covered in Multibyte Strings. Since PHP 8.0, the mbstring functions use UTF-8 by default unless configured otherwise.


Accessing Individual Characters

Strings can be accessed like arrays of bytes using square brackets and a zero-based position (offset).

Example

<?php
$word = "Developer";

echo $word[0] . "\n";    // first character
echo $word[4] . "\n";    // fifth character
echo $word[-1] . "\n";   // last character
echo $word[-3] . "\n";   // third from the end

Output

D
l
r
p

How It Works

  • Offsets start at 0, so $word[0] is D and $word[4] is l (D-e-v-e-l).
  • Negative offsets (PHP 7.1+) count from the end: -1 is the last character.

Reading Beyond the End

<?php
$code = "ABC";
echo $code[10];

This raises a warning ("Uninitialized string offset") and returns an empty string. Check the length first, or use substr(), which handles out-of-range positions without warnings.

Modifying Individual Characters

<?php
$status = "cat";
$status[0] = "b";

echo $status;

Output

bat

PHP strings are mutable at the byte level: you can replace a single byte by assigning to its offset. If you assign beyond the end, PHP pads the gap with spaces.

Warning: Offsets work on bytes, not characters. "₹500"[0] returns only the first of the three bytes of ₹, which is not a valid character on its own. For multibyte text, use mb_substr($text, 0, 1).

Version note: The old syntax $word{0} was removed in PHP 8.0. Always use square brackets.


Strings Are Copied, Functions Return New Strings

String functions do not change the original variable. They return a new string.

<?php
$name = "  priya  ";

trim($name);
echo "[$name]\n";

$name = trim($name);
echo "[$name]\n";

Output

[  priya  ]
[priya]

The first trim() call returns a trimmed string, but the result is discarded because it is not assigned. To keep the change, assign the result back to a variable. This applies to almost all string functions: strtoupper(), str_replace(), substr(), and so on.


Comparing Strings

Equality

<?php
var_dump("apple" === "apple");   // bool(true)
var_dump("Apple" === "apple");   // bool(false) — case-sensitive
var_dump(strcasecmp("Apple", "apple") === 0); // bool(true) — case-insensitive

=== compares strings byte by byte, so uppercase and lowercase letters are different. strcasecmp() compares without case sensitivity and returns 0 when the strings are equal.

Numeric Strings and Loose Comparison

When both sides of == are numeric strings, PHP compares them as numbers:

<?php
var_dump("10" == "1e1");    // bool(true)  — both are the number 10
var_dump("100" == "1e2");   // bool(true)
var_dump("007" == "7");     // bool(true)
var_dump("007" === "7");    // bool(false)

This can cause real bugs — for example, comparing tokens, codes, or hashes that happen to look numeric. Always compare strings with ===.

PHP 8 Change: Comparing Strings With Numbers

<?php
var_dump(0 == "abc");   // bool(false) in PHP 8; bool(true) in PHP 7
var_dump(0 == "");      // bool(false) in PHP 8; bool(true) in PHP 7
var_dump(42 == "42");   // bool(true) in both

In PHP 7, a non-numeric string was converted to a number (0) before comparison, so 0 == "abc" was true. Since PHP 8.0, when a number is compared with a non-numeric string, the number is converted to a string instead, and the comparison is false. This change removed a long-standing source of security bugs.

Ordering Strings

<?php
var_dump(strcmp("apple", "banana"));  // negative: "apple" comes first
var_dump("apple" < "banana");         // bool(true)

$files = ["img12.png", "img10.png", "img2.png"];
sort($files);
print_r($files);

natsort($files);
print_r(array_values($files));

Output

int(-1)
bool(true)
Array
(
    [0] => img10.png
    [1] => img12.png
    [2] => img2.png
)
Array
(
    [0] => img2.png
    [1] => img10.png
    [2] => img12.png
)
  • strcmp() returns a negative number, 0, or a positive number depending on order. Since PHP 8.2, it returns exactly -1, 0, or 1.
  • Standard sorting compares character by character, so "img10" comes before "img2" (because 1 < 2).
  • natsort() uses natural order, which treats numbers inside strings as numbers — the order a human expects.

Converting Between Strings and Numbers

Strings to Numbers

<?php
var_dump((int) "42");        // int(42)
var_dump((float) "3.75");    // float(3.75)
var_dump((int) "12 apples"); // int(12) — leading number is used
var_dump((int) "apples 12"); // int(0)  — no leading number
var_dump("5" + "10");        // int(15)

A string that starts with a number followed by other text ("12 apples") is called a leading-numeric string; casting it with (int) silently uses the leading number. Using such a string directly in arithmetic ("12 apples" + 1) also uses the leading number but raises the warning "A non-numeric value encountered". A completely non-numeric string in arithmetic ("apples" + 1) throws a TypeError in PHP 8. Conversion rules are covered in PHP Casting and PHP Type Juggling.

Validating Numeric Strings

<?php
var_dump(is_numeric("42"));     // bool(true)
var_dump(is_numeric("4.2e1"));  // bool(true)
var_dump(is_numeric(" 42"));    // bool(true)  — leading whitespace allowed
var_dump(is_numeric("42 "));    // bool(true)  — trailing whitespace allowed since PHP 8.0
var_dump(is_numeric("42abc"));  // bool(false)

Numbers to Strings

<?php
$quantity = 3;
$text = "Items: " . $quantity;       // automatic conversion
$formatted = number_format(1234567.891, 2);

var_dump($text, $formatted);

Output

string(8) "Items: 3"
string(12) "1,234,567.89"

Practical Example: Validating and Normalizing a Username

<?php
function normalizeUsername(string $input): ?string
{
    $username = strtolower(trim($input));
    $length = mb_strlen($username);

    if ($length < 3 || $length > 20) {
        return null;
    }

    if (!ctype_alnum(str_replace('_', '', $username))) {
        return null;
    }

    return $username;
}

$inputs = ["  Kavin_R  ", "ab", "hello world", "Dev_2026"];

foreach ($inputs as $input) {
    $result = normalizeUsername($input);
    printf("%-16s => %s\n", "'$input'", $result ?? 'invalid');
}

Output

'  Kavin_R  '    => kavin_r
'ab'             => invalid
'hello world'    => invalid
'Dev_2026'       => dev_2026

Step-by-Step Explanation

  1. trim() removes surrounding spaces, which users often type accidentally.
  2. strtolower() normalizes case so that Kavin_R and kavin_r cannot be registered as two different users.
  3. mb_strlen() counts characters for the length rule.
  4. str_replace('_', '', $username) temporarily removes underscores, then ctype_alnum() checks that every remaining character is a letter or digit. This rejects spaces and symbols while allowing underscores.
  5. The function returns the cleaned username, or null when the input is invalid.

This pattern — trim, normalize, validate, then use — applies to emails, phone numbers, coupon codes, and most other text input.


Common Mistakes

Expecting Variables to Work in Single Quotes

Effect: 'Hello $name' prints $name literally.

Fix: Use double quotes or concatenation.

Using strlen() for User-Facing Length Limits

Effect: A 10-character name in Tamil or with accents may be rejected as "too long".

Fix: Use mb_strlen().

Forgetting to Assign Function Results

Effect: trim($name); has no effect on $name.

Fix: $name = trim($name);

Comparing Strings With ==

Effect: "1e3" == "1000" is true.

Fix: Use === for string comparisons.

Accessing Multibyte Characters by Offset

Effect: Broken characters (often displayed as �).

Fix: Use mb_substr() and other mb_* functions.

Using $str{0}

Effect: Parse error in PHP 8.

Fix: Use $str[0].


Best Practices

  • Use single quotes for literal text and double quotes when interpolating.
  • Store and output all text as UTF-8, and declare <meta charset="UTF-8"> in HTML.
  • Use mb_* functions for anything a human reads.
  • Compare strings with ===; use strcasecmp() for case-insensitive comparison.
  • Remember that string functions return new strings — assign the result.
  • Trim and normalize user input before validating or storing it.

Official reference: https://www.php.net/manual/en/language.types.string.php

0 Comments

Reviewed before they appear

No comments yet.

Data Mining
Introduction to Data Mining Data Mining Implementation Process Data Mining Architecture Data Mining Techniques KDD: Knowledge Discovery in Databases History of Data Mining Data Mining Tools Data Mining vs Machine Learning Facebook Data Mining Social Media Data Mining Methods Clustering in Data Mining Text Data Mining Bagging vs Boosting Data Mining vs Data Warehousing Social Media Data Mining Data Mining: Bayesian Classifiers Data Mining: World Wide Web Different Types of Clustering Bitcoin Mining and Blockchain Data Mining Orange Data Mining Data Mining vs Big Data Decision Tree Induction Educational Data Mining Data Mining in Healthcare Apriori Algorithm Data Integration in Data Mining Difference Between Data Mining and Text Mining Discretization in Data Mining Redundancy and Correlation in Data Mining Classification of Data Mining Systems Classification Algorithms in Data Mining Data Generalization in Data Mining Classification and Prediction in Data Mining Regression in Data Mining What Is an Outlier in Data Mining Data Cleaning in Data Mining Data Processing in Data Mining Data Mining Task Primitives Web Content Mining, Web Structure Mining, and Web Usage Mini Binning in Data Mining KDD vs. Data Mining Noise in Data Mining BIRCH in Data Mining Stemming in Data Mining Feature Transformation in Data Mining Visual and Audio Data Mining Class Comparison Methods in Data Mining Data Selection in Data Mining Tasks and Functionalities of Data Mining Ubiquitous and Invisible Data Mining Importance of Data Mining Data Quality in Data Mining Mining Frequent Patterns in Data Mining Data Warehouse and OLAP Technology for Data Mining Need for Data Mining Pattern Evaluation Methods in Data Mining Logarithms and Exponents in Complexity Analysis Time Series Clustering What is the C4.5 Algorithm and How Does It Work? Expanding Contractions in Text Mining Cosine Similarity in Data Mining Lazy Learning in Data Mining Neural Networks in Data Mining Building a Text Normalizer Shallow Parsing Data Pipeline Orchestration Big Data vs Small Data Myths of Data Mining Data Reduction in Data Mining Data Mining Models Difference Between Data Mining and Data Science Difference Between Data Mining and Statistics Difference Between Data Mining and Web Mining Difference Between Data Mining and Data Analysis Difference Between Business Intelligence and Data Mining Difference Between Data Mining and Data Visualization Data Mining vs Data Analytics Types of Data Mining Difference Between Data Profiling and Data Mining Predictive Analytics vs Data Mining Difference Between Data Mining and OLAP Descriptive and Predictive Data Mining Difference Between Spatial and Temporal Data Mining Difference Between Classification and Clustering in Data Min Hierarchical Clustering in Data Mining Density-Based Clustering in Data Mining What Is Aggregation in Data Mining?
Ask about this post
AI Ask about this post

Ask questions about PHP Strings and get answers drawn from it.

Signed-in readers only.