๐ญ 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 = &#39;activ&#39;<br>โ Typo allowed!"] A --> C["status = &#39;ACTIVE&#39;<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! ๐
