PHP Multiline Comments

La Lakshmi Priya Updated 17 Oct 2026
11 min read ·Lesson 19 of 248

What Is a Multiline Comment?

In simple terms: A multiline comment is a note that can span several lines. It starts with /* and ends with */, and PHP ignores everything in between.

Technically: A multiline comment (also called a C-style or block comment) is delimited by the tokens /* and */. The parser skips all characters between them, including line breaks and ?> sequences.

Why It Exists

Single-line comments (//) are perfect for short notes, but writing a longer explanation with // means repeating the marker on every line. A block comment marks one start and one end, which is convenient for:

  • Longer explanations of complex logic
  • File headers (purpose, author, license)
  • Disabling several lines of code at once
  • Short comments in the middle of a line of code
  • DocBlocks — structured documentation for functions, classes, and properties

Syntax

/*
 This is a multiline comment.
 It can span as many lines as needed.
*/

The comment begins at /* and ends at the first */ PHP finds after it.

Example

<?php
/*
 Shipping rules:
 - Orders above ₹999 ship free.
 - Orders below that pay a flat ₹79.
 - Rules apply only to domestic addresses.
*/
$orderTotal = 1250;
$shipping = $orderTotal > 999 ? 0 : 79;

echo "Shipping: ₹$shipping";

Output

Shipping: ₹0

How It Works

  • The four lines between /* and */ are skipped entirely.
  • Execution starts at $orderTotal = 1250;.
  • The comment documents the business rules in plain language. A reader can understand the rule before reading the ternary expression $orderTotal > 999 ? 0 : 79, which chooses 0 when the condition is true and 79 otherwise.

Common Formatting Style

By convention, each line inside a block comment starts with an aligned asterisk. PHP does not require this — the asterisks are just text inside the comment — but it makes the comment's boundaries obvious at a glance.

<?php
/*
 * Calculates the late fee for a library book.
 *
 * The first 3 days are free (grace period). After that,
 * ₹5 is charged per day, up to a maximum of ₹200.
 */

Inline Block Comments

Because a block comment has an explicit end, it can be placed inside a line of code. A // comment cannot do this, because it always continues to the end of the line.

Example

<?php
$basePrice = 500;
$quantity = 4;

$total = $basePrice * $quantity /* bulk discount is applied later */ ;

echo $total;

Output

2000

A more practical use is labeling arguments in a function call when their meaning is not obvious:

<?php
$text = "Hello World";

echo str_pad($text, 15 /* total length */, "-" /* padding character */);

Output

Hello World----

str_pad() pads the string to a total length of 15 characters using -. The inline comments explain the two numeric and string arguments without breaking the call across lines.

Note: Since PHP 8.0, named arguments often express the same idea more clearly and are checked by PHP: str_pad($text, length: 15, pad_string: "-"). Prefer named arguments when they are available; they are covered in the Named Arguments lesson.


Disabling Several Lines of Code

Block comments are a quick way to switch off a group of statements while testing.

Example

<?php
$users = ["Asha", "Ravi", "Meena"];

/*
foreach ($users as $user) {
    sendWelcomeEmail($user);
}
*/

echo count($users) . " users loaded";

Output

3 users loaded

The loop that sends emails is disabled, so you can test the rest of the script without sending real emails.


Multiline Comments Cannot Be Nested

What This Means

A block comment ends at the first */, no matter how many /* markers appear before it. You cannot place one block comment inside another.

Example

<?php
/*
  Disabled while testing:

  /* Calculate tax */
  $tax = $amount * 0.18;
*/
echo "Done";

Result

PHP Parse error:  syntax error, unexpected token "*" in /path/script.php on line 7

Why This Happens

  1. The comment starts at the /* on line 2.
  2. The inner /* on line 5 is just text inside the comment.
  3. The first */ — the one at the end of line 5 — ends the comment.
  4. $tax = $amount * 0.18; is now real code.
  5. The final */ on line 7 is no longer inside a comment, so PHP sees a stray * and / and reports a syntax error.

How to Avoid It

  • Use // for short notes inside code. Then you can safely wrap any block in /* ... */ when you need to disable it.
  • Use your editor's toggle comment shortcut (Ctrl + / or Cmd + /) to comment out blocks. Editors add // to each line, which never conflicts with existing comments.

The Hidden */ Problem

A less obvious version of the same issue occurs when the code you comment out contains the characters */ inside a string.

Example

<?php
/*
$thumbnails = glob('uploads/*/thumbs/*.jpg');
*/
echo "Done";

Result

The comment ends at uploads/*/ — the */ inside the string. Everything after it, including thumbs/*.jpg');, is parsed as code and causes a parse error.

Why It Happens

The parser looks for the characters */ without understanding that they are inside a string, because inside a comment, strings do not exist — everything is just text. File patterns like */ and regular expressions are common sources of this problem.

Fix: Comment such lines with //, which ignores everything until the end of the line.


Block Comments and ?>

Unlike single-line comments, a block comment is not ended by ?>.

<?php
/*
 This template closes PHP with ?> before the HTML starts.
*/
echo "Still running PHP";

Output

Still running PHP

The ?> inside the comment is ignored because the comment continues until */. This is one reason block comments are safer for longer explanations that might mention PHP tags.


DocBlocks: Documentation Comments

What a DocBlock Is

A DocBlock is a block comment that starts with /** (two asterisks) and is placed directly before a function, class, method, property, or constant. To PHP, it is still a comment and has no effect on execution. To tools — IDEs, static analyzers, and documentation generators — it is structured information following the PHPDoc standard.

Why DocBlocks Exist

  • Editor support: IDEs show the description and parameter details when you hover over or call a function.
  • Static analysis: Tools such as PHPStan and Psalm read DocBlock types to find bugs before the code runs.
  • Generated documentation: Tools such as phpDocumentor build HTML documentation from DocBlocks.
  • Richer types: DocBlocks can describe types that PHP's native type system cannot, such as "an array of strings".

Syntax

/**
 * Short summary on one line.
 *
 * Optional longer description that explains details,
 * edge cases, or usage.
 *
 * @param type $name Description of the parameter
 * @return type Description of the return value
 */

Example

<?php
/**
 * Calculates the late fee for a returned library book.
 *
 * The first 3 days after the due date are free. After that,
 * a fixed amount is charged per day, capped at a maximum fee.
 *
 * @param int $daysLate Number of days after the due date (0 or more)
 * @param int $feePerDay Fee charged for each day after the grace period
 * @return int The total fee in rupees
 * @throws InvalidArgumentException If $daysLate is negative
 */
function calculateLateFee(int $daysLate, int $feePerDay = 5): int
{
    if ($daysLate < 0) {
        throw new InvalidArgumentException('Days late cannot be negative.');
    }

    $gracePeriod = 3;
    $maxFee = 200;

    $chargeableDays = max(0, $daysLate - $gracePeriod);

    return min($chargeableDays * $feePerDay, $maxFee);
}

echo calculateLateFee(10) . "\n";
echo calculateLateFee(2) . "\n";
echo calculateLateFee(100) . "\n";

Output

35
0
200

Step-by-Step Explanation

  1. Summary line — "Calculates the late fee for a returned library book." This is what IDEs show first.
  2. Description — explains the grace period and the cap, information that is not obvious from the function name.
  3. @param — describes each parameter: its type, name, and meaning. "(0 or more)" documents a constraint that the int type alone does not express.
  4. @return — describes the return value, including its unit (rupees).
  5. @throws — tells callers which exception the function can throw, so they know to handle it.
  6. Inside the function, max(0, $daysLate - $gracePeriod) prevents a negative number of chargeable days, and min(..., $maxFee) enforces the cap.

Results: 10 days late → 7 chargeable days × ₹5 = ₹35. 2 days late → within the grace period → ₹0. 100 days late → 97 × ₹5 = ₹485, capped at ₹200.

Common PHPDoc Tags

TagUsed OnPurpose
@paramFunctions, methodsType and meaning of a parameter
@returnFunctions, methodsType and meaning of the return value
@throwsFunctions, methodsExceptions that may be thrown
@varProperties, variablesType of a property or variable
@deprecatedAnythingMarks code that should no longer be used, ideally with what to use instead
@seeAnythingReference to related code or a URL
@sinceAnythingVersion in which the element was added

DocBlocks and Native Types

Modern PHP supports native type declarations: function calculateLateFee(int $daysLate): int. PHP enforces these types at runtime. DocBlock types are not enforced by PHP; they are only read by tools.

Avoid Repeating What Native Types Already Say

<?php
/**
 * @param string $email
 * @return bool
 */
function isValidEmail(string $email): bool
{
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

This DocBlock adds nothing — the signature already declares string and bool. Repeated information creates extra maintenance work and can become inconsistent when the signature changes.

Use DocBlocks Where They Add Information

<?php
/**
 * Returns the email addresses of all active subscribers.
 *
 * @return array<int, string> List of email addresses
 */
function getSubscriberEmails(): array
{
    return ['asha@example.com', 'ravi@example.com'];
}

PHP's native array type cannot say what the array contains. The DocBlock type array<int, string> (integer keys, string values) lets static analyzers detect mistakes such as treating an email address as an array. A common shorthand is string[].

Rule: use native types for everything PHP can express, and add DocBlock types only when they provide more detail.


DocBlocks Are Available at Runtime

Ordinary comments are discarded during compilation, but PHP keeps DocBlocks and exposes them through the Reflection API:

<?php
/**
 * Sends the monthly newsletter.
 */
function sendNewsletter(): void {}

$reflection = new ReflectionFunction('sendNewsletter');
echo $reflection->getDocComment();

Output

/**
 * Sends the monthly newsletter.
 */

Only comments starting with /** are kept; /* comments are not. Some older libraries read annotations from DocBlocks at runtime for routing or database mapping. Modern code uses PHP 8 attributes for this instead, because attributes are real syntax checked by PHP.

Note: If a server sets opcache.save_comments=0, DocBlocks are removed from cached code and getDocComment() returns false. Libraries that depend on runtime DocBlocks will break under that setting. The default is 1.


File Header Comments

Many projects place a block comment at the top of each file describing its purpose and, for open-source code, its license.

<?php
/*
 * This file is part of the GoShop application.
 *
 * Handles checkout: cart validation, tax calculation,
 * and creating the order record.
 *
 * License: MIT
 */

Keep headers short. Information such as the author and change history is better tracked by version control (Git) than maintained by hand in comments.


Common Mistakes

Nesting Block Comments

What happens: The comment ends at the first */, and the rest is parsed as code, causing a syntax error.

Fix: Use // for comments inside code, and use editor shortcuts to comment out blocks.

Commenting Out Code That Contains */

What happens: File patterns or regular expressions inside the disabled code end the comment early.

Fix: Use // on each line when disabling such code.

Forgetting the Closing */

What happens: Everything until the end of the file becomes a comment. PHP may report Unterminated comment starting line N as a warning, and nothing after the comment runs.

Fix: Close every block comment. Editors with syntax highlighting show unclosed comments by coloring the rest of the file as a comment.

Using /* Instead of /** for Documentation

What happens: IDEs, static analyzers, and Reflection ignore the comment because DocBlocks must start with exactly /**.

Fix: Start documentation comments with /**.

DocBlock Types That Contradict the Code

What happens: @return string on a function that returns int. PHP does not check DocBlocks, so the wrong type silently misleads IDEs and other developers.

Fix: Rely on native types and run a static analyzer such as PHPStan, which reports DocBlocks that do not match the code.


Best Practices

  • Use /* */ for longer explanations and file headers, and // for short notes inside code.
  • Use /** */ DocBlocks for functions, classes, methods, and properties that other developers will call or use.
  • Describe behavior, constraints, units, and exceptions in DocBlocks — information the signature cannot show.
  • Do not duplicate native types in DocBlocks; add DocBlock types only for extra detail such as array contents.
  • Keep DocBlocks accurate when the code changes.

Official reference: https://www.php.net/manual/en/language.basic-syntax.comments.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else User-defined Functions Slicing Strings Function Arguments PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning MySQL Database MySQL Connect MySQL Create DB MySQL Create Table MySQL Insert Data MySQL Get Last ID MySQL Insert Multiple MySQL Prepared MySQL Select Data MySQL Where Debugging PHP Project: Image Upload Gallery $_SESSION $_ENV PHP RegEx RegEx Patterns Heredoc and Nowdoc RegEx Modifiers preg_match preg_replace preg_split PHP RegEx Functions Nullable Types Mixed and Never Types Nullsafe Operator PHP Attributes PHP Fibers Readonly Classes Property Hooks (PHP 8.4) Asymmetric Visibility (PHP 8.4) Reflection API SPL Data Structures Composer PHP Form Handling PDO Transactions PDO Error Handling PHP XML Parsers PHP SimpleXML Parser PHP SimpleXML - Get PHP XML Expat Parser PHP DOM Parser PHP XMLReader PHP XMLWriter AJAX Intro PHP Class Constants Encryption with Sodium Recursive Functions Variable Functions Anonymous Functions Closures Arrow Functions First-class Callable Syntax PHP Arrays Indexed Arrays Associative Arrays Create Arrays Variables Scope Static Variables Variable Variables PHP Echo / Print PHP printf / sprintf PHP Data Types PHP Booleans PHP NULL PHP Strings String Functions array_map / array_filter / array_reduce Array Functions PHP Superglobals $GLOBALS What Is `$_SERVER` ? $_REQUEST $_POST $_GET $_FILES $_COOKIE PHP Type Juggling MySQL Order By MySQL Delete Data MySQL Update Data MySQL Limit Data MySQL Joins with PHP Pagination with PHP PDO Introduction PDO Connect PDO Prepared Statements PDO Fetch Modes PSR-4 Autoloading Installing Extensions (PECL / PIE) OPcache & Performance PHP-FPM Project: Contact Form with Email Project: Login & Registration System Project: CRUD App with MySQL Project: Shopping Cart with Sessions Project: REST API with PHP DateTime Class Timezones PHP Include Include vs Require PHP File Handling PHP File Open/Read PHP File Create/Write File Delete / Rename / Copy PHP Directories PHP CSV Files
Ask about this post
AI Ask about this post

Ask questions about PHP Multiline Comments and get answers drawn from it.

Signed-in readers only.