Bird
Raised Fist0
PHPprogramming~15 mins

Readonly properties in PHP - Deep Dive

Choose your learning style10 modes available
Overview - Readonly properties
What is it?
Readonly properties in PHP are special class properties that can only be assigned once, usually during object creation. After they are set, their values cannot be changed. This means you can create objects with fixed data that cannot be accidentally modified later.
Why it matters
Readonly properties help prevent bugs caused by unexpected changes to important data inside objects. Without them, developers might accidentally overwrite values, causing unpredictable behavior. They make code safer and easier to understand by clearly showing which data should stay constant.
Where it fits
Before learning readonly properties, you should understand basic PHP classes and properties. After this, you can explore immutability patterns and advanced object design concepts like value objects and data transfer objects.
Mental Model
Core Idea
Readonly properties are like sealed envelopes: you can put a letter inside once, but you cannot change it afterward.
Think of it like...
Imagine writing a message on a whiteboard and then covering it with a transparent plastic sheet. You can see the message clearly, but you cannot erase or change it anymore. Readonly properties work the same way for data inside objects.
┌─────────────────────────────┐
│         Object              │
│ ┌───────────────┐           │
│ │ Readonly Prop │───set once│
│ └───────────────┘           │
│           │                 │
│           ▼                 │
│    Value locked in          │
└─────────────────────────────┘
Build-Up - 7 Steps
1
FoundationBasic class properties in PHP
🤔
Concept: Learn how to define and use normal class properties.
name = "Alice"; echo $person->name; ?>
Result
Alice
Understanding how normal properties work is essential before learning how readonly properties differ.
2
FoundationWhat is immutability in objects
🤔
Concept: Introduce the idea that some data should not change after creation.
In many programs, some information should stay the same once set, like a person's birthdate. Immutability means making data fixed to avoid accidental changes.
Result
You understand why some properties should not be changed after setting.
Knowing immutability helps appreciate why readonly properties exist.
3
IntermediateDeclaring readonly properties in PHP 8.1+
🤔Before reading on: do you think readonly properties can be changed after the constructor? Commit to your answer.
Concept: PHP 8.1 introduced the readonly keyword to declare properties that can only be assigned once.
email = $email; // Allowed } } $user = new User("user@example.com"); echo $user->email; // $user->email = "new@example.com"; // Error: Cannot modify readonly property ?>
Result
user@example.com
Understanding that readonly properties can only be set once, typically in the constructor, prevents accidental reassignment bugs.
4
IntermediateReadonly properties and object cloning
🤔Before reading on: do you think cloning an object copies readonly properties as-is or resets them? Commit to your answer.
Concept: When cloning objects with readonly properties, the readonly values are copied and remain immutable in the clone.
version = $version; } } $config1 = new Config("1.0"); $config2 = clone $config1; echo $config2->version; // Outputs 1.0 // $config2->version = "2.0"; // Error: Cannot modify readonly property ?>
Result
1.0
Knowing how cloning interacts with readonly properties helps avoid surprises when duplicating objects.
5
IntermediateReadonly properties with typed classes
🤔
Concept: Readonly properties work well with typed properties to enforce both immutability and type safety.
x = $x; $this->y = $y; } } $point = new Point(3.5, 7.2); echo "X: {$point->x}, Y: {$point->y}"; ?>
Result
X: 3.5, Y: 7.2
Combining readonly with types ensures data is both fixed and valid, improving code reliability.
6
AdvancedReadonly properties and inheritance rules
🤔Before reading on: can a child class override a readonly property as writable? Commit to your answer.
Concept: Readonly properties cannot be overridden as writable in child classes; the readonly constraint is preserved.
id = $id; } } class Child extends Base { // public int $id; // Error: Cannot override readonly property with writable } ?>
Result
Error if trying to override readonly as writable
Understanding inheritance restrictions prevents breaking immutability guarantees in subclasses.
7
ExpertReadonly properties and internal mutation loopholes
🤔Before reading on: do you think readonly properties guarantee absolute immutability of complex objects? Commit to your answer.
Concept: Readonly only prevents reassignment of the property itself, but if the property holds an object, that object's internal state can still change unless it is also immutable.
data = $data; } } $data = new Data(); $data->value = 10; $container = new Container($data); $container->data->value = 20; // Allowed, internal mutation ?>
Result
The internal value changes from 10 to 20 despite readonly property
Knowing that readonly protects only the property reference, not the object's internal state, is crucial for designing truly immutable data structures.
Under the Hood
Readonly properties are enforced by PHP's engine at runtime. When a readonly property is assigned, PHP marks it as initialized and prevents any further assignments to that property on the same object instance. This check happens on every write attempt, throwing an error if violated. Internally, the property stores a flag indicating its readonly status and initialization state.
Why designed this way?
Readonly properties were introduced to provide a simple, language-level way to enforce immutability on object properties without requiring complex patterns or external libraries. Before PHP 8.1, developers had to rely on private properties with no setters or custom logic, which was error-prone and verbose. The design balances ease of use with performance by checking assignments at runtime only when necessary.
┌───────────────┐
│   Object      │
│ ┌───────────┐ │
│ │ Property  │ │
│ │ readonly? │─┼─Yes
│ └───────────┘ │
│       │       │
│       ▼       │
│  Is assigned? │
│       │       │
│   ┌───┴───┐   │
│   │ No    │   │
│   │ Assign│   │
│   └───────┘   │
│       │       │
│   ┌───┴───┐   │
│   │ Yes   │   │
│   │ Error │   │
│   └───────┘   │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Can you change a readonly property after the constructor finishes? Commit to yes or no.
Common Belief:Readonly properties can be changed anytime as long as you don't use the constructor.
Tap to reveal reality
Reality:Readonly properties can only be assigned once, typically during construction, and cannot be changed afterward.
Why it matters:Believing you can change readonly properties later leads to runtime errors and confusion when code breaks unexpectedly.
Quick: Does readonly mean the object held by the property is also immutable? Commit to yes or no.
Common Belief:Readonly means the entire object and its data cannot change once assigned.
Tap to reveal reality
Reality:Readonly only prevents changing the property reference; the object's internal data can still be modified unless it is also immutable.
Why it matters:Assuming full immutability causes bugs when internal state changes unexpectedly, breaking assumptions about data safety.
Quick: Can a child class override a readonly property as writable? Commit to yes or no.
Common Belief:Child classes can freely change readonly properties to writable if needed.
Tap to reveal reality
Reality:Readonly properties cannot be overridden as writable in subclasses; the readonly constraint is preserved.
Why it matters:Trying to override readonly as writable causes errors and breaks class inheritance contracts.
Quick: Are readonly properties a new feature in PHP 8.0? Commit to yes or no.
Common Belief:Readonly properties have been in PHP since version 8.0 or earlier.
Tap to reveal reality
Reality:Readonly properties were introduced in PHP 8.1, not earlier versions.
Why it matters:Using readonly syntax in earlier PHP versions causes syntax errors and confusion.
Expert Zone
1
Readonly properties only prevent reassignment of the property itself, not mutation of the object it references, so deep immutability requires immutable objects too.
2
Readonly properties can be combined with constructor property promotion for concise immutable class definitions.
3
Readonly properties are checked at runtime, so excessive use in performance-critical code might have minor overhead compared to normal properties.
When NOT to use
Avoid readonly properties when you need mutable state or when the property value must change after construction. Instead, use normal properties with controlled setters or immutable data structures for deep immutability.
Production Patterns
Readonly properties are commonly used in value objects, configuration objects, and data transfer objects to ensure data integrity. They simplify code by removing the need for explicit getters and setters while enforcing immutability.
Connections
Immutable data structures
Readonly properties build on the idea of immutability by enforcing fixed values at the property level.
Understanding readonly properties helps grasp how immutability can be enforced in programming languages to improve reliability.
Final keyword in object-oriented programming
Both readonly properties and final classes/methods prevent modification, but at different levels: properties vs. inheritance.
Knowing how readonly and final keywords restrict changes helps design safer, more predictable code.
Legal contracts
Readonly properties are like clauses in a contract that cannot be changed once signed.
Recognizing this connection clarifies why immutability is important for trust and correctness in software.
Common Pitfalls
#1Trying to assign a readonly property outside the constructor.
Wrong approach:name = "Alice"; // Error: Cannot assign outside constructor $user->name = "Bob"; // Error ?>
Correct approach:name = $name; } } $user = new User("Alice"); // $user->name = "Bob"; // Still error ?>
Root cause:Misunderstanding that readonly properties must be assigned during construction only.
#2Assuming readonly means deep immutability of objects stored in properties.
Wrong approach:data = $data; } } $container = new Container(new Data()); $container->data->value = 5; // Allowed, unexpected ?>
Correct approach:value = $value; } } class Container { public readonly ImmutableData $data; public function __construct(ImmutableData $data) { $this->data = $data; } } $container = new Container(new ImmutableData(5)); // $container->data->value = 10; // Error ?>
Root cause:Confusing readonly property assignment with immutability of the referenced object.
#3Trying to override a readonly property as writable in a subclass.
Wrong approach:id = $id; } } class Child extends Base { public int $id; // Error: Cannot override readonly property } ?>
Correct approach:id = $id; } } class Child extends Base { // No override of $id property } ?>
Root cause:Not knowing that readonly properties cannot be overridden as writable in subclasses.
Key Takeaways
Readonly properties in PHP allow you to set a property value once, usually during construction, and prevent any further changes.
They help make your objects more reliable by protecting important data from accidental modification.
Readonly only protects the property reference, not the internal state of objects stored in that property.
They were introduced in PHP 8.1 to simplify immutable object design without complex code.
Understanding readonly properties helps you write safer, clearer, and more maintainable PHP code.

Practice

(1/5)
1. What is the main purpose of readonly properties in PHP?
easy
A. To store values that cannot be changed after being set
B. To allow properties to be changed anytime
C. To make properties private
D. To automatically generate getter methods

Solution

  1. Step 1: Understand readonly property behavior

    Readonly properties in PHP are designed to hold values that can only be assigned once and cannot be modified later.
  2. Step 2: Compare options with this behavior

    To store values that cannot be changed after being set correctly describes this behavior, while others describe unrelated features.
  3. Final Answer:

    To store values that cannot be changed after being set -> Option A
  4. Quick Check:

    Readonly means unchangeable after set = A [OK]
Hint: Readonly means value set once and then fixed [OK]
Common Mistakes:
  • Thinking readonly allows changes anytime
  • Confusing readonly with private visibility
  • Assuming readonly auto-generates methods
2. Which of the following is the correct syntax to declare a readonly property in a PHP class?
easy
A. readonly public int $id;
B. public readonly int $id;
C. public int readonly $id;
D. int public readonly $id;

Solution

  1. Step 1: Recall PHP property declaration order

    In PHP, visibility (public/private/protected) comes first, then readonly keyword, then type and variable name.
  2. Step 2: Match syntax with options

    public readonly int $id; matches the correct order: public readonly int $id;. Others have incorrect order.
  3. Final Answer:

    public readonly int $id; -> Option B
  4. Quick Check:

    Visibility then readonly then type = B [OK]
Hint: Visibility keyword comes before readonly in declaration [OK]
Common Mistakes:
  • Placing readonly before visibility
  • Putting readonly after type
  • Mixing order of keywords
3. What will be the output of the following PHP code?
class User {
    public readonly string $name;
    public function __construct(string $name) {
        $this->name = $name;
    }
}
$user = new User('Alice');
echo $user->name;
$user->name = 'Bob';
echo $user->name;
medium
A. Alice followed by a fatal error
B. BobBob
C. AliceBob
D. Syntax error

Solution

  1. Step 1: Understand readonly property assignment

    The readonly property $name is assigned once in the constructor to 'Alice'. This is allowed.
  2. Step 2: Analyze second assignment

    Trying to assign $user->name = 'Bob'; after construction causes a fatal error because readonly properties cannot be changed after initial assignment.
  3. Final Answer:

    Alice followed by a fatal error -> Option A
  4. Quick Check:

    Readonly blocks changes after set = C [OK]
Hint: Readonly allows one assignment only, later changes cause error [OK]
Common Mistakes:
  • Assuming readonly properties can be changed anytime
  • Expecting no error on second assignment
  • Confusing syntax error with runtime error
4. Identify the error in the following PHP code using readonly properties:
class Config {
    public readonly string $version;
    public function __construct() {
        $this->version = '1.0';
        $this->version = '2.0';
    }
}
medium
A. No error, code is correct
B. Missing visibility keyword for property
C. Readonly keyword used incorrectly with string type
D. Assigning readonly property twice in constructor

Solution

  1. Step 1: Check property assignments in constructor

    The readonly property $version is assigned twice: first '1.0', then '2.0'.
  2. Step 2: Understand readonly assignment rules

    Readonly properties can only be assigned once, even inside the constructor. Assigning twice causes an error.
  3. Final Answer:

    Assigning readonly property twice in constructor -> Option D
  4. Quick Check:

    Readonly assigned once only = A [OK]
Hint: Assign readonly property only once, even in constructor [OK]
Common Mistakes:
  • Assigning readonly property multiple times
  • Ignoring visibility keyword importance
  • Thinking readonly disallows string type
5. Given this PHP class with readonly properties, which code correctly creates an immutable user with an ID and name?
class User {
    public readonly int $id;
    public readonly string $name;
    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}

Choose the correct usage:
hard
A. $user = new User(1, 'John'); $user->name = 'Jane';
B. $user = new User(1); $user->name = 'John';
C. $user = new User(1, 'John'); // no changes after construction
D. $user = new User(); $user->id = 1; $user->name = 'John';

Solution

  1. Step 1: Check constructor usage

    The constructor requires two parameters: int $id and string $name. $user = new User(1, 'John'); // no changes after construction correctly calls the constructor with both.
  2. Step 2: Verify immutability

    Readonly properties cannot be changed after construction. $user = new User(1, 'John'); // no changes after construction respects this by not modifying properties after creation.
  3. Final Answer:

    $user = new User(1, 'John'); // no changes after construction -> Option C
  4. Quick Check:

    Construct with all params, no changes after = D [OK]
Hint: Call constructor fully, then do not modify readonly properties [OK]
Common Mistakes:
  • Trying to assign readonly properties after construction
  • Calling constructor with missing arguments
  • Assuming properties can be set without constructor
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard