← Tilbage til koncepter
Magic Methods
Special methods som __construct, __get, __set, __call, __toString, __invoke og andre magic methods i PHP
Kategori: Fundamentals
🎯 Key Points
- ✓__construct() - Called automatisk når object instantieres, bruges til initialization
- ✓__destruct() - Called når object destroyes eller script terminates, til cleanup
- ✓__get($name) - Intercept property reads for non-existent eller inaccessible properties
- ✓__set($name, $value) - Intercept property writes for non-existent eller inaccessible properties
- ✓__isset($name) - Called når isset() eller empty() bruges på inaccessible properties
- ✓__unset($name) - Called når unset() bruges på inaccessible properties
- ✓__call($name, $args) - Intercept calls til non-existent eller inaccessible methods
- ✓__callStatic($name, $args) - Intercept static method calls til non-existent methods
- ✓__toString() - Definerer hvordan object konverteres til string
- ✓__invoke() - Gør object callable som en function
- ✓__clone() - Called når object clones med clone keyword
- ✓__serialize() & __unserialize() - Custom serialization logic (PHP 7.4+)
💻 Kode Eksempel
<?php
// Comprehensive magic methods example
class MagicUser {
private array $data = [];
private array $methodCache = [];
// Constructor
public function __construct(private string $name, private int $age) {
echo "User created: {$this->name}\n";
}
// Dynamic property getter
public function __get(string $name): mixed {
echo "Getting property: {$name}\n";
return $this->data[$name] ?? null;
}
// Dynamic property setter
public function __set(string $name, mixed $value): void {
echo "Setting property {$name} = {$value}\n";
$this->data[$name] = $value;
}
// Check if property exists
public function __isset(string $name): bool {
return isset($this->data[$name]);
}
// Unset property
public function __unset(string $name): void {
unset($this->data[$name]);
}
// Dynamic method calls
public function __call(string $name, array $args): mixed {
// Magic getter methods: getPropertyName()
if (str_starts_with($name, 'get')) {
$property = lcfirst(substr($name, 3));
return $this->data[$property] ?? null;
}
// Magic setter methods: setPropertyName($value)
if (str_starts_with($name, 'set') && count($args) === 1) {
$property = lcfirst(substr($name, 3));
$this->data[$property] = $args[0];
return $this;
}
throw new BadMethodCallException("Method {$name} does not exist");
}
// Static method calls
public static function __callStatic(string $name, array $args): mixed {
if ($name === 'create') {
return new self(...$args);
}
throw new BadMethodCallException("Static method {$name} does not exist");
}
// String conversion
public function __toString(): string {
return "{$this->name} (Age: {$this->age})";
}
// Make object callable
public function __invoke(string $message): void {
echo "{$this->name} says: {$message}\n";
}
// Clone handling
public function __clone(): void {
echo "Cloning user: {$this->name}\n";
// Deep clone data array
$this->data = [...$this->data];
}
// Destructor
public function __destruct() {
echo "User destroyed: {$this->name}\n";
}
}
// Usage examples
echo "=== Creating User ===\n";
$user = new MagicUser('John', 30);
echo "\n=== Dynamic Properties ===\n";
$user->email = 'john@example.com';
echo "Email: {$user->email}\n";
echo "\n=== Dynamic Methods ===\n";
$user->setPhone('555-1234');
echo "Phone: " . $user->getPhone() . "\n";
echo "\n=== String Conversion ===\n";
echo "User: {$user}\n";
echo "\n=== Callable Object ===\n";
$user('Hello World!');
echo "\n=== Static Factory ===\n";
$user2 = MagicUser::create('Jane', 25);
echo "\n=== Cloning ===\n";
$user3 = clone $user;
echo "\n=== Script End (triggers destructors) ===\n";💼 Hvornår bruges det?
- •ORM models (Eloquent, Doctrine) hvor database columns tilgås som object properties dynamisk
- •API clients hvor remote endpoints mappes til method calls med __call for flexible API design
- •Configuration objects med nested access via __get for reading hierarchical config data
- •Mock objects i testing hvor __call intercepter method calls for verification og stubbing
- •Value objects med __toString for convenient debugging og logging af complex objects
- •Event emitters med __invoke til callable objects der kan dispatches som event handlers
⭐ Best Practices
- ✓Dokumentér magic behavior med @property og @method PHPDoc tags for IDE autocomplete support
- ✓Use magic methods sparsomt - prefer explicit methods når behavior er core functionality
- ✓Throw descriptive exceptions i __call for non-existent methods frem for silent failures
- ✓Implement __isset og __unset sammen med __get og __set for consistent property behavior
- ✓Cache results i __get hvis property access er expensive (database queries, calculations)
- ✓Be aware of static analysis limitations - tools som PHPStan kan ikke analysere magic behavior
- ✓Consider performance - magic methods har slight overhead sammenlignet med direct property access
- ✓Use __toString defensively - never throw exceptions, return string representation even for invalid state
ℹ️ Quick Info
Kategori
Fundamentals
Sværhedsgrad
Mellem