PHP Mirrored Number Pattern (Spaced)

Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview

What Is This Pattern?

A spaced mirror number pattern prints a fixed-width left half 1..$i (spaces after), then a fixed-width right half $i..1 (spaces before) — until the last row joins with no gap.

Remember
Rule: for i from 1 to rows
        left:  j=1..rows → j if j<=i else space
        right: k=rows..1 → space if k>i else k

1        1
12      21
123    321
1234  4321
1234554321     ← rows = 5

Follows the 0-centered descending mirror in Program 28; next is the right-aligned descending triangle in Program 30.

How to Solve It

Outer loop grows $i. Both inner loops always run $rows times — print a digit or a space so columns stay aligned.

MethodIdeaBest for
Fixed-width if/elseLeft $j<=$i ? $j : " "; right $k>$i ? " " : $kLearning, interviews, exams
Ternary formSame logic in one expression per positionShorter demos once if/else is clear

Pseudocode

Pseudocode
for i from 1 to rows:
    for j from 1 to rows:
        if j <= i: print j
        else: print space
    for k from rows down to 1:
        if k > i: print space
        else: print k
    print newline

Cheat sheet

GoalPattern
Grow each rowfor ($i = 1; $i <= $rows; $i++)
Left halfif ($j <= $i) echo $j; else echo " ";
Right halfif ($k > $i) echo " "; else echo $k;
Fixed widthBoth inners always loop 1..$rows / $rows..1
End of rowecho PHP_EOL;

Printing Numbers vs Starting a New Line

APIEffectUse for
echo $j / $k / " "Stays on the same lineEach digit or space on the row
echo PHP_EOLEnds the current lineAfter both fixed-width loops finish

Print characters without a newline, then end the row once.

Live Preview

Change the row count and the spaced mirror updates instantly — capped at 9 for readable demos.

Whole numbers from 1 to 9. Tap a chip or type a value — the preview redraws as you go.

Live result rows = 5 · 50 chars
1        1
12      21
123    321
1234  4321
1234554321

Worked Walkthrough — $rows = 5

Trace how left digits grow, gap spaces shrink, and the right mirror closes in.

$iLeftGapRightPrints
118 spaces11 1
2126 spaces2112 21
31234 spaces321123 321
412342 spaces43211234 4321
5123450 spaces543211234554321

Gap spaces = 2 × (rows − i). Each row prints 2 × rows characters → O(n²) total.

PHP Programs

Three complete programs: fixed $rows = 5, CLI input with ternary form, and a compact $rows = 3 demo. Use View Output to reveal sample results.

Example 1 — Fixed $rows = 5

Hard-coded height — fixed-width left and right halves with if/else.

PHP
<?php
for ($i = 1; $i <= 5; $i++) {
    for ($j = 1; $j <= 5; $j++) {
        if ($j <= $i) {
            echo $j;
        } else {
            echo " ";
        }
    }

    for ($k = 5; $k >= 1; $k--) {
        if ($k > $i) {
            echo " ";
        } else {
            echo $k;
        }
    }

    echo PHP_EOL;
}
?>

How It Works

1. Outer grows the filled count. $i is how many digits appear on each half.

2. Fixed width. Both inners always run 5 times — unused slots become spaces.

3. Last row joins. When $i = 5, no spaces remain — output 1234554321.

Example 2 — User Input Rows

Read $rows from the CLI, validate, then use ternary conditions for each position.

PHP
<?php
echo "Enter rows: ";
$input = trim(fgets(STDIN));

if (!is_numeric($input) || (int) $input <= 0) {
    echo "Please enter a positive integer." . PHP_EOL;
    exit(1);
}

$rows = (int) $input;

for ($i = 1; $i <= $rows; $i++) {
    for ($j = 1; $j <= $rows; $j++) {
        echo ($j <= $i) ? $j : " ";
    }

    for ($k = $rows; $k >= 1; $k--) {
        echo ($k > $i) ? " " : $k;
    }

    echo PHP_EOL;
}
?>

How It Works

1. Prompt and validate. Reject non-numeric and non-positive values before printing.

2. Same core. Ternary form matches Example 1’s if/else — only $rows comes from the user.

3. Safer input tip. Cap demos for readable output:

Safer input
if (!is_numeric($input) || (int) $input < 1 || (int) $input > 9) {
    echo "Enter a whole number from 1 to 9." . PHP_EOL;
    exit(1);
}

Example 3 — Compact $rows = 3

Same structure with only three rows — easy to confirm gap spaces shrink by 2 each time.

PHP
<?php
$rows = 3;

for ($i = 1; $i <= $rows; $i++) {
    for ($j = 1; $j <= $rows; $j++) {
        if ($j <= $i) {
            echo $j;
        } else {
            echo " ";
        }
    }

    for ($k = $rows; $k >= 1; $k--) {
        if ($k > $i) {
            echo " ";
        } else {
            echo $k;
        }
    }

    echo PHP_EOL;
}
?>

How It Works

1. Three rows. $i = 1 → 1 1; $i = 2 → 12 21; $i = 3 → 123321.

2. Trace on paper. If either loop stops at $i instead of $rows, columns misalign.

3. Scale up next. Once the small demo is clear, use Examples 1–2 for five rows or user input.

Edge Cases & Pitfalls

Check these before calling the solution done.

no spaces

Missing spaces

Skipping echo " " collapses the halves — you get a tight palindrome, not a spaced mirror.

loop to i

Wrong loop bound

If either inner loop stops at $i instead of $rows, columns misalign and the gap disappears.

PHP_EOL inside

Broken rows

If echo PHP_EOL sits inside either inner loop, the mirror splits across lines. Call it only after both finish.

rows = 1

Single pair

Output is 11 — no gap spaces. A good sanity check for input validation.

rows > 9

Multi-digit glue

Values above 9 print multi-digit numbers that break column alignment. Cap demos at 9.

fgets

Check is_numeric

Bare (int) casts turn non-numeric strings into 0 — prefer is_numeric before casting.

Time and Space Complexity

ProgramTimeExtra space
Fixed / input (Examples 1–2)O(n²)O(1)
Compact rows = 3 (Example 3)O(n²)O(1)

Each of n rows prints 2n characters → 2n² total → O(n²) time. Only a few loop variables are needed.

Key Takeaways

  • Two fixed halves: left fills 1..$i; right fills $i..1; unused slots are spaces.
  • Always width n: both inners loop to $rows, not $i.
  • Break the row: digits and spaces in both inners; echo PHP_EOL after both finish.
  • Complexity: O(n²) time from 2n² characters; O(1) extra space.

One line: for each row $i, print fixed-width 1..$i then spaces, then spaces then $i..1, then echo PHP_EOL.

Frequently Asked Questions

A spaced mirror: for rows=5 you get 1 1 / 12 21 / 123 321 / 1234 4321 / 1234554321 — left 1..i and right i..1 with alignment spaces.
Spaces keep the left and right halves aligned so the pattern looks symmetric. Without them, the right half shifts left each row.
The right loop runs $k from $rows down to 1. When $k > $i it prints a space; otherwise it prints $k — building $i..1 on the right.
Both inner loops always run $rows times. Extra positions are filled with spaces so columns stay aligned.
Program 27 prints a tight palindrome with no alignment spaces. Program 29 uses fixed-width loops and spaces for a symmetric spaced shape.
When $i equals $rows, both halves fill all columns — 12345 on the left and 54321 on the right meet with no space between.
Use trim(fgets(STDIN)) and check is_numeric($input) before casting to int — see Example 2.
O(n²) for n rows because each row runs two inner loops of width n.

Did you know?

This pattern prints an increasing left half (1..$i), then a mirrored right half ($i..1). Spaces in the fixed-width loops keep both halves aligned until the final row joins without a gap.

Next: Right-Aligned Descending Triangle

Continue with a triangle that pads spaces on the left.

Program 30 tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

12 people found this page helpful