Concatenate Strings
What Is Concatenation? In simple terms: Concatenation means joining strings together end to end to form one longer string — for example, joining a first name and a last name into a full name. Technica
What Is Concatenation?
In simple terms: Concatenation means joining strings together end to end to form one longer string — for example, joining a first name and a last name into a full name.
Technically: PHP's concatenation operator is the dot (.). It converts both operands to strings (if they are not already) and returns a new string consisting of the left operand followed by the right operand. The concatenating assignment operator (.=) appends to an existing variable.
Why Concatenation Is Needed
Most output is assembled from parts: fixed text, variables, function results, and HTML. Concatenation is the most direct way to build:
- Messages:
"Welcome back, " . $name - File paths:
$uploadDir . '/' . $filename - URLs:
$baseUrl . '/products/' . $id - HTML fragments, CSV lines, log entries, and email bodies
Note: PHP uses
.for joining strings and+for adding numbers. Unlike JavaScript,+never joins strings in PHP:"5" + "5"is10, not"55".
The Concatenation Operator .
Syntax
$result = $string1 . $string2;
Example
<?php
$firstName = "Karthik";
$lastName = "Raja";
$fullName = $firstName . " " . $lastName;
echo $fullName;
Output
Karthik Raja
How It Works
$firstName . " "produces"Karthik ".- That result
. $lastNameproduces"Karthik Raja". - The final string is assigned to
$fullName.
Concatenation adds nothing between the parts. Spaces, commas, and line breaks must be added explicitly — forgetting the " " would produce "KarthikRaja".
Combining Strings With Other Types
The . operator converts non-string values to strings automatically:
<?php
$item = "Pen";
$quantity = 12;
$price = 19.90;
$inStock = true;
$discount = null;
echo $item . " x " . $quantity . "\n";
echo "Price: " . $price . "\n";
echo "In stock: " . $inStock . "\n";
echo "Discount: [" . $discount . "]\n";
Output
Pen x 12
Price: 19.9
In stock: 1
Discount: []
| Value | Converted To |
|---|---|
Integer 12 | "12" |
Float 19.90 | "19.9" — trailing zeros are dropped |
true | "1" |
false and null | "" (empty string) |
| Array | "Array" with a warning |
| Object | Error, unless the class has a __toString() method |
For prices, format the number explicitly: "Price: " . number_format($price, 2) produces Price: 19.90.
The Concatenating Assignment Operator .=
What It Does
$a .= $b appends $b to the end of $a. It is shorthand for $a = $a . $b.
Example
<?php
$message = "Order received.";
$message .= " Payment confirmed.";
$message .= " Shipping in 2 days.";
echo $message;
Output
Order received. Payment confirmed. Shipping in 2 days.
Building Output in a Loop
.= is commonly used to build a string piece by piece:
<?php
$fruits = ["Mango", "Banana", "Guava"];
$html = "<ul>\n";
foreach ($fruits as $fruit) {
$html .= " <li>" . htmlspecialchars($fruit) . "</li>\n";
}
$html .= "</ul>";
echo $html;
Output
<ul>
<li>Mango</li>
<li>Banana</li>
<li>Guava</li>
</ul>
Why Initialize the Variable First
$html = "<ul>\n"; creates the variable before the loop. If you use .= on a variable that does not exist yet, PHP raises an "Undefined variable" warning and treats it as an empty string. Always initialize the variable — with "" if there is no starting text.
Building a string and outputting it once is useful when the result must be returned from a function, stored, or sent by email rather than printed immediately.
Concatenation vs Interpolation
PHP offers two ways to put variables into text:
<?php
$name = "Revathi";
$points = 1200;
echo "Hello, " . $name . "! You have " . $points . " points.\n"; // concatenation
echo "Hello, $name! You have $points points.\n"; // interpolation
Output
Hello, Revathi! You have 1200 points.
Hello, Revathi! You have 1200 points.
When to Use Each
| Situation | Better Choice | Reason |
|---|---|---|
| Simple variables inside a sentence | Interpolation | Fewer quotes and dots, reads like the final text |
| Function calls or expressions | Concatenation | Interpolation cannot call functions: "Total: number_format($x)" does not work |
| Single-quoted strings | Concatenation | Single quotes do not interpolate |
| Array elements with string keys or object methods | Either — interpolation needs {} | "Name: {$user['name']}" |
| Many values with formatting | sprintf() | Separates the template from the values |
Example: Expressions Require Concatenation
<?php
$price = 1499.5;
$name = "keyboard";
echo "Item: " . ucfirst($name) . " – ₹" . number_format($price, 2) . "\n";
Output
Item: Keyboard – ₹1,499.50
ucfirst() and number_format() are function calls, so their results must be joined with .. Interpolation is covered in String Interpolation.
Operator Precedence: Concatenation and Arithmetic
When . and arithmetic operators appear in the same expression, precedence decides which runs first.
Example
<?php
$price = 500;
$tax = 90;
echo "Total: " . $price + $tax . "\n";
Output (PHP 8.0 and newer)
Total: 590
Why
Since PHP 8.0, the arithmetic operators + and - have higher precedence than .. PHP calculates $price + $tax first (590) and then concatenates.
In PHP 7, ., +, and - had equal precedence and were evaluated left to right: "Total: " . 500 became "Total: 500", and adding 90 to that non-numeric string produced a warning and a wrong result. PHP 7.4 already warned about this ambiguity before PHP 8 changed it.
* and / have always had higher precedence than ., so "Area: " . $w * $h works in all versions.
Best Practice: Use Parentheses
<?php
echo "Total: " . ($price + $tax) . "\n";
Parentheses make the intended order obvious to every reader, work identically in all PHP versions, and cost nothing.
Concatenating Numbers Directly
Numeric literals next to the dot operator need spaces:
<?php
echo 1 . 2;
echo "\n";
echo 1.2;
echo "\n";
Output
12
1.2
1 . 2(with spaces) concatenates the integers1and2into the string"12".1.2(without spaces) is parsed as the float one point two.
With variables ($a . $b), spacing does not change the meaning, but using spaces around . consistently makes code easier to read and follows standard coding style.
Joining Many Values: implode()
When the values to join are in an array, implode() is clearer than a loop with .=:
<?php
$tags = ["php", "backend", "tutorial"];
// With a loop
$result = "";
foreach ($tags as $index => $tag) {
if ($index > 0) {
$result .= ", ";
}
$result .= $tag;
}
echo $result . "\n";
// With implode()
echo implode(", ", $tags) . "\n";
Output
php, backend, tutorial
php, backend, tutorial
The loop needs extra logic to avoid a leading or trailing separator. implode() places separators only between elements, so the result is correct automatically.
Collect, Then Join
A common pattern is to collect parts in an array and join them at the end:
<?php
$user = ['street' => '12 Gandhi Road', 'area' => '', 'city' => 'Salem', 'pin' => '636001'];
$parts = array_filter([$user['street'], $user['area'], $user['city'], $user['pin']]);
echo implode(", ", $parts);
Output
12 Gandhi Road, Salem, 636001
array_filter() removes the empty area, so the address contains no empty segment like ", ,". Building this with .= would require a condition for every field.
Concatenation With sprintf()
When a string has many parts and formatting rules, sprintf() keeps the template readable:
<?php
$orderId = 42;
$customer = "Lavanya";
$amount = 2450;
echo "Order #" . str_pad($orderId, 6, "0", STR_PAD_LEFT) . " for " . $customer . ": ₹" . number_format($amount, 2) . "\n";
echo sprintf("Order #%06d for %s: ₹%s\n", $orderId, $customer, number_format($amount, 2));
Output
Order #000042 for Lavanya: ₹2,450.00
Order #000042 for Lavanya: ₹2,450.00
Both lines produce the same result. In the sprintf() version, the shape of the message is visible at a glance. See PHP printf / sprintf.
Performance
PHP is efficient at concatenation. Appending with .= in a loop is fast because PHP can often extend the existing string in place instead of copying it each time. For typical web pages — even thousands of appends — concatenation is not a performance concern.
Choose between ., .=, interpolation, implode(), and sprintf() based on readability. Optimize only if profiling shows string building is a real bottleneck, which is rare.
Where Concatenation Is Dangerous
Concatenation joins text without understanding its meaning. When the text becomes code in another language — SQL, HTML, shell commands, URLs — concatenating untrusted input creates injection vulnerabilities.
SQL: Never Concatenate User Input
<?php
// DANGEROUS
$email = $_GET['email'];
$sql = "SELECT * FROM users WHERE email = '" . $email . "'";
If a visitor enters ' OR '1'='1, the query becomes:
SELECT * FROM users WHERE email = '' OR '1'='1'
which returns every user. This is SQL injection.
Safe approach — prepared statements:
<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
The query structure and the data are sent separately, so input can never change the query. See SQL Injection Prevention and PDO Prepared Statements.
Other Contexts
| Building | Risk | Safe Approach |
|---|---|---|
| HTML | Cross-site scripting (XSS) | htmlspecialchars() on each value |
| URL query strings | Broken or manipulated parameters | http_build_query() or rawurlencode() |
| Shell commands | Command injection | escapeshellarg(), or avoid the shell |
| File paths | Path traversal (../../etc/passwd) | Validate input; use basename() for file names |
| JSON | Invalid JSON, injection | json_encode() on the whole structure |
Example: Building a URL Safely
<?php
$baseUrl = "https://example.com/search";
$params = ['q' => 'php & mysql', 'page' => 2];
echo $baseUrl . "?" . http_build_query($params);
Output
https://example.com/search?q=php+%26+mysql&page=2
http_build_query() encodes the & and spaces in the search term, so it cannot be mistaken for a parameter separator. Manual concatenation ("?q=" . $q) would break the URL.
Practical Example: Generating a CSV Line and a Log Entry
<?php
function logLine(string $level, string $message): string
{
return "[" . date('Y-m-d H:i:s') . "] " . strtoupper($level) . ": " . $message . PHP_EOL;
}
$order = ['id' => 1042, 'customer' => 'Nila, Arun', 'total' => 3299.0];
$stream = fopen('php://memory', 'r+');
fputcsv($stream, [$order['id'], $order['customer'], number_format($order['total'], 2, '.', '')], escape: '');
rewind($stream);
$csvLine = stream_get_contents($stream);
echo $csvLine;
echo logLine('info', 'Exported order ' . $order['id']);
Output (the timestamp will vary)
1042,"Nila, Arun",3299.00
[2026-10-08 14:30:12] INFO: Exported order 1042
Step-by-Step Explanation
logLine()builds a log entry by concatenating a timestamp, the level, and the message.PHP_EOLadds the correct line ending for the operating system.- For the CSV line, the customer name contains a comma. Concatenating fields with
implode(",", ...)would produce1042,Nila, Arun,3299.00— four columns instead of three. fputcsv()handles CSV rules automatically, wrappingNila, Arunin quotes. It writes to a stream, so the example uses an in-memory stream (php://memory) and reads the line back withstream_get_contents().number_format($total, 2, '.', '')formats the number with two decimals and no thousands separator, which keeps it machine-readable.escape: ''is a named argument that disables PHP's legacy backslash-escape behavior in CSV output; passing it explicitly is recommended because PHP 8.4 deprecates relying on the default value.
The lesson: concatenation is perfect for human-readable text, but structured formats such as CSV, JSON, SQL, and URLs should be built with functions that understand their rules.
Common Mistakes
Using + to Join Strings
<?php
echo "Hello " + "World";
Effect: TypeError: Unsupported operand types: string + string in PHP 8 (non-numeric strings cannot be added).
Fix: Use ..
Forgetting Spaces Between Parts
Effect: "Hello" . $name produces HelloRavi.
Fix: Include spaces in the string parts: "Hello " . $name.
Mixing Arithmetic and Concatenation Without Parentheses
Effect: Different results in PHP 7 and PHP 8; confusing code.
Fix: Wrap calculations in parentheses.
Using .= on an Undefined Variable
Effect: "Undefined variable" warning.
Fix: Initialize with $output = ""; before the loop.
Concatenating Arrays
Effect: The text Array and a warning.
Fix: Use implode() or json_encode().
Building SQL, HTML, or URLs From Raw Input
Effect: Injection vulnerabilities and broken output.
Fix: Use prepared statements, htmlspecialchars(), http_build_query(), and similar context-aware functions.
Best Practices
- Use
.to join strings and.=to append; surround.with spaces for readability. - Prefer interpolation for simple sentences and concatenation for function calls and expressions.
- Use parentheses whenever arithmetic appears in a concatenation.
- Use
implode()to join arrays andsprintf()for formatted templates. - Initialize variables before appending to them.
- Never build SQL, shell commands, or HTML from untrusted input by concatenation alone.
Official reference: https://www.php.net/manual/en/language.operators.string.php