ZetCode

PHP Anonymous Classes

last modified October 22, 2026

PHP anonymous classes allow you to define and instantiate a class inline, without giving it a name. They were introduced in PHP 7.0 and are useful for simple, one-off objects, for implementing interfaces and extending classes on the fly, and for test doubles. This tutorial covers basic and advanced usage of anonymous classes with practical examples.

An anonymous class can do everything a named class can: it can have properties, methods and a constructor, extend a class, implement interfaces and use traits. The class is declared and instantiated in a single new class expression.

Basic anonymous class

This example creates and uses a basic anonymous class.

basic_anonymous.php
<?php

declare(strict_types=1);

$greeting = new class {
    public function sayHello(): string
    {
        return "Hello, World!";
    }
};

echo $greeting->sayHello(), "\n";

The anonymous class is instantiated with the new class syntax and assigned to the $greeting variable. Note the semicolon after the closing brace; the whole construct is an expression.

$ php basic_anonymous.php
Hello, World!

Implementing an interface

This example creates an anonymous class that implements an interface.

implement_interface.php
<?php

declare(strict_types=1);

interface Greeting
{
    public function sayHello(): string;
}

$greeting = new class implements Greeting {
    public function sayHello(): string
    {
        return "Hello, World!";
    }
};

echo $greeting->sayHello(), "\n";
var_dump($greeting instanceof Greeting);

The anonymous class implements the Greeting interface, so the object can be passed wherever a Greeting is expected. The instanceof operator confirms this.

$ php implement_interface.php
Hello, World!
bool(true)

Extending a class

This example creates an anonymous class that extends an existing class.

extend_class.php
<?php

declare(strict_types=1);

class BaseGreeting
{
    public function sayHello(): string
    {
        return "Hello, Base!";
    }
}

$greeting = new class extends BaseGreeting {
    public function sayHello(): string
    {
        return parent::sayHello() . " Hello, Anonymous!";
    }
};

echo $greeting->sayHello(), "\n";

The anonymous class extends BaseGreeting and overrides the sayHello method. The parent implementation is still available through parent::.

$ php extend_class.php
Hello, Base! Hello, Anonymous!

Constructor arguments

Arguments for the constructor are passed in parentheses after the class keyword.

constructor_arguments.php
<?php

declare(strict_types=1);

$greeting = new class("World") {
    public function __construct(private string $name) {}

    public function sayHello(): string
    {
        return "Hello, " . $this->name . "!";
    }
};

echo $greeting->sayHello(), "\n";

The string "World" is passed to the constructor, which stores it in a promoted private property.

$ php constructor_arguments.php
Hello, World!

Accessing outer variables

Unlike closures, an anonymous class has no use clause and cannot see variables of the enclosing scope. Values must be passed through the constructor.

outer_scope.php
<?php

declare(strict_types=1);

$prefix = "[app]";

$logger = new class($prefix) {
    public function __construct(private string $prefix) {}

    public function log(string $message): void
    {
        echo "$this->prefix $message\n";
    }
};

$logger->log("started");
$logger->log("finished");

The $prefix variable is handed over as a constructor argument and stored in the object.

$ php outer_scope.php
[app] started
[app] finished

Using traits

This example uses a trait within an anonymous class.

use_traits.php
<?php

declare(strict_types=1);

trait GreetingTrait
{
    public function sayHello(): string
    {
        return "Hello, Trait!";
    }
}

$greeting = new class {
    use GreetingTrait;
};

echo $greeting->sayHello(), "\n";

The anonymous class uses the GreetingTrait trait to provide the sayHello method.

$ php use_traits.php
Hello, Trait!

Anonymous class with properties

This example shows an anonymous class with typed properties.

properties.php
<?php

declare(strict_types=1);

$person = new class {
    public string $name = "Anonymous";
    public int $age = 30;

    public function getInfo(): string
    {
        return "Name: $this->name, Age: $this->age";
    }
};

echo $person->getInfo(), "\n";

$person->age = 31;
echo $person->getInfo(), "\n";

The anonymous class defines typed properties with default values and a method to display them. Public properties can be changed from outside.

$ php properties.php
Name: Anonymous, Age: 30
Name: Anonymous, Age: 31

Anonymous class as a callback object

An anonymous class can be passed directly as an argument.

callback.php
<?php

declare(strict_types=1);

interface Task
{
    public function execute(): string;
}

function runTask(Task $task): string
{
    return $task->execute();
}

$result = runTask(new class implements Task {
    public function execute(): string
    {
        return "Task executed!";
    }
});

echo $result, "\n";

The runTask function expects a Task. Typing the parameter with an interface, rather than with object, guarantees that the execute method exists.

$ php callback.php
Task executed!

Anonymous class with multiple methods

This example shows an anonymous class with several typed methods.

multiple_methods.php
<?php

declare(strict_types=1);

$calculator = new class {
    public function add(int $a, int $b): int
    {
        return $a + $b;
    }

    public function multiply(int $a, int $b): int
    {
        return $a * $b;
    }
};

echo $calculator->add(5, 3), "\n";
echo $calculator->multiply(4, 3), "\n";

The anonymous class groups two math operations with strict typing.

$ php multiple_methods.php
8
12

Class names of anonymous classes

The engine gives every anonymous class a generated name. It starts with class@anonymous and contains the file name and position of the declaration, so it should not be relied upon.

class_name.php
<?php

declare(strict_types=1);

$a = new class {};
$b = new class {};

$name = get_class($a);

var_dump(str_starts_with($name, 'class@anonymous'));
var_dump((new ReflectionClass($a))->isAnonymous());

var_dump($a::class === $b::class);

$factory = fn() => new class {};
var_dump($factory()::class === $factory()::class);

Two declarations produce two different classes, even when their bodies are identical. A single declaration evaluated twice, here inside an arrow function, produces two objects of the same class. The isAnonymous method of ReflectionClass is the reliable way to detect an anonymous class.

$ php class_name.php
bool(true)
bool(true)
bool(false)
bool(true)

Test doubles

Anonymous classes are handy for simple stubs in tests, where creating a named class for each scenario would be noise.

test_double.php
<?php

declare(strict_types=1);

interface Clock
{
    public function now(): DateTimeImmutable;
}

final class Greeter
{
    public function __construct(private Clock $clock) {}

    public function greet(): string
    {
        $hour = (int) $this->clock->now()->format('G');

        return $hour < 12 ? 'Good morning' : 'Good afternoon';
    }
}

$morning = new class implements Clock {
    public function now(): DateTimeImmutable
    {
        return new DateTimeImmutable('2026-10-22 08:30');
    }
};

$afternoon = new class implements Clock {
    public function now(): DateTimeImmutable
    {
        return new DateTimeImmutable('2026-10-22 15:00');
    }
};

echo (new Greeter($morning))->greet(), "\n";
echo (new Greeter($afternoon))->greet(), "\n";

The Greeter depends on a Clock interface. Two anonymous classes return fixed times, which makes the output of greet predictable.

$ php test_double.php
Good morning
Good afternoon

Readonly anonymous classes

Since PHP 8.3, an anonymous class can be declared readonly. All its properties then become readonly.

readonly_anonymous.php
<?php

declare(strict_types=1);

$point = new readonly class(3, 4) {
    public function __construct(public int $x, public int $y) {}

    public function length(): float
    {
        return sqrt($this->x ** 2 + $this->y ** 2);
    }
};

echo $point->length(), "\n";

try {
    $point->x = 10;
} catch (Error $e) {
    echo get_class($e), ": ", $e->getMessage(), "\n";
}

The properties are initialized once in the constructor. Any later attempt to modify them throws an Error.

$ php readonly_anonymous.php
5
Error: Cannot modify readonly property class@anonymous::$x

Best practices for anonymous classes

Source

PHP Anonymous Classes Documentation

In this article, we have explored PHP anonymous classes, including interfaces, inheritance, constructor arguments, traits, test doubles, and readonly anonymous classes.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.