Object Features

Back

Loading concept...

🎭 PHP Advanced OOP: Object Features

Imagine you’re a master chef who not only creates amazing dishes but can also clone them perfectly, compare flavors, create secret recipes on the fly, and label everything beautifully. That’s what these PHP object features let you do with your code!


πŸ‘ Object Cloning: Making Perfect Copies

What is it?

Think of a photocopier. You put a document in, and you get an exact copy. Object cloning in PHP works the same way!

When you clone an object, you create a brand new copy that lives separately from the original. Change the copyβ€”the original stays the same!

Simple Example

class Sheep {
    public string $name;

    public function __construct($name) {
        $this->name = $name;
    }
}

$dolly = new Sheep("Dolly");
$molly = clone $dolly;  // Make a copy!
$molly->name = "Molly"; // Change the copy

echo $dolly->name; // Still "Dolly"
echo $molly->name; // Now "Molly"

🎩 The Magic __clone() Method

When you need to do something special during cloning:

class Document {
    public string $title;
    public DateTime $created;

    public function __clone() {
        // Reset creation date for copy
        $this->created = new DateTime();
        $this->title = "Copy of " . $this->title;
    }
}

⚠️ Deep vs Shallow Clone

graph TD A["Original Object"] --> B["Shallow Clone"] A --> C["Deep Clone"] B --> D["Shares references<br>to inner objects"] C --> E["Copies everything<br>completely separate"]

By default, PHP does shallow cloning. If your object contains other objects, you need to clone them manually in __clone().


βš–οΈ Object Comparison: Are These the Same?

Two Ways to Compare

Think of comparing twins:

  • == asks: β€œDo they look alike?” (same properties)
  • === asks: β€œAre they the exact same person?” (same instance)

Simple Example

class Box {
    public int $size;
}

$box1 = new Box();
$box1->size = 10;

$box2 = new Box();
$box2->size = 10;

$box3 = $box1; // Same reference!

// Equal comparison (==)
var_dump($box1 == $box2);  // true (same values)

// Identical comparison (===)
var_dump($box1 === $box2); // false (different objects)
var_dump($box1 === $box3); // true (same object!)

πŸ” What == Checks

Condition Result
Same class βœ… Required
Same property names βœ… Required
Same property values βœ… Required
Same memory location ❌ Not required

🎭 Anonymous Classes: Classes Without Names

What are they?

Imagine needing a disposable costume for just one scene in a play. You don’t need to name it or store itβ€”you just create it, use it, and move on.

Anonymous classes are perfect for:

  • One-time-use objects
  • Quick testing
  • Simple callbacks

Simple Example

// Create and use immediately!
$greeter = new class {
    public function sayHi() {
        return "Hello, World!";
    }
};

echo $greeter->sayHi(); // "Hello, World!"

πŸš€ With Constructor and Inheritance

interface Logger {
    public function log(string $msg): void;
}

// Anonymous class that implements interface
$logger = new class implements Logger {
    public function log(string $msg): void {
        echo "πŸ“ " . $msg;
    }
};

$logger->log("Task completed!");

πŸ’‘ Passing Arguments

$name = "PHP";

$obj = new class($name) {
    private string $language;

    public function __construct(string $lang) {
        $this->language = $lang;
    }

    public function greet(): string {
        return "I love {$this->language}!";
    }
};

echo $obj->greet(); // "I love PHP!"

🏷️ Enumerations (Enums): Named Constants with Superpowers

What are they?

Think of a traffic light. It can only be:

  • πŸ”΄ Red
  • 🟑 Yellow
  • 🟒 Green

Not β€œPurple” or β€œSparkly”! Enums give you a fixed set of allowed values.

Simple Example (Pure Enum)

enum Status {
    case Pending;
    case Active;
    case Completed;
    case Cancelled;
}

function checkOrder(Status $status) {
    if ($status === Status::Active) {
        echo "Your order is being processed!";
    }
}

checkOrder(Status::Active);

🎯 Why Use Enums?

graph TD A["Without Enums"] --> B["status = 'activ'<br>❌ Typo allowed!"] A --> C["status = 'ACTIVE'<br>❌ Case mismatch!"] D["With Enums"] --> E["Status::Active<br>βœ… Only valid values"] D --> F["IDE autocomplete<br>βœ… No typos possible"]

πŸ”§ Enum Methods

enum Color {
    case Red;
    case Blue;
    case Green;

    public function hex(): string {
        return match($this) {
            self::Red => '#FF0000',
            self::Blue => '#0000FF',
            self::Green => '#00FF00',
        };
    }
}

echo Color::Red->hex(); // "#FF0000"

πŸ’Ύ Backed Enums: Enums with Values

What’s the difference?

Pure Enums = Just labels (no value attached) Backed Enums = Labels WITH a stored value (string or int)

Think of it like:

  • Pure Enum = Name tags (β€œHi, I’m Active!”)
  • Backed Enum = ID badges (β€œHi, I’m Active! Badge #1”)

String-Backed Enum

enum UserRole: string {
    case Admin = 'admin';
    case Editor = 'editor';
    case Viewer = 'viewer';
}

// Get the value
echo UserRole::Admin->value; // "admin"

// Perfect for databases!
$sql = "SELECT * FROM users
        WHERE role = ?";
// Pass: UserRole::Admin->value

Integer-Backed Enum

enum Priority: int {
    case Low = 1;
    case Medium = 2;
    case High = 3;
    case Critical = 4;
}

echo Priority::High->value; // 3

πŸ”„ Converting Back: from() and tryFrom()

enum Size: string {
    case Small = 'S';
    case Medium = 'M';
    case Large = 'L';
}

// from() - Throws error if not found
$size = Size::from('M'); // Size::Medium

// tryFrom() - Returns null if not found
$size = Size::tryFrom('XL'); // null (no error!)

πŸ“Š Quick Comparison

Feature Pure Enum Backed Enum
Has value ❌ βœ… (string/int)
Database storage ❌ Tricky βœ… Easy
API responses ❌ Need extra work βœ… Direct
Use .value ❌ βœ…
Use from()/tryFrom() ❌ βœ…

🎯 Quick Reference: All Features Together

graph TD subgraph Object Features A["πŸ‘ Clone"] --> A1["Duplicate objects"] B["βš–οΈ Compare"] --> B1["== vs ==="] C["🎭 Anonymous"] --> C1["One-time classes"] D["🏷️ Enum"] --> D1["Fixed value sets"] E["πŸ’Ύ Backed Enum"] --> E1["Enums + stored values"] end

🌟 Real-World Example: Putting It All Together

// Backed Enum for order status
enum OrderStatus: string {
    case Pending = 'pending';
    case Processing = 'processing';
    case Shipped = 'shipped';
    case Delivered = 'delivered';

    public function emoji(): string {
        return match($this) {
            self::Pending => '⏳',
            self::Processing => 'πŸ“¦',
            self::Shipped => '🚚',
            self::Delivered => 'βœ…',
        };
    }
}

// Class using enum
class Order {
    public function __construct(
        public int $id,
        public OrderStatus $status,
        public DateTime $created
    ) {}

    public function __clone() {
        $this->id = 0; // New order needs new ID
        $this->created = new DateTime();
        $this->status = OrderStatus::Pending;
    }
}

// Create and clone
$order1 = new Order(
    123,
    OrderStatus::Shipped,
    new DateTime()
);

$order2 = clone $order1;

// Compare
echo $order1 === $order2; // false (different)
echo $order1->status->emoji(); // 🚚
echo $order2->status->emoji(); // ⏳

πŸŽ‰ You Did It!

You’ve just learned how to:

Feature Your Superpower
πŸ‘ Clone Duplicate objects like a pro
βš–οΈ Compare Know if objects are twins or the same person
🎭 Anonymous Classes Create quick, disposable classes
🏷️ Enums Lock down values to a fixed set
πŸ’Ύ Backed Enums Store real values with your enums

You’re now ready to write cleaner, safer, and more elegant PHP code! πŸš€

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.