Symmetric Dual-Column Row Number Pattern in PHP

What You’ll Learn
How to print a symmetric row-number pattern in PHP: each line shows i twice with a widening gap of spaces between them.
You’ll use two inner loops that walk different column ranges and print a digit only when the column index matches the current row.
⭐ Pattern Output
For 5 rows, the pattern looks like this:
1
2 2
3 3
4 4
5 5Complete PHP Program
Scan columns from n down to 1, then from 2 up to n; print the column index when it equals the row index, otherwise print a space.
<?php
for ($i = 1; $i <= 5; $i++) {
for ($j = 5; $j >= 1; $j--) {
if ($i == $j) {
echo $j;
} else {
echo " ";
}
}
for ($k = 2; $k <= 5; $k++) {
if ($i == $k) {
echo $k;
} else {
echo " ";
}
}
echo PHP_EOL;
}🧠 How It Works
Outer loop is the row
for ($i = 1; $i <= 5; $i++) sets which row number must appear on that line.
Left half: columns high to low
$j runs 5..1. When $i == $j, print $j; else print a space.
Right half: columns low to high
$k runs 2..5 with the same rule so the second occurrence of $i lines up on the right.
New line each row
echo PHP_EOL; moves to the next row after both inner loops finish.
Growing gap between digits
As $i grows, more column positions fall between the two matches, so the space run widens. Work per row is O(n), overall O(n²).
Variation — User Input (CLI) Version
This version accepts row count from user input (run from terminal with php):
<?php
echo "Enter number of rows: ";
$n = (int) trim(fgets(STDIN));
if ($n < 1) {
echo "Rows must be at least 1" . PHP_EOL;
exit;
}
for ($i = 1; $i <= $n; $i++) {
for ($j = $n; $j >= 1; $j--) {
if ($i == $j) {
echo $j;
} else {
echo " ";
}
}
for ($k = 2; $k <= $n; $k++) {
if ($i == $k) {
echo $k;
} else {
echo " ";
}
}
echo PHP_EOL;
}💡 Tips for Enhancement
Try These
- Use
str_repeat(" ", ...)orstr_pad()for wider, even spacing - Print stars instead of spaces for a hollow bridge between digits
- Mirror with three blocks for a wider diamond-style layout
- Parameterize the right loop start (e.g. skip more middle columns)
- Collect each row in a string for unit tests
Avoid
- Starting the second loop at
1unless you intend to duplicate column 1 - Mixing HTML
in CLI-oriented examples - Forgetting to use the same
$nin both inner loop bounds - Skipping validation when reading row count from input
Key Takeaways
Two column scans (descending then ascending) place the same row digit on both sides.
Spaces fill every position where the column index does not equal the row index.
The right loop starts at 2 so column 1 is handled only once in the left block.
The same idea extends to symbols, letters, or multi-character cells with adjusted width.
❓ Frequently Asked Questions
3 when j == 3, and the right block prints 3 when k == 3. All other positions on that row are spaces.1 twice for rows where i == 1, changing the pattern. Starting at 2 matches the intended symmetric layout.$n from any trusted source; keep the same inner loop structure.n rows because each row does about 2n character decisions.Explore More PHP Number Patterns!
Practice column-based thinking with more symmetric and mirrored layouts.
Treating output as a fixed-width grid (row × column) makes patterns like this easier to debug: print a character for every cell, then adjust rules per cell.
12 people found this page helpful
