PHPComments

Comments

A comment is text in your source file that PHP's parser skips over entirely — it never reaches the compiled opcode, never affects behavior, and costs nothing at runtime. Comments exist purely for the humans reading the file: future you, a teammate, or the IDE trying to offer useful autocomplete. PHP supports four comment styles, and picking the right one in the right place is a small but real signal of code quality.

Single-line comments: // and #

PHP accepts two interchangeable syntaxes for a comment that runs to the end of the current line: the C++-style // and the shell-style #. Both stop at the first newline, or at a closing ?> tag, whichever comes first.

Single-line comment styles

PHP
<?php

// This is a single-line comment (the conventional style in PHP)
$price = 19.99; // Price in USD, VAT excluded

# This is also a valid single-line comment
$discount = 0.10; # 10% seasonal discount

echo $price * (1 - $discount);

In practice, // is overwhelmingly the community convention — it's what PSR-12 examples use, what Laravel and Symfony's own codebases use, and what most style guides recommend for consistency. # shows up mostly in configuration-style files or when a codebase's conventions were shaped by developers coming from Python or shell scripting. Pick one and stay consistent within a project; mixing both styles at random reads as sloppy.

Block comments: /* */

For anything spanning multiple lines — a longer explanation, a licence header, temporarily disabling a chunk of code — use the C-style block comment. Everything between /* and */ is ignored, regardless of how many lines it spans.

Block comments

PHP
<?php

/*
 * Calculates compound interest.
 * Formula: A = P(1 + r/n)^(nt)
 * This function assumes r is already expressed as a decimal (0.05, not 5).
 */
function compoundInterest(float $principal, float $rate, int $timesPerYear, int $years): float
{
    return $principal * (1 + $rate / $timesPerYear) ** ($timesPerYear * $years);
}
Block comments do not nest

This is the single most common comment-related bug in PHP. A /* inside an already-open block comment does not start a nested comment — the block simply ends at the first */ the parser finds, no matter how many /* tokens appeared before it.

A comment that ends earlier than you'd expect

PHP
<?php

/*
echo 'first line';
/* a note-to-self inside the disabled block */
echo 'second line';
*/

// The outer comment actually closed at the FIRST */ above.
// PHP parses "echo 'second line'; */" as live code and throws
// a parse error on the stray "*/".
Never put /* */ comments inside other /* */ comments
If you need to temporarily disable a block of code that already contains block comments, either delete those inner comments first, switch the whole block to `//` lines, or wrap the section in an `if (false) { ... }` guard instead. Nesting `/* */` reliably produces a confusing parse error far from where the real mistake is.
Docblocks: comments IDEs actually read

A docblock is a block comment that starts with an extra asterisk — /** instead of /* — followed by tags like @param, @return, and @throws. PHP itself still ignores the contents completely, but tools do not: IDEs like PhpStorm and VS Code parse docblocks to power autocomplete, inline parameter hints, and type checking, and static analysers like PHPStan and Psalm use them to catch bugs before runtime.

A docblock that improves IDE support

PHP
<?php

/**
 * Converts an amount between two currencies using a fixed exchange rate.
 *
 * @param float  $amount   The amount to convert, in the source currency.
 * @param float  $rate     Exchange rate: 1 unit of source = $rate units of target.
 * @param string $rounding Either 'up', 'down', or 'nearest'. Defaults to 'nearest'.
 *
 * @return float The converted amount, rounded per $rounding.
 *
 * @throws InvalidArgumentException If $rounding is not a recognised value.
 */
function convertCurrency(float $amount, float $rate, string $rounding = 'nearest'): float
{
    $converted = $amount * $rate;

    return match ($rounding) {
        'up'      => ceil($converted),
        'down'    => floor($converted),
        'nearest' => round($converted),
        default   => throw new InvalidArgumentException("Unknown rounding mode: {$rounding}"),
    };
}
PHP 8's native types reduce, but don't eliminate, docblocks
Since scalar type declarations and return types are now first-class PHP syntax, you no longer need `@param int $x` just to document a type the function signature already states. Docblocks still earn their keep for things the type system cannot express: array shapes (`@param string[] $tags`), generics-style intent, `@throws`, and a one-line summary of *why* the function exists.
Comment what the code doesn't already say

The most common mistake with comments isn't a syntax error, it's wasted words. A comment that restates the code adds noise and rots the moment the code changes underneath it. A useful comment explains the why — a business rule, a workaround for a bug in a dependency, a reason an "obvious" simplification would actually be wrong.

Noise vs. signal

PHP
<?php

// Bad: restates the obvious, will drift out of sync with the code
// Increment counter by 1
$counter++;

// Good: explains a non-obvious business rule
// Free trial users get 3 exports; upgrading resets this counter to 0.
$exportsRemaining--;

// Good: documents a workaround someone would otherwise "helpfully" remove
// Sleep briefly before retrying — the payment gateway rate-limits bursts
// of requests under 200ms apart (see incident-2026-03-14).
usleep(250_000);
  • // and # both comment to end-of-line; // is the community standard.

  • /* */ comments span multiple lines but never nest — the first */ closes the whole block.

  • /** ... */ docblocks are ignored by PHP but read by IDEs and static analysis tools.

  • PHP 8 native types cover simple parameter/return documentation; docblocks are still valuable for array shapes, @throws, and rationale.

  • Write comments that explain why, not what — the code already says what.

Tip
Before writing a comment explaining a confusing line, try renaming a variable or extracting a small function with a descriptive name instead. `$daysUntilExpiry = $expiresAt->diff($now)->days;` often needs no comment at all, while the equivalent one-liner buried in a larger expression usually does. Comments are a good tool, but self-explanatory code needs fewer of them.