← Tilbage til koncepter
Closures & Anonymous Functions
Anonymous functions, closures, arrow functions og callback patterns i moderne PHP
Kategori: Fundamentals
🎯 Key Points
- ✓Anonymous functions - Funktioner uden navn der kan assignes til variabler
- ✓use keyword - Capture (inherit) variabler fra parent scope til closure
- ✓Arrow functions (fn) - Kort syntaks med implicit variable binding fra PHP 7.4
- ✓First-class functions - Funktioner kan passes som argumenter og returneres fra andre funktioner
- ✓Closure::bind() - Bind closure til specifik object scope og class context
- ✓Callbacks - Brug closures som callbacks i array_map, array_filter, usort etc
- ✓Variable scope - Closures har deres egen scope men kan access parent scope via use
- ✓By reference capture - Brug use (&$var) til at modificere parent scope variabler
- ✓Callable type hint - Type hint parameters som callable for at acceptere closures
- ✓Dependency injection - Brug closures til lazy loading af dependencies i containers
- ✓Higher-order functions - Funktioner der tager eller returnerer andre funktioner
- ✓Immutable by default - Captured variabler er by value unless explicitly by reference
💻 Kode Eksempel
<?php
// Basic closure with use keyword
$taxRate = 0.25;
$calculatePrice = function(float $amount) use ($taxRate): float {
return $amount * (1 + $taxRate);
};
echo "Price with tax: " . $calculatePrice(100) . "\n";
// By-reference capture
$counter = 0;
$increment = function() use (&$counter): int {
return ++$counter;
};
echo "Count: {$increment()}\n"; // 1
echo "Count: {$increment()}\n"; // 2
echo "Count: {$increment()}\n"; // 3
// Arrow functions (PHP 7.4+)
$numbers = [1, 2, 3, 4, 5];
$multiplier = 3;
$result = array_map(
fn($n) => $n * $multiplier, // Implicit use of $multiplier
$numbers
);
print_r($result);
// Higher-order functions
function createMultiplier(int $factor): Closure {
return fn(int $x) => $x * $factor;
}
$double = createMultiplier(2);
$triple = createMultiplier(3);
echo "Double 10: {$double(10)}\n";
echo "Triple 10: {$triple(10)}\n";
// Closure binding to object scope
class User {
private string $name = 'John Doe';
}
$user = new User();
$getName = function() {
return $this->name; // Access private property
};
$boundClosure = Closure::bind($getName, $user, User::class);
echo "User name: {$boundClosure()}\n";
// Array operations with closures
$products = [
['name' => 'Laptop', 'price' => 1000],
['name' => 'Mouse', 'price' => 25],
['name' => 'Keyboard', 'price' => 75],
];
// Filter products over 50
$expensive = array_filter(
$products,
fn($p) => $p['price'] > 50
);
// Sort by price
usort($products, fn($a, $b) => $a['price'] <=> $b['price']);
// Calculate total
$total = array_reduce(
$products,
fn($sum, $p) => $sum + $p['price'],
0
);
echo "Total price: {$total}\n";💼 Hvornår bruges det?
- •Array transformations med array_map, array_filter og array_reduce for data processing pipelines
- •Event handlers og callbacks i event-driven arkitekturer og observer patterns
- •Dependency injection containers hvor services lazy-loades via closures (Laravel service providers)
- •Route definitions i web frameworks hvor hver route handler er en closure (Laravel, Slim)
- •Database query builders med dynamic where clauses som closures (Eloquent, Doctrine)
- •Middleware pipelines hvor hver middleware layer er implementeret som closure
⭐ Best Practices
- ✓Prefer arrow functions (fn) for simple one-liner callbacks - mere læsbar og koncis
- ✓Brug use keyword eksplicit for bedre readability - gør det klart hvilke variabler der captures
- ✓Undgå for mange captured variabler - hvis closure bruger > 3 variabler, overvej class method
- ✓Type hint callable parameters og return types for bedre IDE support og type safety
- ✓Brug by-reference capture (&$var) sparsomt - kan føre til unexpected side effects
- ✓Dokumentér closures med PHPDoc @var annotations når type ikke er obvious
- ✓Hold closures små og fokuserede - split komplekse closures i multiple named functions
- ✓Vær opmærksom på memory leaks - closures holder references til captured variabler
ℹ️ Quick Info
Kategori
Fundamentals
Sværhedsgrad
Mellem