How to access items inside nested read-only classes and interfaces in PHP

1 Answer

0 votes
// 1. Define metadata using a modern readonly class
readonly class Metadata {
    public function __construct(
        public string $name,
        public bool $isActive
    ) {}
}

// 2. Define an interface representing the variant dimensions (union equivalent)
interface Dimension {}

readonly class Circle implements Dimension {
    public function __construct(
        public float $radius
    ) {}
}

readonly class Rectangle implements Dimension {
    public function __construct(
        public float $width,
        public float $height
    ) {}
}

// 3. Define the main container class holding ID, metadata, and the variant dimension
readonly class Shape {
    public function __construct(
        public int $id,
        public Metadata $metadata,
        public Dimension $dimension
    ) {}
}

/**
 * Safely accesses and prints properties from nested readonly objects and variant types
 * using PHP 8+ match expressions.
 * 
 * @param Shape|null $shape The shape object to inspect.
 */
function printShapeProperties(?Shape $shape): void {
    if ($shape === null) {
        echo "Error: Received null shape.\n";
        return;
    }

    // Accessing nested object properties directly
    echo "Shape ID: {$shape->id}\n";
    echo "Shape Name: {$shape->metadata->name}\n";
    echo "Status: " . ($shape->metadata->isActive ? "Active" : "Inactive") . "\n";

    // Match expressions with boolean evaluation handle variant types cleanly
    match (true) {
        $shape->dimension instanceof Circle => printCircle($shape->dimension),
        $shape->dimension instanceof Rectangle => printRectangle($shape->dimension),
        default => throw new \InvalidArgumentException("Unknown dimension type")
    };

    echo "------------------------------------\n";
}

function printCircle(Circle $c): void {
    echo "Type: Circle\n";
    echo "Radius: {$c->radius}\n";
}

function printRectangle(Rectangle $r): void {
    echo "Type: Rectangle\n";
    echo "Width: {$r->width}, Height: {$r->height}\n";
}

// --- Application Entry Point ---

// Initialize a Circle shape with named arguments
$myCircle = new Shape(
    id: 101,
    metadata: new Metadata(name: 'Unit Circle', isActive: true),
    dimension: new Circle(radius: 5.5)
);

// Initialize a Rectangle shape
$myRectangle = new Shape(
    id: 102,
    metadata: new Metadata(name: 'Bounding Box', isActive: false),
    dimension: new Rectangle(width: 10.0, height: 20.0)
);

// Print properties
printShapeProperties($myCircle);
printShapeProperties($myRectangle);


/*
run:

Shape ID: 101
Shape Name: Unit Circle
Status: Active
Type: Circle
Radius: 5.5
------------------------------------
Shape ID: 102
Shape Name: Bounding Box
Status: Inactive
Type: Rectangle
Width: 10, Height: 20
------------------------------------

*/

 



answered 2 hours ago by avibootz

Related questions

...