PHP Hollow Diamond Star Pattern (Inside Square)

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

What Is This Pattern?

A hollow diamond inside a square frames a hollow diamond with solid top and bottom bars: every line is 2 * rows characters wide, and height is 2 * rows - 1.

Remember
Rule: solid bars on ends; elsewhere left * + gap + right *

**********
****  ****
***    ***
**      **
*        *
**      **
***    ***
****  ****
**********     ← rows = 5 (width 10, height 9)

Unlike Program 9 (hollow diamond alone) or Program 10 (filled diamond), middle rows here are always left stars, gap spaces, then left stars again — with a mirrored i so the hollow opens to the waist and closes again.

How to Solve It

Two ways to emit the same shape — start with segment loops, then optionally shorten with str_repeat.

MethodIdeaBest for
Three-segment loopsSolid bars on ends; left / gap / right insideLearning, interviews, exams
str_repeat segmentsBuild each bar or segment in one callShorter demos once formulas click

Pseudocode

Pseudocode
height = 2 * rows - 1
width  = 2 * rows

for line from 1 to height:
    if line is first or last:
        print width stars
    else:
        i = line if line <= rows else (2 * rows - line)
        left = rows - i + 1
        gap  = 2 * (i - 1)
        print left stars, gap spaces, left stars
    print newline

Cheat sheet

GoalPattern
Dimensions$height = 2 * $rows - 1, $width = 2 * $rows
Solid barif ($line == 1 || $line == $height) print $width stars
Map line → i$i = ($line <= $rows) ? $line : (2 * $rows - $line)
Left / right stars$left = $rows - $i + 1
Hollow gap$gap = 2 * ($i - 1)
Width check2 * $left + $gap == $width
One-line bar shortcutecho str_repeat("*", $width) . PHP_EOL;

Printing Stars vs Starting a New Line

APIEffectUse for
echo "*" / echo " "Stays on the same lineEach * and each space
echo PHP_EOLEnds the current lineAfter the bar or the three segments

Live Preview

Change the size and the framed hollow diamond updates instantly — including width and height.

Whole numbers from 1 to 10. Width is 2 * rows; height is 2 * rows - 1.

Live result 5 rows · 10×9
**********
****  ****
***    ***
**      **
*        *
**      **
***    ***
****  ****
**********

Worked Walkthrough — rows = 4

Trace each line: solid bar or inner row with i, left, and gap. Grid size: width 8, height 7.

lineKindileftgapPrinted row
1Bar———********
2Inner232*** ***
3Inner324** **
4Inner416* *
5Inner324** **
6Inner232*** ***
7Bar———********

On every inner row, 2 * left + gap = 8 = width. Lines 3 and 5 share the same i because of mirroring — that is why time is still O(n²).

PHP Programs

Three complete programs: fixed size, CLI input, and a str_repeat shortcut. Use View Output to reveal sample results.

Example 1 — Fixed rows = 5

Hard-coded size — solid bars on the ends; left / gap / right on every other line.

PHP
<?php
$rows = 5;
$height = 2 * $rows - 1;
$width = 2 * $rows;

for ($line = 1; $line <= $height; $line++) {
    if ($line == 1 || $line == $height) {
        for ($j = 1; $j <= $width; $j++) {
            echo "*";
        }
    } else {
        $i = ($line <= $rows) ? $line : (2 * $rows - $line);
        $left = $rows - $i + 1;
        $gap = 2 * ($i - 1);

        for ($j = 1; $j <= $left; $j++) {
            echo "*";
        }
        for ($j = 1; $j <= $gap; $j++) {
            echo " ";
        }
        for ($j = 1; $j <= $left; $j++) {
            echo "*";
        }
    }
    echo PHP_EOL;
}
?>

How It Works

1. Set the grid. $height = 9 and $width = 10 for $rows = 5.

2. Solid bars. When $line is 1 or 9, print ten stars with echo "*".

3. Map the inner index. For other lines, $i = $line on the way down, or 2 * $rows - $line on the way up.

4. Print three segments. $left stars, $gap spaces, $left stars — then echo PHP_EOL.

On the waist ($line = 5), $i = 5, so $left = 1 and $gap = 8: one star on each side with a wide hollow center.

Example 2 — User Input Version

Read the size from the CLI. Prefer is_numeric in real apps (shown in the tip below).

PHP
<?php
echo "Enter the number of rows: ";
$rows = (int) trim(fgets(STDIN));

$height = 2 * $rows - 1;
$width = 2 * $rows;

for ($line = 1; $line <= $height; $line++) {
    if ($line == 1 || $line == $height) {
        for ($j = 1; $j <= $width; $j++) {
            echo "*";
        }
    } else {
        $i = ($line <= $rows) ? $line : (2 * $rows - $line);
        $left = $rows - $i + 1;
        $gap = 2 * ($i - 1);

        for ($j = 1; $j <= $left; $j++) {
            echo "*";
        }
        for ($j = 1; $j <= $gap; $j++) {
            echo " ";
        }
        for ($j = 1; $j <= $left; $j++) {
            echo "*";
        }
    }
    echo PHP_EOL;
}
?>

How It Works

1. Prompt and read. Ask for a size, then trim(fgets(STDIN)) and cast to int.

2. Same grid core. Only the source of $rows changes — the bar and left/gap/right logic match Example 1.

3. Safer input tip. Bare (int) casts turn letters into 0. Prefer:

Safer input
echo "Enter the number of rows: ";
$input = trim(fgets(STDIN));
if (!is_numeric($input) || (int) $input < 1) {
    echo "Enter a positive whole number." . PHP_EOL;
    exit(1);
}
$rows = (int) $input;

Example 3 — str_repeat Segments

Build the solid bar and each left / gap / right piece as strings — same shape, fewer inner loops.

PHP
<?php
$rows = 5;
$height = 2 * $rows - 1;
$width = 2 * $rows;

for ($line = 1; $line <= $height; $line++) {
    if ($line == 1 || $line == $height) {
        echo str_repeat("*", $width) . PHP_EOL;
    } else {
        $i = ($line <= $rows) ? $line : (2 * $rows - $line);
        $left = $rows - $i + 1;
        $gap = 2 * ($i - 1);

        echo str_repeat("*", $left);
        echo str_repeat(" ", $gap);
        echo str_repeat("*", $left) . PHP_EOL;
    }
}
?>

How It Works

1. Same outer loop. Still walk $line from 1 to $height with the same bar vs inner branch.

2. Build each segment. str_repeat("*", $left) and str_repeat(" ", $gap) replace the character loops.

3. Print and advance. Echo the first two segments, then concatenate PHP_EOL on the last so the row ends correctly.

Learn the loop version first (Examples 1–2) so you can explain every bound in an interview; treat this as a polish shortcut afterward.

Edge Cases & Pitfalls

Check these before calling the solution done.

Width vs height

Do not swap formulas

Width is 2 * $rows; height is 2 * $rows - 1. Mixing them skews the whole frame.

Wrong mirror

Broken lower half

Use $i = ($line <= $rows) ? $line : (2 * $rows - $line). Forgetting the mirror breaks symmetry.

Program 9 logic

Different layout

Diagonal $i == $j tests from Program 9 do not draw this framed figure — use left / gap / right.

rows = 1

Single bar

Height = 1, width = 2 — output is just ** (first line is also the last).

rows ≤ 0

Empty output

Outer loop never runs. Validate and re-prompt for interactive programs.

Bad input

Check is_numeric

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

Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(rows²)O(1)
str_repeat segments (Example 3)O(rows²)O(rows) temporary per segment

About 2n - 1 lines × 2n characters per line for n = rows — still quadratic in n.

Key Takeaways

  • Grid: width 2n, height 2n - 1.
  • Bars: solid top and bottom; elsewhere left / gap / right.
  • Mirror: map line → i, then left = rows - i + 1 and gap = 2 * (i - 1).
  • Complexity: O(n²) time; O(1) extra space for nested loops.

One line: solid bars on the ends; elsewhere print left stars, gap spaces, left stars — keep 2 * left + gap == width.

Frequently Asked Questions

Use height 2*rows-1 and width 2*rows. Print a full row of stars on the first and last lines. For every other line, map line to i with symmetry, then print (rows-i+1) stars, a gap of 2*(i-1) spaces, and the same number of stars again.
Width is 2*rows and height is 2*rows-1 so the top and bottom are full horizontal bars while the sides close on the leftmost and rightmost columns of the inner rows.
Program 9 prints a hollow diamond alone with constant width 2*rows-1. Program 11 adds solid top and bottom bars of length 2*rows and builds each inner line from left stars, a gap, and right stars.
left = rows - i + 1 is how many stars sit on each side. gap = 2 * (i - 1) is the hollow space between them. Together they always sum to width.
If line <= rows, i = line. Otherwise i = 2 * rows - line. That mirrors the distance from the nearest end so the hollow waist is widest in the middle.
echo stays on the same line. echo PHP_EOL ends the current line. Stars and spaces use echo; the row break uses echo PHP_EOL after the bar or the three segments.
O(n²) where n is rows. There are 2n-1 lines and each prints 2n characters.
Use trim(fgets(STDIN)) and check is_numeric($input) before casting to int so bad input does not produce unexpected results.

Did you know?

Every line is exactly 2 * rows characters wide. Inner rows always satisfy 2 * left + gap == 2 * rows — so the frame closes cleanly on both sides.

Last Numbered Star Pattern

Review Programs 9 and 10, then explore more PHP topics from the hub.

All PHP Star Patterns →

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